From e619fe5bfc52ef1802e273480c92a8d475fa3984 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Wed, 23 Jan 2019 11:35:44 +0100 Subject: [PATCH] Fixed handling of PrismContainerValue in expressions (MID-5080) --- .../functions/BasicExpressionFunctions.java | 4 + .../script/jsr223/Jsr223ScriptEvaluator.java | 15 ++- .../model/common/mapping/MappingImpl.java | 4 +- ...bstractConfiguredModelIntegrationTest.java | 4 + .../intest/gensync/TestRoleEntitlement.java | 47 ++++++-- .../gensync/object-template-role.xml | 87 ++++++++++---- .../src/test/resources/logback-test.xml | 1 + .../src/test/resources/schema/piracy.xsd | 20 +++- .../test/AbstractModelIntegrationTest.java | 5 + .../common/expression/ExpressionUtil.java | 31 +++-- .../test/asserter/AbstractRoleAsserter.java | 15 +-- .../test/asserter/ExtensionAsserter.java | 98 +++++---------- .../midpoint/test/asserter/OrgAsserter.java | 7 ++ .../asserter/PrismContainerValueAsserter.java | 113 +++++++++++++++++- .../midpoint/test/asserter/RoleAsserter.java | 6 + .../testing/story/TestDelayedEnable.java | 16 +-- 16 files changed, 340 insertions(+), 133 deletions(-) diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java index 32c61f90cdb..c80f8a2ddf3 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/functions/BasicExpressionFunctions.java @@ -431,6 +431,10 @@ public boolean isEmpty(Object whatever) { } return whateverString.isEmpty(); } + + public PrismContext getPrismContext() { + return prismContext; + } public Collection getExtensionPropertyValues(ObjectType object, String namespace, String localPart) { return getExtensionPropertyValues(object, new javax.xml.namespace.QName(namespace, localPart)); diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java index e009ed9f1a1..5cea495d49d 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/jsr223/Jsr223ScriptEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2019 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,8 @@ import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.util.exception.SystemException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionReturnTypeType; @@ -65,6 +67,8 @@ public class Jsr223ScriptEvaluator implements ScriptEvaluator { private static final String LANGUAGE_URL_BASE = MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX + "/expression/language#"; + + private static final Trace LOGGER = TraceManager.getTrace(Jsr223ScriptEvaluator.class); private final ScriptEngine scriptEngine; private final PrismContext prismContext; @@ -130,12 +134,19 @@ public List evaluate(ScriptExpressionEvaluatorType if (javaReturnType == null) { javaReturnType = prismContext.getSchemaRegistry().getCompileTimeClass(xsdReturnType); } + + if (javaReturnType == null && (outputDefinition instanceof PrismContainerDefinition)) { + // This is the case when we need a container, but we do not have compile-time class for that + // E.g. this may be container in object extension (MID-5080) + javaReturnType = (Class) PrismContainerValue.class; + } if (javaReturnType == null) { // TODO quick and dirty hack - because this could be because of enums defined in schema extension (MID-2399) // ...and enums (xsd:simpleType) are not parsed into ComplexTypeDefinitions - javaReturnType = (Class) String.class; + javaReturnType = (Class) String.class; } + LOGGER.trace("expected return type: XSD={}, Java={}", xsdReturnType, javaReturnType); List pvals = new ArrayList<>(); diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingImpl.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingImpl.java index b1b8a184351..07e3367a37e 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingImpl.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/mapping/MappingImpl.java @@ -441,10 +441,10 @@ public void evaluateBody(Task task, OperationResult parentResult) throws Express evaluateCondition(task, result); - boolean conditionOutputOld = computeConditionResult(conditionOutputTriple.getNonPositiveValues()); + boolean conditionOutputOld = computeConditionResult(conditionOutputTriple==null ? null : conditionOutputTriple.getNonPositiveValues()); boolean conditionResultOld = conditionOutputOld && conditionMaskOld; - boolean conditionOutputNew = computeConditionResult(conditionOutputTriple.getNonNegativeValues()); + boolean conditionOutputNew = computeConditionResult(conditionOutputTriple==null ? null : conditionOutputTriple.getNonNegativeValues()); boolean conditionResultNew = conditionOutputNew && conditionMaskNew; if (!conditionResultOld && !conditionResultNew) { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 902ecf60bb3..f8d8b7d8df8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -498,6 +498,10 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final ItemName PIRACY_MARK = new ItemName(NS_PIRACY, "mark"); protected static final ItemName PIRACY_KEY = new ItemName(NS_PIRACY, "key"); protected static final ItemName PIRACY_BINARY_ID = new ItemName(NS_PIRACY, "binaryId"); + protected static final ItemName PIRACY_COST_CENTER = new ItemName(NS_PIRACY, "costCenter"); + protected static final ItemName PIRACY_RISK_VECTOR = new ItemName(NS_PIRACY, "riskVector"); + protected static final ItemName PIRACY_RISK_VECTOR_RISK = new ItemName(NS_PIRACY, "risk"); + protected static final ItemName PIRACY_RISK_VECTOR_VALUE = new ItemName(NS_PIRACY, "value"); protected static final ItemName RELATION_PIRACY_CAPTAIN = new ItemName(NS_PIRACY, "captain"); protected static final ItemPath ROLE_EXTENSION_COST_CENTER_PATH = ItemPath diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java index 2635ae4ef3f..3b78a634344 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestRoleEntitlement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2019 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,8 +83,7 @@ public void test050GetRolePirate() throws Exception { display("Role pirate", role); assertRolePirate(role); - result.computeStatus(); - TestUtil.assertSuccess("getObject result", result); + assertSuccess(result); } protected void assertRolePirate(PrismObject role) { @@ -1183,16 +1182,16 @@ public void test200AddRoleSwashbuckler() throws Exception { PrismObject role = PrismTestUtil.parseObject(ROLE_SWASHBUCKLER_FILE); ObjectDelta roleDelta = DeltaFactory.Object.createAddDelta(role); - Collection> deltas = MiscSchemaUtil.createCollection(roleDelta); XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar(); // WHEN - modelService.executeChanges(deltas, null, task, result); + displayWhen(TEST_NAME); + executeChanges(roleDelta, null, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess("executeChanges result", result); + displayThen(TEST_NAME); + assertSuccess(result); XMLGregorianCalendar endTime = clock.currentTimeXMLGregorianCalendar(); assertNotNull("No account OID in resulting delta", groupOid); @@ -1233,6 +1232,40 @@ public void test200AddRoleSwashbuckler() throws Exception { dummyAuditService.assertTarget(ROLE_SWASHBUCKLER_OID); dummyAuditService.assertExecutionSuccess(); } + + /** + * MID-5080 + */ + @Test + public void test210ModifyRoleSwashbucklerRiskLevel() throws Exception { + final String TEST_NAME = "test210ModifyRoleSwashbucklerRiskLevel"; + displayTestTitle(TEST_NAME); + + // GIVEN + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + prepareTest(AssignmentPolicyEnforcementType.RELATIVE); + + assertRoleBefore(ROLE_SWASHBUCKLER_OID) + .extension() + .assertItems(PIRACY_COST_CENTER); + + // WHEN + displayWhen(TEST_NAME); + modifyObjectReplaceProperty(RoleType.class, ROLE_SWASHBUCKLER_OID, RoleType.F_RISK_LEVEL, task, result, "99"); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + assertRoleAfter(ROLE_SWASHBUCKLER_OID) + .assertRiskLevel("99") + .extension() + .assertItems(PIRACY_COST_CENTER, PIRACY_RISK_VECTOR) + .containerSingle(PIRACY_RISK_VECTOR) + .assertPropertyEquals(PIRACY_RISK_VECTOR_RISK, "X") + .assertPropertyEquals(PIRACY_RISK_VECTOR_VALUE, 99); + } private void prepareTest(AssignmentPolicyEnforcementType enforcement) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { assumeAssignmentPolicy(enforcement); diff --git a/model/model-intest/src/test/resources/gensync/object-template-role.xml b/model/model-intest/src/test/resources/gensync/object-template-role.xml index 6f035d71f48..385ae102d5c 100644 --- a/model/model-intest/src/test/resources/gensync/object-template-role.xml +++ b/model/model-intest/src/test/resources/gensync/object-template-role.xml @@ -1,6 +1,6 @@ + + extension/riskVector + + role-risk-vector + strong + true + + name + + + riskLevel + + + + + + true + + + + + diff --git a/model/model-intest/src/test/resources/logback-test.xml b/model/model-intest/src/test/resources/logback-test.xml index a0349c95b50..f4765a002dc 100644 --- a/model/model-intest/src/test/resources/logback-test.xml +++ b/model/model-intest/src/test/resources/logback-test.xml @@ -99,6 +99,7 @@ + diff --git a/model/model-intest/src/test/resources/schema/piracy.xsd b/model/model-intest/src/test/resources/schema/piracy.xsd index fb56e04165e..bf67bad924c 100644 --- a/model/model-intest/src/test/resources/schema/piracy.xsd +++ b/model/model-intest/src/test/resources/schema/piracy.xsd @@ -1,7 +1,7 @@ @@ -156,6 +157,23 @@ + + + + + + + + Prism container in role extension. + MID-5080 + + + true + + + + + diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 0a0a2d24205..13132099ad0 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -5583,6 +5583,11 @@ protected RoleAsserter assertRole(PrismObject role, String messa return asserter; } + protected RoleAsserter assertRoleBefore(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + RoleAsserter asserter = assertRole(oid, "before"); + return asserter; + } + protected RoleAsserter assertRoleAfter(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { RoleAsserter asserter = assertRole(oid, "after"); return asserter; diff --git a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java index fc08e07fde6..8ae7b0b444f 100644 --- a/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java +++ b/repo/repo-common/src/main/java/com/evolveum/midpoint/repo/common/expression/ExpressionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2018 Evolveum + * Copyright (c) 2010-2019 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1007,14 +1007,31 @@ public static boolean isEmpty(T val) { public static V convertToPrismValue(T value, ItemDefinition definition, String contextDescription, PrismContext prismContext) throws ExpressionEvaluationException { if (definition instanceof PrismReferenceDefinition) { return (V) ((ObjectReferenceType) value).asReferenceValue(); + } else if (definition instanceof PrismContainerDefinition) { - try { - prismContext.adopt((Containerable) value); - ((Containerable) value).asPrismContainerValue().applyDefinition(definition); - } catch (SchemaException e) { - throw new ExpressionEvaluationException(e.getMessage() + " " + contextDescription, e); + + if (value instanceof Containerable) { + try { + prismContext.adopt((Containerable) value); + ((Containerable) value).asPrismContainerValue().applyDefinition(definition); + } catch (SchemaException e) { + throw new ExpressionEvaluationException(e.getMessage() + " " + contextDescription, e); + } + return (V) ((Containerable) value).asPrismContainerValue(); + + } else if (value instanceof PrismContainerValue) { + try { + prismContext.adopt((PrismContainerValue) value); + ((PrismContainerValue) value).applyDefinition(definition); + } catch (SchemaException e) { + throw new ExpressionEvaluationException(e.getMessage() + " " + contextDescription, e); + } + return (V) ((PrismContainerValue) value); + + } else { + throw new ExpressionEvaluationException("Expected Containerable or PrismContainerValue as expression output, got "+value.getClass()); } - return (V) ((Containerable) value).asPrismContainerValue(); + } else { return (V) prismContext.itemFactory().createPropertyValue(value); } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractRoleAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractRoleAsserter.java index e374cccf0da..8d652c5e080 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractRoleAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractRoleAsserter.java @@ -172,22 +172,17 @@ public AbstractRoleAsserter assertLocality(String expectedOrig) { } public AbstractRoleAsserter assertDisplayName(String expectedOrig) { - assertPolyStringProperty(OrgType.F_DISPLAY_NAME, expectedOrig); + assertPolyStringProperty(AbstractRoleType.F_DISPLAY_NAME, expectedOrig); return this; } public AbstractRoleAsserter assertIdentifier(String expectedOrig) { - assertPropertyEquals(OrgType.F_IDENTIFIER, expectedOrig); + assertPropertyEquals(AbstractRoleType.F_IDENTIFIER, expectedOrig); return this; } - - public AbstractRoleAsserter assertTenant(Boolean expected) { - assertPropertyEquals(OrgType.F_TENANT, expected); - return this; - } - - public AbstractRoleAsserter assertIsTenant() { - assertPropertyEquals(OrgType.F_TENANT, true); + + public AbstractRoleAsserter assertRiskLevel(String expected) { + assertPropertyEquals(AbstractRoleType.F_RISK_LEVEL, expected); return this; } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ExtensionAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ExtensionAsserter.java index b26c6e11c58..61578857025 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ExtensionAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ExtensionAsserter.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 Evolveum + * Copyright (c) 2018-2019 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExtensionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.prism.xml.ns._public.types_3.RawType; @@ -34,115 +35,70 @@ * @author semancik * */ -public class ExtensionAsserter, RA> extends AbstractAsserter { +public class ExtensionAsserter, RA> extends PrismContainerValueAsserter { - private PrismContainerValue extensionContainerValue; private OA objectAsserter; public ExtensionAsserter(OA objectAsserter) { - super(); + super((PrismContainerValue) objectAsserter.getObject().getExtensionContainerValue()); this.objectAsserter = objectAsserter; } public ExtensionAsserter(OA objectAsserter, String details) { - super(details); + super((PrismContainerValue) objectAsserter.getObject().getExtensionContainerValue(), details); this.objectAsserter = objectAsserter; } private PrismObject getObject() { return objectAsserter.getObject(); } - - private PrismContainerValue getExtensionContainerValue() { - if (extensionContainerValue == null) { - extensionContainerValue = getObject().getExtensionContainerValue(); - } - return extensionContainerValue; - } - + + @Override public ExtensionAsserter assertSize(int expected) { - assertEquals("Wrong number of items in "+desc(), expected, getExtensionContainerValue().size()); + super.assertSize(expected); return this; } + @Override public ExtensionAsserter assertItems(QName... expectedItems) { - for (QName expectedItem: expectedItems) { - Item item = getExtensionContainerValue().findItem(ItemName.fromQName(expectedItem)); - if (item == null) { - fail("Expected item "+expectedItem+" in "+desc()+" but there was none. Items present: "+presentItemNames()); - } - } - for (Item existingItem : getExtensionContainerValue().getItems()) { - if (!QNameUtil.contains(expectedItems, existingItem.getElementName())) { - fail("Unexpected item "+existingItem.getElementName()+" in "+desc()+". Expected items: "+QNameUtil.prettyPrint(expectedItems)); - } - } + super.assertItems(expectedItems); return this; } + @Override public ExtensionAsserter assertAny() { - assertNotNull("No extension container value in "+desc(), getExtensionContainerValue()); - assertFalse("No items in "+desc(), getExtensionContainerValue().isEmpty()); + super.assertAny(); return this; } - private String presentItemNames() { - StringBuilder sb = new StringBuilder(); - Iterator> iterator = getExtensionContainerValue().getItems().iterator(); - while (iterator.hasNext()) { - sb.append(PrettyPrinter.prettyPrint(iterator.next().getElementName())); - if (iterator.hasNext()) { - sb.append(", "); - } - } - return sb.toString(); - } - - public ExtensionAsserter assertPropertyValue(QName propName, T... expectedValues) { - PrismProperty property = findProperty(propName); - assertNotNull("No property "+propName+" in "+desc(), property); - PrismAsserts.assertPropertyValueDesc(property, desc(), expectedValues); + @Override + public ExtensionAsserter assertPropertyValuesEqual(QName propName, T... expectedValues) { + super.assertPropertyValuesEqual(propName, expectedValues); return this; } - public ExtensionAsserter assertValueRaw(QName attrName, T... expectedValues) { - PrismProperty property = findProperty(attrName); - assertNotNull("No attribute "+attrName+" in "+desc(), property); - RawType[] expectedRaw = rawize(attrName, getPrismContext(), expectedValues); - PrismAsserts.assertPropertyValueDesc(property, desc(), (T[])expectedRaw); + @Override + public ExtensionAsserter assertPropertyValuesEqualRaw(QName attrName, T... expectedValues) { + super.assertPropertyValuesEqualRaw(attrName, expectedValues); return this; } - private RawType[] rawize(QName attrName, PrismContext prismContext, T[] expectedValues) { - RawType[] raws = new RawType[expectedValues.length]; - for(int i = 0; i < expectedValues.length; i++) { - raws[i] = new RawType(prismContext.itemFactory().createPropertyValue(expectedValues[i]), attrName, prismContext); - } - return raws; - } - + @Override public ExtensionAsserter assertNoItem(QName itemName) { - Item item = findItem(itemName); - assertNull("Unexpected item "+itemName+" in "+desc()+": "+item, item); + super.assertNoItem(itemName); return this; } - private PrismProperty findProperty(QName attrName) { - return getExtensionContainerValue().findProperty(ItemName.fromQName(attrName)); - } - - private Item findItem(QName itemName) { - return getExtensionContainerValue().findItem(ItemName.fromQName(itemName)); - } - + @Override public ExtensionAsserter assertTimestampBetween(QName propertyName, XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) { - PrismProperty property = findProperty(propertyName); - assertNotNull("No property "+propertyName+" in "+desc(), property); - XMLGregorianCalendar timestamp = property.getRealValue(); - assertNotNull("No value of property "+propertyName+" in "+desc(), timestamp); - TestUtil.assertBetween("Wrong value of property "+propertyName+" in "+desc(), startTs, endTs, timestamp); + super.assertTimestampBetween(propertyName, startTs, endTs); return this; } + + @Override + public PrismContainerValueAsserter> containerSingle(QName subcontainerQName) { + return (PrismContainerValueAsserter>) super.containerSingle(subcontainerQName); + } protected String desc() { diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java index c848cf3f984..ab3f933d5fe 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; @@ -192,6 +193,12 @@ public OrgAsserter assertIsTenant() { return this; } + @Override + public OrgAsserter assertRiskLevel(String expected) { + super.assertRiskLevel(expected); + return this; + } + @Override public OrgAsserter assertHasProjectionOnResource(String resourceOid) throws ObjectNotFoundException, SchemaException { super.assertHasProjectionOnResource(resourceOid); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismContainerValueAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismContainerValueAsserter.java index 5bc9b28a2c0..5095cbb9ccc 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismContainerValueAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismContainerValueAsserter.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018 Evolveum + * Copyright (c) 2018-2019 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,16 +21,28 @@ import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; +import java.util.Iterator; import java.util.List; +import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.Containerable; +import com.evolveum.midpoint.prism.Item; +import com.evolveum.midpoint.prism.ItemDefinition; +import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerValue; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.path.ItemName; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.prism.xml.ns._public.types_3.RawType; /** * @author semancik @@ -50,8 +62,58 @@ public PrismContainerValueAsserter(PrismContainerValue prismValue, RA returnA super(prismValue, returnAsserter, detail); } + public PrismContainerValueAsserter assertSize(int expected) { + assertEquals("Wrong number of items in "+desc(), expected, getPrismValue().size()); + return this; + } + + public PrismContainerValueAsserter assertItems(QName... expectedItems) { + for (QName expectedItem: expectedItems) { + Item item = getPrismValue().findItem(ItemName.fromQName(expectedItem)); + if (item == null) { + fail("Expected item "+expectedItem+" in "+desc()+" but there was none. Items present: "+presentItemNames()); + } + } + for (Item existingItem : getPrismValue().getItems()) { + if (!QNameUtil.contains(expectedItems, existingItem.getElementName())) { + fail("Unexpected item "+existingItem.getElementName()+" in "+desc()+". Expected items: "+QNameUtil.prettyPrint(expectedItems)); + } + } + return this; + } + + public PrismContainerValueAsserter assertAny() { + assertNotNull("No container value in "+desc(), getPrismValue()); + assertFalse("No items in "+desc(), getPrismValue().isEmpty()); + return this; + } + + private String presentItemNames() { + StringBuilder sb = new StringBuilder(); + Iterator> iterator = getPrismValue().getItems().iterator(); + while (iterator.hasNext()) { + sb.append(PrettyPrinter.prettyPrint(iterator.next().getElementName())); + if (iterator.hasNext()) { + sb.append(", "); + } + } + return sb.toString(); + } + + private PrismProperty findProperty(QName attrName) { + return getPrismValue().findProperty(ItemName.fromQName(attrName)); + } + + private PrismContainer findContainer(QName attrName) { + return getPrismValue().findContainer(ItemName.fromQName(attrName)); + } + + private Item findItem(QName itemName) { + return getPrismValue().findItem(ItemName.fromQName(itemName)); + } + public PrismContainerValueAsserter assertPropertyEquals(QName propName, T expected) { - PrismProperty prop = getPrismValue().findProperty(ItemName.fromQName(propName)); + PrismProperty prop = findProperty(propName); if (prop == null && expected == null) { return this; } @@ -62,6 +124,29 @@ public PrismContainerValueAsserter assertPropertyEquals(QName propName return this; } + public PrismContainerValueAsserter assertPropertyValuesEqual(QName propName, T... expectedValues) { + PrismProperty property = findProperty(propName); + assertNotNull("No property "+propName+" in "+desc(), property); + PrismAsserts.assertPropertyValueDesc(property, desc(), expectedValues); + return this; + } + + public PrismContainerValueAsserter assertPropertyValuesEqualRaw(QName attrName, T... expectedValues) { + PrismProperty property = findProperty(attrName); + assertNotNull("No attribute "+attrName+" in "+desc(), property); + RawType[] expectedRaw = rawize(attrName, getPrismContext(), expectedValues); + PrismAsserts.assertPropertyValueDesc(property, desc(), (T[])expectedRaw); + return this; + } + + private RawType[] rawize(QName attrName, PrismContext prismContext, T[] expectedValues) { + RawType[] raws = new RawType[expectedValues.length]; + for(int i = 0; i < expectedValues.length; i++) { + raws[i] = new RawType(prismContext.itemFactory().createPropertyValue(expectedValues[i]), attrName, prismContext); + } + return raws; + } + public PrismContainerValueAsserter assertRefEquals(QName refName, String expectedOid) { PrismReference ref = getPrismValue().findReference(refName); if (ref == null && expectedOid == null) { @@ -81,6 +166,30 @@ public PrismContainerValueAsserter assertRefEquals(QName refName, Stri return this; } + public PrismContainerValueAsserter assertNoItem(QName itemName) { + Item item = findItem(itemName); + assertNull("Unexpected item "+itemName+" in "+desc()+": "+item, item); + return this; + } + + public PrismContainerValueAsserter assertTimestampBetween(QName propertyName, XMLGregorianCalendar startTs, XMLGregorianCalendar endTs) { + PrismProperty property = findProperty(propertyName); + assertNotNull("No property "+propertyName+" in "+desc(), property); + XMLGregorianCalendar timestamp = property.getRealValue(); + assertNotNull("No value of property "+propertyName+" in "+desc(), timestamp); + TestUtil.assertBetween("Wrong value of property "+propertyName+" in "+desc(), startTs, endTs, timestamp); + return this; + } + + public PrismContainerValueAsserter> containerSingle(QName subcontainerQName) { + PrismContainer container = findContainer(subcontainerQName); + assertNotNull("No container "+subcontainerQName+" in "+desc(), container); + PrismContainerValue pval = container.getValue(); + PrismContainerValueAsserter> asserter = new PrismContainerValueAsserter<>(pval, this, subcontainerQName.getLocalPart() + " in " + desc()); + copySetupTo(asserter); + return asserter; + } + // TODO protected String desc() { diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/RoleAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/RoleAsserter.java index e58650e91c0..bfe4e53d756 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/RoleAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/RoleAsserter.java @@ -107,6 +107,12 @@ public RoleAsserter assertTenantRef(String expectedOid) { return this; } + @Override + public RoleAsserter assertRiskLevel(String expected) { + super.assertRiskLevel(expected); + return this; + } + @Override public RoleAsserter assertLifecycleState(String expected) { super.assertLifecycleState(expected); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestDelayedEnable.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestDelayedEnable.java index 5420f392855..39db73019e4 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestDelayedEnable.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestDelayedEnable.java @@ -198,7 +198,7 @@ private void assertMancombCreated() throws Exception { .assertName(USER_MANCOMB_USERNAME) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrCreateTsStart, hrCreateTsEnd) .end() .activation() @@ -268,7 +268,7 @@ private void assertMancombEnabled() throws Exception { .assertName(USER_MANCOMB_USERNAME) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrCreateTsStart, hrCreateTsEnd) .end() .activation() @@ -357,7 +357,7 @@ private void assertMancombHalfDisabled() throws Exception { .assertName(USER_MANCOMB_USERNAME) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrModifyTsStart, hrModifyTsEnd) .end() .activation() @@ -445,7 +445,7 @@ private void assertMancombDisabled() throws Exception { .assertName(USER_MANCOMB_USERNAME) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrModifyTsStart, hrModifyTsEnd) .end() .activation() @@ -686,7 +686,7 @@ private UserAsserter assertGuybrushCreated(UserAsserter userAsserter return userAsserter .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrCreateTsStart, hrCreateTsEnd) .end() .activation() @@ -815,7 +815,7 @@ private void assertGuybrushEnabled() throws Exception { assertUserAfter(userGuybrushOid) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_ENABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrCreateTsStart, hrCreateTsEnd) .end() .activation() @@ -938,7 +938,7 @@ private void assertGuybrushHalfDisabled() throws Exception { assertUserAfter(userGuybrushOid) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrModifyTsStart, hrModifyTsEnd) .end() .activation() @@ -1037,7 +1037,7 @@ private void assertGuybrushDisabled() throws Exception { assertUserAfter(userGuybrushOid) .assertSubtype(SUBTYPE_EMPLOYEE) .extension() - .assertPropertyValue(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) + .assertPropertyValuesEqual(EXT_HR_STATUS_QNAME, EXT_HR_STATUS_DISABLED) .assertTimestampBetween(EXT_HR_STATUS_CHANGE_TIMESTAMP_QNAME, hrModifyTsStart, hrModifyTsEnd) .end() .activation()