diff --git a/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/match/PolyStringStrictMatchingRule.java b/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/match/PolyStringStrictMatchingRule.java index 280801c9216..c8d689c3901 100644 --- a/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/match/PolyStringStrictMatchingRule.java +++ b/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/match/PolyStringStrictMatchingRule.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. @@ -58,7 +58,9 @@ public boolean match(PolyString a, PolyString b) { if (a == null || b == null) { return false; } - return MiscUtil.equals(a.getOrig(), b.getOrig()) && MiscUtil.equals(a.getNorm(), b.getNorm()); + // Delegate to PolyString.equals(). This does it well. As we want to compare + // all aspects of polystring here: orig, norm, translations, langs + return a.equals(b); } /* (non-Javadoc) diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java index c3d25c98cdf..f3e02a5c102 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/opendj/TestOpenDj.java @@ -85,6 +85,7 @@ import com.evolveum.midpoint.test.util.MidPointAsserts; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.JAXBUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.CommunicationException; @@ -145,6 +146,33 @@ @DirtiesContext public class TestOpenDj extends AbstractOpenDjTest { + protected static final String USER_JACK_FULL_NAME = "Jack Sparrow"; + + private static final String[] JACK_FULL_NAME_LANG_EN_SK = { + "en", "Jack Sparrow", + "sk", "Džek Sperou" + }; + + private static final String[] JACK_FULL_NAME_LANG_EN_SK_RU_HR = { + "en", "Jack Sparrow", + "sk", "Džek Sperou", + "ru", "Джек Воробей", + "hr", "Ðek Sperou" + }; + + private static final String[] JACK_FULL_NAME_LANG_CZ_HR = { + "cz", "Džek Sperou", + "hr", "Ðek Sperou" + }; + + protected static final String USER_JACK_FULL_NAME_CAPTAIN = "Captain Jack Sparrow"; + + private static final String[] JACK_FULL_NAME_LANG_CAPTAIN_EN_CZ_SK = { + "en", "Captain Jack Sparrow", + "cz", "Kapitán Džek Sperou", + "sk", "Kapitán Džek Sperou" + }; + private static Trace LOGGER = TraceManager.getTrace(TestOpenDj.class); private String groupSailorOid; @@ -163,6 +191,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti openDJController.addEntry("dn: ou=specialgroups,dc=example,dc=com\n"+ "objectclass: organizationalUnit\n"+ "ou: specialgroups\n"); + + DebugUtil.setDetailedDebugDump(true); } @BeforeClass @@ -2961,7 +2991,8 @@ public void test472ModifyAccountJackDescriptionOrig() throws Exception { PolyString descriptionBefore = new PolyString("Bar"); - PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create(ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), + PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create( + ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), null); descriptionDelta.setRealValuesToReplace(descriptionBefore); @@ -2980,9 +3011,7 @@ public void test472ModifyAccountJackDescriptionOrig() throws Exception { Entry entry = openDJController.searchByUid("rename"); display("LDAP Entry", entry); - String descriptionStringAfter = OpenDJController.getAttributeValue(entry, ATTRIBUTE_DESCRIPTION_NAME); - assertNotNull("No description in LDAP entry", descriptionStringAfter); - assertEquals("Unexpected description in LDAP entry", descriptionBefore.getOrig(), descriptionStringAfter); + assertDescription(entry, descriptionBefore.getOrig() /* no langs */); PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); @@ -2991,10 +3020,220 @@ public void test472ModifyAccountJackDescriptionOrig() throws Exception { PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); PrismProperty descAttr = attributesContainer.findProperty(ATTRIBUTE_DESCRIPTION_QNAME); - PolyString descriptionPolyStringAfter = descAttr.getValues().get(0).getValue(); - display("description after (shadow)", descriptionPolyStringAfter); + assertPolyString(descAttr.getValues().get(0).getValue(), "description after (shadow from provisioning)") + .assertOrig(descriptionBefore.getOrig()) + .assertNoLangs(); + + assertShadows(25); + } + + /** + * Description is a "language tag" attribute (PolyString). + * Modification with languages. + * MID-5210 + */ + @Test + public void test474ModifyAccountJackDescriptionLangEnSk() throws Exception { + final String TEST_NAME = "test474ModifyAccountJackDescriptionLangEnSk"; + displayTestTitle(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString descriptionBefore = new PolyString(USER_JACK_FULL_NAME); + descriptionBefore.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_EN_SK)); + + PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create( + ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), + null); + descriptionDelta.setRealValuesToReplace(descriptionBefore); + + Collection modifications = MiscSchemaUtil.createCollection(descriptionDelta); + + display("Modifications",modifications); + + // WHEN + displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, ACCOUNT_JACK_OID, + modifications, null, null, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + Entry entry = openDJController.searchByUid("rename"); + display("LDAP Entry", entry); + assertDescription(entry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_EN_SK); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); + + display("Object after change",shadow); + + PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); + PrismProperty descAttr = attributesContainer.findProperty(ATTRIBUTE_DESCRIPTION_QNAME); + assertPolyString(descAttr.getValues().get(0).getValue(), "description after (shadow from provisioning)") + .assertOrig(descriptionBefore.getOrig()) + .assertLangs(JACK_FULL_NAME_LANG_EN_SK); + + + assertShadows(25); + } + + /** + * Description is a "language tag" attribute (PolyString). + * Modification with more languages. + * MID-5210 + */ + @Test + public void test476ModifyAccountJackDescriptionLangEnSkRuHr() throws Exception { + final String TEST_NAME = "test476ModifyAccountJackDescriptionLangEnSkRuHr"; + displayTestTitle(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString descriptionBefore = new PolyString(USER_JACK_FULL_NAME); + descriptionBefore.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_EN_SK_RU_HR)); + + PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create( + ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), + null); + descriptionDelta.setRealValuesToReplace(descriptionBefore); + + Collection modifications = MiscSchemaUtil.createCollection(descriptionDelta); + + display("Modifications",modifications); + + // WHEN + displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, ACCOUNT_JACK_OID, + modifications, null, null, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + Entry entry = openDJController.searchByUid("rename"); + display("LDAP Entry", entry); + assertDescription(entry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_EN_SK_RU_HR); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); + + display("Object after change",shadow); + + PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); + PrismProperty descAttr = attributesContainer.findProperty(ATTRIBUTE_DESCRIPTION_QNAME); + assertPolyString(descAttr.getValues().get(0).getValue(), "description after (shadow from provisioning)") + .assertOrig(descriptionBefore.getOrig()) + .assertLangs(JACK_FULL_NAME_LANG_EN_SK_RU_HR); + + + assertShadows(25); + } + + /** + * Description is a "language tag" attribute (PolyString). + * Modification with languages, some are new, some are deleted. + * MID-5210 + */ + @Test + public void test478ModifyAccountJackDescriptionLangEnSkRuHr() throws Exception { + final String TEST_NAME = "test478ModifyAccountJackDescriptionLangEnSkRuHr"; + displayTestTitle(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString descriptionBefore = new PolyString(USER_JACK_FULL_NAME); + descriptionBefore.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_CZ_HR)); + + PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create( + ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), + null); + descriptionDelta.setRealValuesToReplace(descriptionBefore); + + Collection modifications = MiscSchemaUtil.createCollection(descriptionDelta); + + display("Modifications",modifications); + + // WHEN + displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, ACCOUNT_JACK_OID, + modifications, null, null, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + Entry entry = openDJController.searchByUid("rename"); + display("LDAP Entry", entry); + assertDescription(entry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_CZ_HR); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); + + display("Object after change",shadow); + + PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); + PrismProperty descAttr = attributesContainer.findProperty(ATTRIBUTE_DESCRIPTION_QNAME); + assertPolyString(descAttr.getValues().get(0).getValue(), "description after (shadow from provisioning)") + .assertOrig(descriptionBefore.getOrig()) + .assertLangs(JACK_FULL_NAME_LANG_CZ_HR); + + + assertShadows(25); + } + + /** + * Description is a "language tag" attribute (PolyString). + * Modification without any values. Clean slate again. + * MID-5210 + */ + @Test + public void test479ModifyAccountJackDescriptionJack() throws Exception { + final String TEST_NAME = "test479ModifyAccountJackDescriptionJack"; + displayTestTitle(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString descriptionBefore = new PolyString(USER_JACK_FULL_NAME); + + PropertyDelta descriptionDelta = prismContext.deltaFactory().property().create( + ItemPath.create(ShadowType.F_ATTRIBUTES, ATTRIBUTE_DESCRIPTION_QNAME), + null); + descriptionDelta.setRealValuesToReplace(descriptionBefore); + + Collection modifications = MiscSchemaUtil.createCollection(descriptionDelta); + + display("Modifications",modifications); + + // WHEN + displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, ACCOUNT_JACK_OID, + modifications, null, null, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + Entry entry = openDJController.searchByUid("rename"); + display("LDAP Entry", entry); + assertDescription(entry, USER_JACK_FULL_NAME /* no langs */); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); + + display("Object after change",shadow); + + PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); + PrismProperty descAttr = attributesContainer.findProperty(ATTRIBUTE_DESCRIPTION_QNAME); + assertPolyString(descAttr.getValues().get(0).getValue(), "description after (shadow from provisioning)") + .assertOrig(descriptionBefore.getOrig()) + .assertNoLangs(); - assertEquals("Wrong orig in description polystring (shadow)", descriptionBefore.getOrig(), descriptionPolyStringAfter.getOrig()); assertShadows(25); } @@ -3174,4 +3413,8 @@ protected void assertEntitlementGroup(PrismObject account, String en protected void assertConnectorOperationIncrement(int expectedIncrementSmart, int expectedIncrementDumb) { assertCounterIncrement(InternalCounters.CONNECTOR_OPERATION_COUNT, expectedIncrementSmart); } + + private void assertDescription(Entry entry, String expectedOrigValue, String... params) { + OpenDJController.assertAttributeLang(entry, ATTRIBUTE_DESCRIPTION_NAME, expectedOrigValue, params); + } } diff --git a/provisioning/provisioning-impl/src/test/resources/opendj/resource-opendj.xml b/provisioning/provisioning-impl/src/test/resources/opendj/resource-opendj.xml index 36fda9d6731..96d42b90804 100644 --- a/provisioning/provisioning-impl/src/test/resources/opendj/resource-opendj.xml +++ b/provisioning/provisioning-impl/src/test/resources/opendj/resource-opendj.xml @@ -1,6 +1,6 @@ explicit + + ri:description + + + 1 + + ri:group LDAP Group Membership diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java index 749fa3e3d22..2fc51848c20 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnIdConvertor.java @@ -430,6 +430,9 @@ private Object polyStringFromConnIdMap(Map connIdMap) { lang.put(key, connIdMapEntry.getValue()); } } + if (orig == null) { + return null; + } PolyString polyString = new PolyString(orig); polyString.setLang(lang); return polyString; diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index b6463a4c794..424db8c8609 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -69,6 +69,7 @@ import com.evolveum.midpoint.task.api.TaskManager; import com.evolveum.midpoint.test.asserter.AbstractAsserter; import com.evolveum.midpoint.test.asserter.ShadowAsserter; +import com.evolveum.midpoint.test.asserter.prism.PolyStringAsserter; import com.evolveum.midpoint.test.asserter.refinedschema.RefinedResourceSchemaAsserter; import com.evolveum.midpoint.test.ldap.OpenDJController; import com.evolveum.midpoint.test.util.DerbyController; @@ -2423,6 +2424,12 @@ protected void initializeAsserter(AbstractAsserter asserter) { asserter.setProtector(protector); } + protected PolyStringAsserter assertPolyString(PolyString polystring, String desc) { + PolyStringAsserter asserter = new PolyStringAsserter<>(polystring, desc); + initializeAsserter(asserter); + return asserter; + } + protected RefinedResourceSchemaAsserter assertRefinedResourceSchema(PrismObject resource, String details) throws SchemaException { RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, prismContext); assertNotNull("No refined schema for "+resource+" ("+details+")", refinedSchema); diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/prism/PolyStringAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/prism/PolyStringAsserter.java index 55fae8219d6..76d24cc1f75 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/prism/PolyStringAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/prism/PolyStringAsserter.java @@ -101,6 +101,11 @@ public PolyStringAsserter assertLangs(String... expectedParams) { return this; } + public PolyStringAsserter assertNoLangs() { + assertNull("Unexpected langs in "+desc(), polystring.getLang()); + return this; + } + protected String desc() { return descWithDetails(polystring); } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/ldap/TestLdapPolyString.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/ldap/TestLdapPolyString.java index 74044027202..f9e000cd15f 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/ldap/TestLdapPolyString.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/ldap/TestLdapPolyString.java @@ -17,62 +17,30 @@ package com.evolveum.midpoint.testing.story.ldap; -import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import javax.xml.namespace.QName; - -import org.opends.server.types.Attribute; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; -import org.testng.AssertJUnit; import org.testng.annotations.AfterClass; import org.testng.annotations.Test; -import com.evolveum.midpoint.util.exception.PolicyViolationException; -import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.ldap.OpenDJController; -import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.test.util.TestUtil; -import com.evolveum.midpoint.testing.story.AbstractStoryTest; import com.evolveum.midpoint.testing.story.TestTrafo; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.MiscUtil; -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.SchemaException; -import com.evolveum.midpoint.util.exception.SecurityViolationException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; -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.OrgType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -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.PolyStringType; /** * Testing PolyString all the way to LDAP connector. The PolyString data should be translated @@ -93,6 +61,26 @@ public class TestLdapPolyString extends AbstractLdapTest { "en", "Jack Sparrow", "sk", "Džek Sperou" }; + + private static final String[] JACK_FULL_NAME_LANG_EN_SK_RU_HR = { + "en", "Jack Sparrow", + "sk", "Džek Sperou", + "ru", "Джек Воробей", + "hr", "Ðek Sperou" + }; + + private static final String[] JACK_FULL_NAME_LANG_CZ_HR = { + "cz", "Džek Sperou", + "hr", "Ðek Sperou" + }; + + protected static final String USER_JACK_FULL_NAME_CAPTAIN = "Captain Jack Sparrow"; + + private static final String[] JACK_FULL_NAME_LANG_CAPTAIN_EN_CZ_SK = { + "en", "Captain Jack Sparrow", + "cz", "Kapitán Džek Sperou", + "sk", "Kapitán Džek Sperou" + }; private PrismObject resourceOpenDj; @@ -218,10 +206,191 @@ public void test100ModifyJackFullNameLang() throws Exception { .end() .links() .assertNone(); - } + /** + * Assign LDAP account to jack. Jack's fullName is full of langs, + * those should be translated to description;lang-* LDAP attributes. + * MID-5210 + */ + @Test + public void test110AssignAccountOpenDjLang() throws Exception { + final String TEST_NAME = "test110AssignAccountOpenDjLang"; + displayTestTitle(TEST_NAME); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + assignAccountToUser(USER_JACK_OID, RESOURCE_OPENDJ_OID, null, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + accountJackOid = assertUserAfter(USER_JACK_OID) + .fullName() + .assertOrig(USER_JACK_FULL_NAME) + .assertLangs(JACK_FULL_NAME_LANG_EN_SK) + .end() + .singleLink() + .getOid(); + + assertModelShadow(accountJackOid); + + Entry accountEntry = getLdapEntryByUid(USER_JACK_USERNAME); + display("Jack LDAP entry", accountEntry); + assertCn(accountEntry, USER_JACK_FULL_NAME); + assertDescription(accountEntry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_EN_SK); + } + + /** + * Adding more langs to Jack's fullName. This should update all + * LDAP language tags properly. + */ + @Test + public void test112ModifyJackFullNameLangEnSkRuHr() throws Exception { + final String TEST_NAME = "test112ModifyJackFullNameLangEnSkRuHr"; + displayTestTitle(TEST_NAME); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString newFullName = new PolyString(USER_JACK_FULL_NAME); + newFullName.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_EN_SK_RU_HR)); + + // WHEN + displayWhen(TEST_NAME); + modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, newFullName); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .fullName() + .display() + .assertOrig(USER_JACK_FULL_NAME) + .assertLangs(JACK_FULL_NAME_LANG_EN_SK_RU_HR) + .end() + .singleLink() + .assertOid(accountJackOid); + + Entry accountEntry = getLdapEntryByUid(USER_JACK_USERNAME); + display("Jack LDAP entry", accountEntry); + assertCn(accountEntry, USER_JACK_FULL_NAME); + assertDescription(accountEntry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_EN_SK_RU_HR); + } + + /** + * Modifying langs in Jack's fullName again. Some are removed, some are new. + * This should update all LDAP language tags properly. + */ + @Test + public void test114ModifyJackFullNameLangCzHr() throws Exception { + final String TEST_NAME = "test114ModifyJackFullNameLangCzHr"; + displayTestTitle(TEST_NAME); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString newFullName = new PolyString(USER_JACK_FULL_NAME); + newFullName.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_CZ_HR)); + + // WHEN + displayWhen(TEST_NAME); + modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, newFullName); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .fullName() + .display() + .assertOrig(USER_JACK_FULL_NAME) + .assertLangs(JACK_FULL_NAME_LANG_CZ_HR) + .end() + .singleLink() + .assertOid(accountJackOid); + + Entry accountEntry = getLdapEntryByUid(USER_JACK_USERNAME); + display("Jack LDAP entry", accountEntry); + assertCn(accountEntry, USER_JACK_FULL_NAME); + assertDescription(accountEntry, USER_JACK_FULL_NAME, JACK_FULL_NAME_LANG_CZ_HR); + } + + /** + * Modifying Jack's full name to include proper "Captain" title. + * The orig is also changed this time. + */ + @Test + public void test116ModifyJackFullNameLangCaptain() throws Exception { + final String TEST_NAME = "test116ModifyJackFullNameLangCaptain"; + displayTestTitle(TEST_NAME); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString newFullName = new PolyString(USER_JACK_FULL_NAME_CAPTAIN); + newFullName.setLang(MiscUtil.paramsToMap(JACK_FULL_NAME_LANG_CAPTAIN_EN_CZ_SK)); + + // WHEN + displayWhen(TEST_NAME); + modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, newFullName); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .fullName() + .display() + .assertOrig(USER_JACK_FULL_NAME_CAPTAIN) + .assertLangs(JACK_FULL_NAME_LANG_CAPTAIN_EN_CZ_SK) + .end() + .singleLink() + .assertOid(accountJackOid); + + Entry accountEntry = getLdapEntryByUid(USER_JACK_USERNAME); + display("Jack LDAP entry", accountEntry); + assertCn(accountEntry, USER_JACK_FULL_NAME_CAPTAIN); + assertDescription(accountEntry, USER_JACK_FULL_NAME_CAPTAIN, JACK_FULL_NAME_LANG_CAPTAIN_EN_CZ_SK); + } + + /** + * Back to simple polystring. No langs. + */ + @Test + public void test118ModifyJackFullNameCaptain() throws Exception { + final String TEST_NAME = "test118ModifyJackFullNameCaptain"; + displayTestTitle(TEST_NAME); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + PolyString newFullName = new PolyString(USER_JACK_FULL_NAME_CAPTAIN); + + // WHEN + displayWhen(TEST_NAME); + modifyUserReplace(USER_JACK_OID, UserType.F_FULL_NAME, task, result, newFullName); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .fullName() + .display() + .assertOrig(USER_JACK_FULL_NAME_CAPTAIN) + .assertNoLangs() + .end() + .singleLink() + .assertOid(accountJackOid); + + Entry accountEntry = getLdapEntryByUid(USER_JACK_USERNAME); + display("Jack LDAP entry", accountEntry); + assertCn(accountEntry, USER_JACK_FULL_NAME_CAPTAIN); + assertDescription(accountEntry, USER_JACK_FULL_NAME_CAPTAIN /* no langs */); + } + private Entry getLdapEntryByUid(String uid) throws DirectoryException { return openDJController.searchSingle("uid="+uid); } diff --git a/testing/story/src/test/resources/ldap/polystring/resource-opendj.xml b/testing/story/src/test/resources/ldap/polystring/resource-opendj.xml index b405080ef7c..fb7fcd99803 100644 --- a/testing/story/src/test/resources/ldap/polystring/resource-opendj.xml +++ b/testing/story/src/test/resources/ldap/polystring/resource-opendj.xml @@ -136,9 +136,16 @@ + cf. attribute 'cn' above. + This is EXPERIMENTAL functionality. It is not officialy supported. Use only at your own risk. --> ri:description + + + 1 + + + mr:polyStringStrict fullName diff --git a/testing/story/src/test/resources/logback-test.xml b/testing/story/src/test/resources/logback-test.xml index d0f9cecf278..d71b56096bf 100644 --- a/testing/story/src/test/resources/logback-test.xml +++ b/testing/story/src/test/resources/logback-test.xml @@ -46,10 +46,10 @@ if any of the following is set to "TRACE" then it was changed by mistake and should be changed back --> - + - + @@ -59,22 +59,25 @@ + + + - - - + + + - + - + - + @@ -83,7 +86,7 @@ - + @@ -91,9 +94,9 @@ - + - +