[java-oidc-common] branch main updated: JCOMOIDC-28 - Support for metadata policies

Henri Mikkonen henri.mikkonen at iki.fi
Fri Jan 7 11:09:54 UTC 2022


This is an automated email from the git hooks/post-receive script.

hjmikkon pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=38f0593b1220ab907e7f666a3ce7dd3263038d44

The following commit(s) were added to refs/heads/main by this push:
     new 38f0593  JCOMOIDC-28 - Support for metadata policies
38f0593 is described below

commit 38f0593b1220ab907e7f666a3ce7dd3263038d44
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Jan 7 13:07:08 2022 +0200

    JCOMOIDC-28 - Support for metadata policies
    
    https://shibboleth.atlassian.net/browse/JCOMOIDC-28
    
    Added utility method for merging metadata policies. We need this for
    merging metadata policies in profile configuration and registration
    access token.
---
 .../metadata/policy/impl/MetadataPolicyHelper.java | 162 +++++++-
 .../policy/impl/MetadataPolicyHelperTest.java      | 440 +++++++++++++++++++++
 2 files changed, 601 insertions(+), 1 deletion(-)

diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelper.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelper.java
index 7d2b678..56ae653 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelper.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelper.java
@@ -17,9 +17,17 @@
 
 package net.shibboleth.oidc.metadata.policy.impl;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
 
 /**
  * Static utility methods related to metadata policies.
@@ -58,5 +66,157 @@ public final class MetadataPolicyHelper {
                 ? values.containsAll((Collection<?>) candidate)
                 : values.contains(candidate);
     }
+    
+    /**
+     * <p>Merges two metadata policies with the rules defined in the OIDC federation spec 5.1.3.1:</p>
+     * <ul>
+     * <li>
+     * subset_of: The result of merging the values of two subset_of operators is the intersection of the operator
+     * values.
+     * </li>
+     * <li>
+     * one_of: The result of merging the values of two one_of operators is the intersection of the operator values.
+     * </li>
+     * <li>
+     * superset_of: The result of merging the values of two superset_of operators is the union of the operator values.
+     * </li>
+     * <li>
+     * add: The result of merging the values of two add operators is the union of the values.
+     * </li>
+     * <li>
+     * value: Merging two value operators is NOT allowed unless the two operator values are equal.
+     * </li>
+     * <li>
+     * default: Merging two default operators is NOT allowed unless the two operator values are equal.
+     * </li>
+     * <li>
+     * essential: If a superior has specified essential=true, then a subordinate cannot change that. If a superior has
+     * specified essential=false, then a subordinate is allowed to change that to essential=true. If a superior has not
+     * specified essential, then a subordinate can set essential to true or false.
+     * </li>
+     * </ul>
+     * 
+     * <p>In addition to the list above, 'regex' operator is treated in the same way as 'value' and 'default'.</p>
+     * 
+     * @param superior The superior metadata policy.
+     * @param subordinate The subordinate metadata policy.
+     * @return The merged metadata policy.
+     * @throws ConstraintViolationException If two 'value' or 'default' operators with different values are attempted
+     * to be merged.
+     */
+    @Nullable public static MetadataPolicy mergeMetadataPolicies(@Nullable final MetadataPolicy superior,
+            @Nullable final MetadataPolicy subordinate) throws ConstraintViolationException {
+        if (superior == null) {
+            return subordinate;
+        }
+        if (subordinate == null) {
+            return superior;
+        }
+        final Object defaultValue = superior.getDefaultValue();
+        if (defaultValue != null) {
+            final Object anotherDefault = subordinate.getDefaultValue();
+            if (anotherDefault != null && !defaultValue.equals(anotherDefault)) {
+                throw new ConstraintViolationException(
+                        "Merging two default operators is NOT allowed unless the two operator values are equal.");
+            }
+        }
+        final Object value = superior.getValue();
+        if (value != null) {
+            final Object anotherValue = subordinate.getValue();
+            if (anotherValue != null && !value.equals(anotherValue)) {
+                throw new ConstraintViolationException(
+                        "Merging two value operators is NOT allowed unless the two operator values are equal.");
+                
+            }
+        }
+        final String regexp = superior.getRegexp();
+        if (regexp != null) {
+            final String anotherRegexp = subordinate.getRegexp();
+            if (anotherRegexp != null && !regexp.equals(anotherRegexp)) {
+                throw new ConstraintViolationException(
+                        "Mering two regexp operators is NOT allowed unless the two operator values are equal.");
+            }
+        }
+        return new MetadataPolicy.Builder()
+                .withSubsetOfValues(doMergeForTwoLists(superior.getSubsetOfValues(),
+                        subordinate.getSubsetOfValues(), false))
+                .withOneOfValues(doMergeForTwoLists(superior.getOneOfValues(), subordinate.getOneOfValues(), false))
+                .withSupersetOfValues(doMergeForTwoLists(superior.getSupersetOfValues(),
+                        subordinate.getSupersetOfValues(), true))
+                .withAdd(doMergeForTwoObjects(superior.getAdd(), subordinate.getAdd(), true))
+                .withValue(value)
+                .withDefaultValue(defaultValue)
+                .withEssential(superior.isEssential() ? Boolean.TRUE : subordinate.getEssential())
+                .withRegexp(regexp)
+                .build();
+    }
+
+    /**
+     * Merges two metadata policy values that can be either single valued or lists.
+     * 
+     * @param superior The superior metadata value.
+     * @param subordinate The subordinate metadata value.
+     * @param union Flag to indicate the use of union. Intersection is used if false.
+     * @return The merged value.
+     * @throws ConstraintViolationException If the values are conflicting: two different values cannot be
+     * merged when union-flag is true.
+     */
+    @Nullable private static Object doMergeForTwoObjects(@Nullable final Object superior,
+            @Nullable final Object subordinate, final boolean union) throws ConstraintViolationException {
+        if (superior == null) {
+            return subordinate;
+        }
+        // check if either of superior or subordinate are lists and process if they are
+        if (superior instanceof List) {
+            if (subordinate instanceof List) {
+                return doMergeForTwoLists(new ArrayList<Object>((List<?>) superior), (List<?>) subordinate, union);
+            }
+            return doMergeForTwoLists(new ArrayList<Object>((List<?>) superior),
+                    subordinate == null ? null : List.of(subordinate), union);
+        } else if (subordinate instanceof List) {
+            return doMergeForTwoLists(List.of(superior), (List<?>) subordinate, union);
+        }
+        // superior and subordinate are plain objects
+        if (subordinate == null) {
+            return superior;
+        }
+        if (union) {
+            if (superior.equals(subordinate)) {
+                return superior;
+            } else {
+                return List.of(superior, subordinate);
+            }
+        }
+        if (!superior.equals(subordinate)) {
+            throw new ConstraintViolationException("Merging of two different values is not allowed");
+        }
+        return superior;
+    }
 
-}
+    /**
+     * Merges two metadata policy list values.
+     * 
+     * @param superior The superior value.
+     * @param subordinate The subordinate value.
+     * @param union Flag to indicate the use of union. Intersection is used if false.
+     * @return The merged value.
+     */
+    @SuppressWarnings("unchecked")
+    @Nullable private static List<Object> doMergeForTwoLists(@Nullable final List<?> superior,
+            @Nullable final List<?> subordinate, final boolean union) {
+        if (superior == null) {
+            return (List<Object>) subordinate;
+        }
+        if (subordinate == null) {
+            return List.copyOf(superior);
+        }
+        if (union) {
+            final Set<Object> set = new HashSet<>(superior);
+            set.addAll(subordinate);
+            return List.copyOf(set);
+        }
+        final List<Object> result = new ArrayList<>(superior);
+        result.retainAll(subordinate);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelperTest.java b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelperTest.java
new file mode 100644
index 0000000..8a13c5e
--- /dev/null
+++ b/oidc-common-metadata-impl/src/test/java/net/shibboleth/oidc/metadata/policy/impl/MetadataPolicyHelperTest.java
@@ -0,0 +1,440 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.oidc.metadata.policy.impl;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.oidc.metadata.policy.MetadataPolicy;
+import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
+
+/**
+ * Unit tests for {@link MetadataPolicyHelper}.
+ */
+public class MetadataPolicyHelperTest {
+
+    @Test
+    public void mergeMetadataPolicies_bothNull_shouldReturnNull() {
+        Assert.assertNull(MetadataPolicyHelper.mergeMetadataPolicies(null, null));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_subordinateNull_shouldReturnSuperior() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, null);
+        assertEquals(merged, superior);
+    }
+
+    @Test
+    public void mergeMetadataPolicies_superiorNull_shouldReturnSubordinate() {
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(null, subordinate);
+        assertEquals(merged, subordinate);
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothSubsetOf_shouldReturnIntersection() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value2", "value3", "value4"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>(merged.getSubsetOfValues()),
+                Set.of("value2", "value3"));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothSubsetOfDifferentTypes_shouldReturnEmptyList() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("1", "2", "3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of(2, 3, 4))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getSubsetOfValues(), Collections.emptyList());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneSubsetOf_shouldReturnSameOne() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getSubsetOfValues(), superior.getSubsetOfValues());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneSubsetOf_shouldReturnSameOne2() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getSubsetOfValues(), subordinate.getSubsetOfValues());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneSubsetOf_anotherEmpty_shouldReturnEmpty() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(Collections.emptyList())
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getSubsetOfValues(), Collections.emptyList());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneSubsetOf_anotherEmpty_shouldReturnEmpty2() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSubsetOfValues(Collections.emptyList())
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSubsetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getSubsetOfValues(), Collections.emptyList());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothOneOf_shouldReturnIntersection() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value2", "value3", "value4"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>(merged.getOneOfValues()),
+                Set.of("value2", "value3"));
+    }
+    
+    @Test
+    public void mergeMetadataPolicies_bothOneOfDifferentTypes_shouldReturnEmptyList() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("1", "2", "3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of(2, 3, 4))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getOneOfValues(), Collections.emptyList());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneOneOf_shouldReturnSameOne() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getOneOfValues(), superior.getOneOfValues());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneOneOf_shouldReturnSameOne2() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getOneOfValues(), subordinate.getOneOfValues());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneOneOf_anotherEmpty_shouldReturnEmpty() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withOneOfValues(Collections.emptyList())
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getOneOfValues(), Collections.emptyList());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneOneOf_anotherEmpty_shouldReturnEmpty2() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withOneOfValues(Collections.emptyList())
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withOneOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getOneOfValues(), Collections.emptyList());
+    }
+    
+    @Test
+    public void mergeMetadataPolicies_bothSupersetOf_shouldReturnUnion() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSupersetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withSupersetOfValues(List.of("value2", "value3", "value4"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>(merged.getSupersetOfValues()),
+                Set.of("value1", "value2", "value3", "value4"));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_oneSupersetOf_shouldReturnSame() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withSupersetOfValues(List.of("value1", "value2", "value3"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>(merged.getSupersetOfValues()),
+                Set.of("value1", "value2", "value3"));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothAdd_oneSingle_shouldReturnSameValue() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withAdd("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withAdd("singleValue1")
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getAdd(), "singleValue1");
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothAdd_twoSinglesDifferentTypes_shouldReturnUnionAsList() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withAdd("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withAdd(2)
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>((List<?>) merged.getAdd()),
+                Set.of("singleValue1", 2));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothAdd_twoSingles_shouldReturnUnionAsList() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withAdd("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withAdd("singleValue2")
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>((List<?>) merged.getAdd()),
+                Set.of("singleValue1", "singleValue2"));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothAdd_singleAndList_shouldReturnUnionAsList() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withAdd("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withAdd(List.of("listValue1", "listValue2"))
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(new HashSet<Object>((List<?>) merged.getAdd()),
+                Set.of("singleValue1", "listValue1", "listValue2"));
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothSameValue_shouldReturnSame() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withValue("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withValue("singleValue1")
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getValue(), "singleValue1");
+    }
+
+    @Test(expectedExceptions = { ConstraintViolationException.class })
+    public void mergeMetadataPolicies_bothDifferentValue_shouldThrow() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withValue("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withValue("singleValue2")
+                .build();
+        MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+    }
+
+    @Test(expectedExceptions = { ConstraintViolationException.class })
+    public void mergeMetadataPolicies_bothDifferentListValue_shouldThrow() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withValue(List.of("singleValue1"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withValue(List.of("singleValue2"))
+                .build();
+        MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothSameDefaultValue_shouldReturnSame() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withDefaultValue("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withDefaultValue("singleValue1")
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getDefaultValue(), "singleValue1");
+    }
+
+    @Test(expectedExceptions = { ConstraintViolationException.class })
+    public void mergeMetadataPolicies_bothDifferentDefaultValue_shouldThrow() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withDefaultValue("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withDefaultValue("singleValue2")
+                .build();
+        MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothSameRegexp_shouldReturnSame() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withRegexp("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withRegexp("singleValue1")
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertEquals(merged.getRegexp(), "singleValue1");
+    }
+
+    @Test(expectedExceptions = { ConstraintViolationException.class })
+    public void mergeMetadataPolicies_bothDifferentRegexp_shouldThrow() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withRegexp("singleValue1")
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withRegexp("singleValue2")
+                .build();
+        MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+    }
+
+    @Test(expectedExceptions = { ConstraintViolationException.class })
+    public void mergeMetadataPolicies_bothDifferentDefaultListValue_shouldThrow() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withDefaultValue(List.of("singleValue1"))
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withDefaultValue(List.of("singleValue2"))
+                .build();
+        MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothEssentialTrue_shouldReturnTrue() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withEssential(Boolean.TRUE)
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withEssential(Boolean.TRUE)
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertTrue(merged.isEssential());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_bothEssentialFalse_shouldReturnFalse() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withEssential(Boolean.FALSE)
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withEssential(Boolean.FALSE)
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertFalse(merged.isEssential());
+    }
+
+    @Test
+    public void mergeMetadataPolicies_superiorEssentialTrueSubordinateFalse_shouldReturnTrue() {
+        final MetadataPolicy superior = new MetadataPolicy.Builder()
+                .withEssential(Boolean.TRUE)
+                .build();
+        final MetadataPolicy subordinate = new MetadataPolicy.Builder()
+                .withEssential(Boolean.FALSE)
+                .build();
+        final MetadataPolicy merged = MetadataPolicyHelper.mergeMetadataPolicies(superior, subordinate);
+        Assert.assertNotNull(merged);
+        Assert.assertTrue(merged.isEssential());
+    }
+    
+    protected void assertEquals(final MetadataPolicy actual, final MetadataPolicy expected) {
+        Assert.assertNotNull(actual);
+        Assert.assertNotNull(expected);
+        Assert.assertEquals(actual.getSubsetOfValues(), expected.getSubsetOfValues());
+        Assert.assertEquals(actual.getAdd(), expected.getAdd());
+        Assert.assertEquals(actual.getDefaultValue(), expected.getDefaultValue());
+        Assert.assertEquals(actual.getValue(), expected.getValue());
+        Assert.assertEquals(actual.getOneOfValues(), expected.getOneOfValues());
+        Assert.assertEquals(actual.getSupersetOfValues(), expected.getSupersetOfValues());
+        Assert.assertEquals(actual.getRegexp(), expected.getRegexp());
+        Assert.assertEquals(actual.isEssential(), expected.isEssential());
+    }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list