From c7ded2f3479595673e32259c025a29966fce8742 Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Mon, 10 Sep 2018 16:27:26 +0200 Subject: [PATCH] Basic footwork for multitenant security tests (MID-4882) --- .../security/TestSecurityMultitenant.java | 253 ++++++++++++++++++ .../security/multitenant/org-multitenant.xml | 86 ++++++ model/model-intest/testng-integration.xml | 1 + .../test/AbstractModelIntegrationTest.java | 39 ++- .../test/asserter/AssignmentsAsserter.java | 4 - .../midpoint/test/asserter/FocusAsserter.java | 45 +++- .../midpoint/test/asserter/LinkFinder.java | 5 +- .../midpoint/test/asserter/LinksAsserter.java | 2 +- .../midpoint/test/asserter/OrgAsserter.java | 241 +++++++++++++++++ .../test/asserter/ParentOrgRefAsserter.java | 99 +++++++ .../test/asserter/ParentOrgRefFinder.java | 125 +++++++++ .../test/asserter/ParentOrgRefsAsserter.java | 143 ++++++++++ .../test/asserter/PrismObjectAsserter.java | 67 ++++- .../midpoint/test/asserter/UserAsserter.java | 20 ++ 14 files changed, 1099 insertions(+), 31 deletions(-) create mode 100644 model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityMultitenant.java create mode 100644 model/model-intest/src/test/resources/security/multitenant/org-multitenant.xml create mode 100644 repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java create mode 100644 repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefAsserter.java create mode 100644 repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefFinder.java create mode 100644 repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefsAsserter.java diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityMultitenant.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityMultitenant.java new file mode 100644 index 00000000000..4f6797735cc --- /dev/null +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/TestSecurityMultitenant.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2010-2018 Evolveum + * + * Licensed 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 com.evolveum.midpoint.model.intest.security; + +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import javax.xml.datatype.XMLGregorianCalendar; + +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import com.evolveum.midpoint.model.api.ModelAuthorizationAction; +import com.evolveum.midpoint.model.api.RoleSelectionSpecification; +import com.evolveum.midpoint.prism.PrismContainer; +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.path.NameItemPathSegment; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.TypeFilter; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.MiscSchemaUtil; +import com.evolveum.midpoint.security.api.MidPointPrincipal; +import com.evolveum.midpoint.security.enforcer.api.AuthorizationParameters; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.DummyResourceContoller; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.util.exception.CommunicationException; +import com.evolveum.midpoint.util.exception.ConfigurationException; +import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; +import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.PolicyViolationException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ImportOptionsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ExclusionPolicyConstraintType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ModelExecuteOptionsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyExceptionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyRuleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; + +/** + * Security tests for multitenant environment. + * + * @author semancik + */ +@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestSecurityMultitenant extends AbstractSecurityTest { + + public static final File TEST_DIR = new File("src/test/resources/security/multitenant"); + + protected static final File ORG_MULTITENANT_FILE = new File(TEST_DIR, "org-multitenant.xml"); + + protected static final String ORG_ROOT_OID = "00000000-8888-6666-1111-000000000000"; + + protected static final String ORG_CORRINO_OID = "00000000-8888-6666-1111-000000001000"; + protected static final String ROLE_CORRINO_ADMIN_OID = "00000000-8888-6666-1111-100000001000"; + + protected static final String ORG_ATREIDES_OID = "00000000-8888-6666-1111-000000002000"; + protected static final String ROLE_ATREIDES_ADMIN_OID = "00000000-8888-6666-1111-100000002000"; + + protected static final String ORG_HARKONNEN_OID = "00000000-8888-6666-1111-000000003000"; + protected static final String ROLE_HARKONNEN_ADMIN_OID = "00000000-8888-6666-1111-100000003000"; + +// protected static final File ROLE_X_FILE = new File(TEST_DIR, "role-vault-dweller.xml"); +// protected static final String ROLE_X_OID = "8d8471f4-2906-11e8-9078-4f2b205aa01d"; + + @Override + public void initSystem(Task initTask, OperationResult initResult) throws Exception { + super.initSystem(initTask, initResult); + +// repoAddObjectFromFile(ROLE_VAULT_DWELLER_FILE, initResult); + + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE); + + } + + @Override + protected boolean doAddOrgstruct() { + return false; + } + + @Override + protected String getTopOrgOid() { + return ORG_ROOT_OID; + } + + protected static final int NUMBER_OF_IMPORTED_ROLES = 0; + + protected int getNumberOfRoles() { + return super.getNumberOfRoles() + NUMBER_OF_IMPORTED_ROLES; + } + + /** + * Stay logged in as administrator. Make sure that our assumptions about + * the users and roles are correct. + */ + @Test + public void test000Sanity() throws Exception { + final String TEST_NAME = "test000Sanity"; + displayTestTitle(TEST_NAME); + // GIVEN + cleanupAutzTest(USER_JACK_OID); + + // WHEN + displayWhen(TEST_NAME); + assertSearch(UserType.class, null, NUMBER_OF_ALL_USERS); + assertSearch(RoleType.class, null, getNumberOfRoles()); + + assertReadAllow(NUMBER_OF_ALL_USERS); + assertReadAllowRaw(NUMBER_OF_ALL_USERS); + assertAddAllow(); + assertAddAllowRaw(); + assertModifyAllow(); + assertDeleteAllow(); + + assertGlobalStateUntouched(); + } + + /** + * Stay logged in as administrator. + * Import orgstruct with tenant and roles and everything. + */ + @Test + public void test010ImportOrgstruct() throws Exception { + final String TEST_NAME = "test010ImportOrgstruct"; + displayTestTitle(TEST_NAME); + // GIVEN + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + ImportOptionsType options = MiscSchemaUtil.getDefaultImportOptions(); + ModelExecuteOptionsType modelOptions = new ModelExecuteOptionsType(); + modelOptions.setRaw(false); + options.setModelExecutionOptions(modelOptions); + + // WHEN + displayWhen(TEST_NAME); + importObjectFromFile(ORG_MULTITENANT_FILE, options, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + dumpOrgTree(); + + assertOrgAfter(ORG_ATREIDES_OID) + .assertIsTenant() + .assignments() + .single() + .assertTargetOid(ORG_ROOT_OID) + .end() + .end() + .assertLinks(0) + .assertParentOrgRefs(ORG_ROOT_OID); + + assertRoleAfter(ROLE_CORRINO_ADMIN_OID) +// .assertTenantRef(ORG_ATREIDES_OID) + .assertParentOrgRefs(ORG_ATREIDES_OID); + + assertGlobalStateUntouched(); + } + + /** + */ + @Test(enabled=false) // work in progress + public void test080AutzJackEndUserPassword() throws Exception { + final String TEST_NAME = "test080AutzJackEndUserPassword"; + displayTestTitle(TEST_NAME); + // GIVEN + cleanupAutzTest(USER_JACK_OID); + +// assignRole(USER_JACK_OID, ROLE_END_USER_OID); + + login(USER_JACK_USERNAME); + + // WHEN + displayWhen(TEST_NAME); + +// assertAllow("set jack's password", +// (task, result) -> modifyUserSetPassword(USER_JACK_OID, "nbusr123", task, result) ); + + // THEN + displayThen(TEST_NAME); + +// XMLGregorianCalendar endTs = clock.currentTimeXMLGregorianCalendar(); +// +// user = getUser(USER_JACK_OID); +// display("user after password change", user); +// PasswordType passwordType = assertUserPassword(user, "nbusr123"); +// MetadataType metadata = passwordType.getMetadata(); +// assertNotNull("No password metadata", metadata); +// assertMetadata("password metadata", metadata, true, false, startTs, endTs, USER_JACK_OID, SchemaConstants.CHANNEL_GUI_USER_URI); + + assertGlobalStateUntouched(); + } + +} diff --git a/model/model-intest/src/test/resources/security/multitenant/org-multitenant.xml b/model/model-intest/src/test/resources/security/multitenant/org-multitenant.xml new file mode 100644 index 00000000000..9728c3f61f7 --- /dev/null +++ b/model/model-intest/src/test/resources/security/multitenant/org-multitenant.xml @@ -0,0 +1,86 @@ + + + + + + + 0000 + Root of the multitenant structure + tenancy + Multitenant root + 0000 + + + + Corrino + tenancy + + + + House Corrino + 1000 + Kaitain + true + + + + Corrino Admin + + + + + + + Atreides + tenancy + + + + House Atreides + 2000 + Caladan + true + + + + Atreides Admin + + + + + + + Harkonnen + tenancy + + + + House Harkonnen + 3000 + Giedi Prime + true + + + + Harkonnen Admin + + + + + + diff --git a/model/model-intest/testng-integration.xml b/model/model-intest/testng-integration.xml index 2522e64e63c..d1f40366fcf 100644 --- a/model/model-intest/testng-integration.xml +++ b/model/model-intest/testng-integration.xml @@ -144,6 +144,7 @@ + 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 4c8a19b22a4..8918d860046 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 @@ -164,6 +164,7 @@ import com.evolveum.midpoint.test.asserter.AbstractAsserter; import com.evolveum.midpoint.test.asserter.DummyAccountAsserter; import com.evolveum.midpoint.test.asserter.FocusAsserter; +import com.evolveum.midpoint.test.asserter.OrgAsserter; import com.evolveum.midpoint.test.asserter.ShadowAsserter; import com.evolveum.midpoint.test.asserter.UserAsserter; import com.evolveum.midpoint.test.util.MidPointAsserts; @@ -181,6 +182,7 @@ import com.evolveum.midpoint.util.exception.TunnelException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ImportOptionsType; 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.ActivationType; @@ -428,8 +430,12 @@ protected void importObjectFromFile(File file, OperationResult result) throws Fi } protected void importObjectFromFile(File file, Task task, OperationResult result) throws FileNotFoundException { + importObjectFromFile(file, MiscSchemaUtil.getDefaultImportOptions(), task, result); + } + + protected void importObjectFromFile(File file, ImportOptionsType options, Task task, OperationResult result) throws FileNotFoundException { FileInputStream stream = new FileInputStream(file); - modelService.importObjectsFromStream(stream, MiscSchemaUtil.getDefaultImportOptions(), task, result); + modelService.importObjectsFromStream(stream, PrismContext.LANG_XML, options, task, result); } protected Throwable findCause(OperationResult result) { @@ -5417,6 +5423,37 @@ protected UserAsserter assertUserByUsername(String username, String messag return asserter; } + protected OrgAsserter assertOrg(String oid, String message) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + PrismObject org = getObject(OrgType.class, oid); + OrgAsserter asserter = OrgAsserter.forOrg(org, message); + initializeAsserter(asserter); + asserter.assertOid(oid); + return asserter; + } + + protected OrgAsserter assertOrgAfter(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + OrgAsserter asserter = assertOrg(oid, "after"); + asserter.display(); + asserter.assertOid(oid); + return asserter; + } + + protected FocusAsserter assertRole(String oid, String message) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + PrismObject role = getObject(RoleType.class, oid); + // TODO: change to ServiceAsserter later + FocusAsserter asserter = FocusAsserter.forFocus(role, message); + initializeAsserter(asserter); + asserter.assertOid(oid); + return asserter; + } + + protected FocusAsserter assertRoleAfter(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + FocusAsserter asserter = assertRole(oid, "after"); + asserter.display(); + asserter.assertOid(oid); + return asserter; + } + protected FocusAsserter assertService(String oid, String message) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { PrismObject service = getObject(ServiceType.class, oid); // TODO: change to ServiceAsserter later diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AssignmentsAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AssignmentsAsserter.java index 40d60fc4afe..1a4637a2c98 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AssignmentsAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AssignmentsAsserter.java @@ -62,10 +62,6 @@ public static AssignmentsAsserter, return new AssignmentsAsserter<>(FocusAsserter.forFocus(focus)); } - PrismObject getLinkTarget(String oid) throws ObjectNotFoundException, SchemaException { - return focusAsserter.getLinkTarget(oid); - } - List getAssignments() { if (assignments == null) { assignments = getFocus().asObjectable().getAssignment(); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/FocusAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/FocusAsserter.java index 237dced173f..5a11893c728 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/FocusAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/FocusAsserter.java @@ -42,6 +42,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; @@ -52,8 +53,6 @@ */ public class FocusAsserter extends PrismObjectAsserter { - private Map> projectionCache = new HashMap<>(); - public FocusAsserter(PrismObject focus) { super(focus); } @@ -73,6 +72,16 @@ public static FocusAsserter forFocus(PrismObject FocusAsserter forFocus(PrismObject focus, String details) { return new FocusAsserter<>(focus, details); } + + // :::::::::::::::::::::::::::::::::::::::::: + // : NOTE : WARNING : ATTENTION : LOOK HERE : + // :::::::::::::::::::::::::::::::::::::::::: + // + // If you add any method here, add it also in UserAsserter, OrgAsserter and other subclasses. + // + // It is insane to override all those methods from superclass. + // But there is no better way to specify something like type in Java. + // This is lesser evil. @Override public FocusAsserter assertOid() { @@ -110,6 +119,12 @@ public FocusAsserter assertDescription(String expected) { return this; } + @Override + public FocusAsserter assertTenantRef(String expectedOid) { + super.assertTenantRef(expectedOid); + return this; + } + @Override public FocusAsserter assertLifecycleState(String expected) { super.assertLifecycleState(expected); @@ -178,6 +193,19 @@ public ShadowReferenceAsserter> singleLink() { return asserter; } + @Override + public ParentOrgRefsAsserter, RA> parentOrgRefs() { + ParentOrgRefsAsserter,RA> asserter = new ParentOrgRefsAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + @Override + public FocusAsserter assertParentOrgRefs(String... expectedOids) { + super.assertParentOrgRefs(expectedOids); + return this; + } + public FocusAsserter assertHasProjectionOnResource(String resourceOid) throws ObjectNotFoundException, SchemaException { PrismObject shadow = findProjectionOnResource(resourceOid); assertNotNull("Projection for resource "+resourceOid+" not found in "+desc(), shadow); @@ -219,19 +247,12 @@ private List> getLinkTargets() throws ObjectNotFoundExce for (ObjectReferenceType linkRefType: focusType.getLinkRef()) { String linkTargetOid = linkRefType.getOid(); assertFalse("No linkRef oid in "+desc(), StringUtils.isBlank(linkTargetOid)); - shadows.add(getLinkTarget(linkTargetOid)); + shadows.add(getCachedObject(ShadowType.class, linkTargetOid)); } return shadows; } - PrismObject getLinkTarget(String oid) throws ObjectNotFoundException, SchemaException { - PrismObject shadow = projectionCache.get(oid); - if (shadow == null) { - shadow = resolveObject(ShadowType.class, oid); - projectionCache.put(oid, shadow); - } - return shadow; - } + public FocusAsserter displayWithProjections() throws ObjectNotFoundException, SchemaException { StringBuilder sb = new StringBuilder(); @@ -242,7 +263,7 @@ public FocusAsserter displayWithProjections() throws ObjectNotFoundExcept String linkTargetOid = linkRefType.getOid(); assertFalse("No linkRef oid in "+desc(), StringUtils.isBlank(linkTargetOid)); try { - PrismObject linkTarget = getLinkTarget(linkTargetOid); + PrismObject linkTarget = getCachedObject(ShadowType.class, linkTargetOid); sb.append(linkTarget); ShadowType shadowType = linkTarget.asObjectable(); ObjectReferenceType resourceRef = shadowType.getResourceRef(); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinkFinder.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinkFinder.java index bad3d490c31..55109424485 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinkFinder.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinkFinder.java @@ -36,8 +36,11 @@ import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; /** + * + * Note: considered to align this with ParentOrgRefFinder into some kind of common superclass. + * But the resulting structure of generics is just too insane. It is lesser evil to have copy&pasted code. + * * @author semancik - * */ public class LinkFinder,RA> { diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinksAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinksAsserter.java index 68a39e1968c..72a5544ef6c 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinksAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/LinksAsserter.java @@ -60,7 +60,7 @@ public static LinksAsserter,Void> } PrismObject getLinkTarget(String oid) throws ObjectNotFoundException, SchemaException { - return focusAsserter.getLinkTarget(oid); + return focusAsserter.getCachedObject(ShadowType.class, oid); } List getLinks() { 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 new file mode 100644 index 00000000000..caa62a04615 --- /dev/null +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/OrgAsserter.java @@ -0,0 +1,241 @@ +/** + * Copyright (c) 2018 Evolveum + * + * Licensed 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 com.evolveum.midpoint.test.asserter; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.crypto.EncryptionException; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsStorageTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; + +/** + * @author semancik + * + */ +public class OrgAsserter extends FocusAsserter { + + public OrgAsserter(PrismObject focus) { + super(focus); + } + + public OrgAsserter(PrismObject focus, String details) { + super(focus, details); + } + + public OrgAsserter(PrismObject focus, RA returnAsserter, String details) { + super(focus, returnAsserter, details); + } + + public static OrgAsserter forOrg(PrismObject focus) { + return new OrgAsserter<>(focus); + } + + public static OrgAsserter forOrg(PrismObject focus, String details) { + return new OrgAsserter<>(focus, details); + } + + // It is insane to override all those methods from superclass. + // But there is no better way to specify something like type in Java. + // This is lesser evil. + @Override + public OrgAsserter assertOid() { + super.assertOid(); + return this; + } + + @Override + public OrgAsserter assertOid(String expected) { + super.assertOid(expected); + return this; + } + + @Override + public OrgAsserter assertOidDifferentThan(String oid) { + super.assertOidDifferentThan(oid); + return this; + } + + @Override + public OrgAsserter assertName() { + super.assertName(); + return this; + } + + @Override + public OrgAsserter assertName(String expectedOrig) { + super.assertName(expectedOrig); + return this; + } + + @Override + public OrgAsserter assertDescription(String expected) { + super.assertDescription(expected); + return this; + } + + @Override + public OrgAsserter assertTenantRef(String expectedOid) { + super.assertTenantRef(expectedOid); + return this; + } + + @Override + public OrgAsserter assertLifecycleState(String expected) { + super.assertLifecycleState(expected); + return this; + } + + @Override + public OrgAsserter assertActiveLifecycleState() { + super.assertActiveLifecycleState(); + return this; + } + + public OrgAsserter assertAdministrativeStatus(ActivationStatusType expected) { + ActivationType activation = getActivation(); + if (activation == null) { + if (expected == null) { + return this; + } else { + fail("No activation in "+desc()); + } + } + assertEquals("Wrong activation administrativeStatus in "+desc(), expected, activation.getAdministrativeStatus()); + return this; + } + + private ActivationType getActivation() { + return getObject().asObjectable().getActivation(); + } + + public OrgAsserter display() { + super.display(); + return this; + } + + public OrgAsserter display(String message) { + super.display(message); + return this; + } + + @Override + public ActivationAsserter, RA> activation() { + ActivationAsserter, RA> asserter = new ActivationAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + @Override + public LinksAsserter, RA> links() { + LinksAsserter, RA> asserter = new LinksAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + @Override + public OrgAsserter assertLinks(int expected) { + super.assertLinks(expected); + return this; + } + + @Override + public AssignmentsAsserter, RA> assignments() { + AssignmentsAsserter, RA> asserter = new AssignmentsAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + public OrgAsserter assertDisplayName(String expectedOrig) { + assertPolyStringProperty(OrgType.F_DISPLAY_NAME, expectedOrig); + return this; + } + + public OrgAsserter assertLocality(String expectedOrig) { + assertPolyStringProperty(OrgType.F_LOCALITY, expectedOrig); + return this; + } + + public OrgAsserter assertIsTenant() { + assertPropertyEquals(OrgType.F_TENANT, true); + return this; + } + + @Override + public OrgAsserter assertHasProjectionOnResource(String resourceOid) throws ObjectNotFoundException, SchemaException { + super.assertHasProjectionOnResource(resourceOid); + return this; + } + + @Override + public ShadowAsserter> projectionOnResource(String resourceOid) throws ObjectNotFoundException, SchemaException { + return super.projectionOnResource(resourceOid); + } + + @Override + public OrgAsserter displayWithProjections() throws ObjectNotFoundException, SchemaException { + super.displayWithProjections(); + return this; + } + + @Override + public ShadowReferenceAsserter> singleLink() { + return (ShadowReferenceAsserter>) super.singleLink(); + } + + @Override + public OrgAsserter assertAssignments(int expected) { + super.assertAssignments(expected); + return this; + } + + @Override + public ParentOrgRefsAsserter, RA> parentOrgRefs() { + ParentOrgRefsAsserter, RA> asserter = new ParentOrgRefsAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + @Override + public OrgAsserter assertParentOrgRefs(String... expectedOids) { + super.assertParentOrgRefs(expectedOids); + return this; + } + +} diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefAsserter.java new file mode 100644 index 00000000000..05dad61a741 --- /dev/null +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefAsserter.java @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2018 Evolveum + * + * Licensed 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 com.evolveum.midpoint.test.asserter; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.namespace.QName; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.schema.DeltaConvertor; +import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.test.util.TestUtil; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; + +/** + * @author semancik + * + */ +public class ParentOrgRefAsserter extends ObjectReferenceAsserter { + + public ParentOrgRefAsserter(PrismReferenceValue refVal) { + super(refVal, OrgType.class); + } + + public ParentOrgRefAsserter(PrismReferenceValue refVal, String detail) { + super(refVal, OrgType.class, detail); + } + + public ParentOrgRefAsserter(PrismReferenceValue refVal, PrismObject resolvedTarget, R returnAsserter, String detail) { + super(refVal, OrgType.class, resolvedTarget, returnAsserter, detail); + } + + @Override + public ParentOrgRefAsserter assertOid() { + super.assertOid(); + return this; + } + + @Override + public ParentOrgRefAsserter assertOid(String expected) { + super.assertOid(expected); + return this; + } + + @Override + public ParentOrgRefAsserter assertOidDifferentThan(String expected) { + super.assertOidDifferentThan(expected); + return this; + } + + public ShadowAsserter> shadow() { + ShadowAsserter> asserter = new ShadowAsserter<>((PrismObject)getRefVal().getObject(), this, "shadow in reference "+desc()); + copySetupTo(asserter); + return asserter; + } + + @Override + public FocusAsserter> target() + throws ObjectNotFoundException, SchemaException { + return new FocusAsserter<>(getResolvedTarget(), this, "object resolved from "+desc()); + } + + @Override + public FocusAsserter> resolveTarget() + throws ObjectNotFoundException, SchemaException { + PrismObject object = resolveTargetObject(); + return new FocusAsserter<>(object, this, "object resolved from "+desc()); + } + +} diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefFinder.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefFinder.java new file mode 100644 index 00000000000..52d367faff2 --- /dev/null +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefFinder.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2018 Evolveum + * + * Licensed 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 com.evolveum.midpoint.test.asserter; + +import static org.testng.AssertJUnit.assertEquals; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.testng.AssertJUnit; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.util.ShadowUtil; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; +import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType; +import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; + +/** + * + * Note: considered to align this with ParentOrgRefFinder into some kind of common superclass. + * But the resulting structure of generics is just too insane. It is lesser evil to have copy&pasted code. + * + * @author semancik + */ +public class ParentOrgRefFinder,RA> { + + private final ParentOrgRefsAsserter refsAsserter; + private String targetOid; + private QName relation; + + public ParentOrgRefFinder(ParentOrgRefsAsserter refsAsserter) { + this.refsAsserter = refsAsserter; + } + + public ParentOrgRefFinder targetOid(String targetOid) { + this.targetOid = targetOid; + return this; + } + + public ParentOrgRefFinder relation(QName relation) { + this.relation = relation; + return this; + } + + public ParentOrgRefAsserter> find() throws ObjectNotFoundException, SchemaException { + PrismReferenceValue found = null; + PrismObject foundTarget = null; + for (PrismReferenceValue ref: refsAsserter.getRefs()) { + PrismObject refTarget = refsAsserter.getRefTarget(ref.getOid()); + if (matches(ref, refTarget)) { + if (found == null) { + found = ref; + foundTarget = refTarget; + } else { + fail("Found more than one parentOrgRef that matches search criteria"); + } + } + } + if (found == null) { + fail("Found no parentOrgRef that matches search criteria"); + } + return refsAsserter.forRef(found, foundTarget); + } + + public ParentOrgRefsAsserter assertCount(int expectedCount) throws ObjectNotFoundException, SchemaException { + int foundCount = 0; + for (PrismReferenceValue ref: refsAsserter.getRefs()) { + PrismObject linkTarget = refsAsserter.getRefTarget(ref.getOid()); + if (matches(ref, linkTarget)) { + foundCount++; + } + } + assertEquals("Wrong number of links for specified criteria in "+refsAsserter.desc(), expectedCount, foundCount); + return refsAsserter; + } + + private boolean matches(PrismReferenceValue refVal, PrismObject refTarget) throws ObjectNotFoundException, SchemaException { + OrgType refTargetType = refTarget.asObjectable(); + + if (targetOid != null) { + if (!targetOid.equals(refVal.getOid())) { + return false; + } + } + + if (relation != null) { + if (!QNameUtil.match(relation, refVal.getRelation())) { + return false; + } + } + + // TODO: more criteria + return true; + } + + protected void fail(String message) { + AssertJUnit.fail(message); + } + +} diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefsAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefsAsserter.java new file mode 100644 index 00000000000..e5e057dc5b8 --- /dev/null +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/ParentOrgRefsAsserter.java @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2018 Evolveum + * + * Licensed 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 com.evolveum.midpoint.test.asserter; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.PrismReferenceValue; +import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationExecutionStatusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; + +/** + * + * Note: considered to align this with LinksAsserter into some kind of common superclass. + * But the resulting structure of generics is just too insane. It is lesser evil to have copy&pasted code. + * + * @author semancik + */ +public class ParentOrgRefsAsserter,RA> extends AbstractAsserter { + + private OA objectAsserter; + private List parentOrgRefs; + + public ParentOrgRefsAsserter(OA objectAsserter) { + super(); + this.objectAsserter = objectAsserter; + } + + public ParentOrgRefsAsserter(OA focusAsserter, String details) { + super(details); + this.objectAsserter = focusAsserter; + } + + public static ParentOrgRefsAsserter,Void> forFocus(PrismObject focus) { + return new ParentOrgRefsAsserter<>(FocusAsserter.forFocus(focus)); + } + + PrismObject getRefTarget(String oid) throws ObjectNotFoundException, SchemaException { + return objectAsserter.getCachedObject(OrgType.class, oid); + } + + List getRefs() { + if (parentOrgRefs == null) { + PrismReference linkRef = getFocus().findReference(FocusType.F_PARENT_ORG_REF); + if (linkRef == null) { + parentOrgRefs = new ArrayList<>(); + } else { + parentOrgRefs = linkRef.getValues(); + } + } + return parentOrgRefs; + } + + public ParentOrgRefsAsserter assertRefs(int expected) { + assertEquals("Wrong number of parentOrgRefs in " + desc(), expected, getRefs().size()); + return this; + } + + public ParentOrgRefsAsserter assertNone() { + assertRefs(0); + return this; + } + + public ParentOrgRefsAsserter assertRefs(String... expectedOids) { + PrismAsserts.assertEqualsCollectionUnordered("Wrong parentOrgRefs in " + desc(), getOids(), expectedOids); + return this; + } + + ParentOrgRefAsserter> forRef(PrismReferenceValue refVal, PrismObject target) { + ParentOrgRefAsserter> asserter = new ParentOrgRefAsserter<>(refVal, target, this, "parentOrgRef in "+desc()); + copySetupTo(asserter); + return asserter; + } + + public ParentOrgRefAsserter> single() { + assertRefs(1); + return forRef(getRefs().get(0), null); + } + + PrismObject getFocus() { + return objectAsserter.getObject(); + } + + @Override + public OA end() { + return objectAsserter; + } + + @Override + protected String desc() { + return descWithDetails("parentOrgRefs of "+getFocus()); + } + + public ParentOrgRefFinder by() { + return new ParentOrgRefFinder<>(this); + } + + public ParentOrgRefsAsserter hasTarget(String targetOid) throws ObjectNotFoundException, SchemaException { + return by() + .targetOid(targetOid) + .find() + .end(); + } + + public List getOids() { + List oids = new ArrayList<>(); + for (PrismReferenceValue ref: getRefs()) { + oids.add(ref.getOid()); + } + return oids; + } + +} diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismObjectAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismObjectAsserter.java index 6d850afcf0d..cb825cffb19 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismObjectAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/PrismObjectAsserter.java @@ -21,7 +21,9 @@ import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.xml.namespace.QName; @@ -31,6 +33,9 @@ import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.util.exception.ObjectNotFoundException; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; @@ -39,9 +44,12 @@ * @author semancik * */ -public class PrismObjectAsserter extends AbstractAsserter { +public class PrismObjectAsserter extends AbstractAsserter { private PrismObject object; + + // Cache of focus-related objects: projections, targets, orgs, ... + private Map> objectCache = new HashMap<>(); public PrismObjectAsserter(PrismObject object) { super(); @@ -53,7 +61,7 @@ public PrismObjectAsserter(PrismObject object, String details) { this.object = object; } - public PrismObjectAsserter(PrismObject object, R returnAsserter, String details) { + public PrismObjectAsserter(PrismObject object, RA returnAsserter, String details) { super(returnAsserter, details); this.object = object; } @@ -70,43 +78,50 @@ public static PrismObjectAsserter forObject(Prism return new PrismObjectAsserter<>(shadow, details); } - public PrismObjectAsserter assertOid() { + public PrismObjectAsserter assertOid() { assertNotNull("No OID in "+desc(), getObject().getOid()); return this; } - public PrismObjectAsserter assertOid(String expected) { + public PrismObjectAsserter assertOid(String expected) { assertEquals("Wrong OID in "+desc(), expected, getObject().getOid()); return this; } - public PrismObjectAsserter assertOidDifferentThan(String oid) { + public PrismObjectAsserter assertOidDifferentThan(String oid) { assertFalse("Expected that "+desc()+" will have different OID than "+oid+", but it has the same", oid.equals(getObject().getOid())); return this; } - public PrismObjectAsserter assertName() { + public PrismObjectAsserter assertName() { assertNotNull("No name in "+desc(), getObject().getName()); return this; } - public PrismObjectAsserter assertName(String expectedOrig) { + public PrismObjectAsserter assertName(String expectedOrig) { PrismAsserts.assertEqualsPolyString("Wrong name in "+desc(), expectedOrig, getObject().getName()); return this; } - public PrismObjectAsserter assertDescription(String expected) { + public PrismObjectAsserter assertDescription(String expected) { assertEquals("Wrong description in "+desc(), expected, getObject().asObjectable().getDescription()); return this; } - public PrismObjectAsserter assertLifecycleState(String expected) { + public PrismObjectAsserter assertTenantRef(String expectedOid) { + ObjectReferenceType tenantRef = getObject().asObjectable().getTenantRef(); + assertNotNull("No tenantRef in "+desc(), tenantRef); + assertEquals("Wrong tenantRef OID in "+desc(), expectedOid, tenantRef.getOid()); + return this; + } + + public PrismObjectAsserter assertLifecycleState(String expected) { assertEquals("Wrong lifecycleState in "+desc(), expected, getObject().asObjectable().getLifecycleState()); return this; } - public PrismObjectAsserter assertActiveLifecycleState() { + public PrismObjectAsserter assertActiveLifecycleState() { String actualLifecycleState = getObject().asObjectable().getLifecycleState(); if (actualLifecycleState != null) { assertEquals("Wrong lifecycleState in "+desc(), SchemaConstants.LIFECYCLE_ACTIVE, actualLifecycleState); @@ -118,12 +133,12 @@ protected String desc() { return descWithDetails(object); } - public PrismObjectAsserter display() { + public PrismObjectAsserter display() { display(desc()); return this; } - public PrismObjectAsserter display(String message) { + public PrismObjectAsserter display(String message) { IntegrationTestTools.display(message, object); return this; } @@ -134,8 +149,36 @@ protected void assertPolyStringProperty(QName propName, String expectedOrig) { PrismAsserts.assertEqualsPolyString("Wrong "+propName.getLocalPart()+" in "+desc(), expectedOrig, prop.getRealValue()); } + protected void assertPropertyEquals(QName propName, T expected) { + PrismProperty prop = getObject().findProperty(propName); + assertNotNull("No "+propName.getLocalPart()+" in "+desc(), prop); + T realValue = prop.getRealValue(); + assertNotNull("No value in "+propName.getLocalPart()+" in "+desc(), realValue); + assertEquals("Wrong "+propName.getLocalPart()+" in "+desc(), expected, realValue); + } + public String getOid() { return getObject().getOid(); } + + public ParentOrgRefsAsserter, RA> parentOrgRefs() { + ParentOrgRefsAsserter,RA> asserter = new ParentOrgRefsAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + + public PrismObjectAsserter assertParentOrgRefs(String... expectedOids) { + parentOrgRefs().assertRefs(expectedOids); + return this; + } + + PrismObject getCachedObject(Class type, String oid) throws ObjectNotFoundException, SchemaException { + PrismObject object = (PrismObject) objectCache.get(oid); + if (object == null) { + object = resolveObject(type, oid); + objectCache.put(oid, object); + } + return object; + } } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java index cf868d8dbdd..ceb8accdb62 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java @@ -70,6 +70,9 @@ public static UserAsserter forUser(PrismObject focus, String det return new UserAsserter<>(focus, details); } + // It is insane to override all those methods from superclass. + // But there is no better way to specify something like type in Java. + // This is lesser evil. @Override public UserAsserter assertOid() { super.assertOid(); @@ -106,6 +109,12 @@ public UserAsserter assertDescription(String expected) { return this; } + @Override + public UserAsserter assertTenantRef(String expectedOid) { + super.assertTenantRef(expectedOid); + return this; + } + @Override public UserAsserter assertLifecycleState(String expected) { super.assertLifecycleState(expected); @@ -230,5 +239,16 @@ public UserAsserter assertAssignments(int expected) { return this; } + @Override + public ParentOrgRefsAsserter, RA> parentOrgRefs() { + ParentOrgRefsAsserter, RA> asserter = new ParentOrgRefsAsserter<>(this, getDetails()); + copySetupTo(asserter); + return asserter; + } + @Override + public UserAsserter assertParentOrgRefs(String... expectedOids) { + super.assertParentOrgRefs(expectedOids); + return this; + } }