Repository: syncope Updated Branches: refs/heads/SYNCOPE-666 a78a6f1f7 -> 419fccfeb
http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java index 4767422..c9b551a 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java @@ -34,12 +34,17 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.Transformer; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership; +import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr; import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.group.Group; @@ -47,6 +52,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.AbstractTest; +import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership; import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -59,6 +65,12 @@ public class GroupTest extends AbstractTest { private EntityManager entityManager; @Autowired + private AnyTypeDAO anyTypeDAO; + + @Autowired + private AnyObjectDAO anyObjectDAO; + + @Autowired private UserDAO userDAO; @Autowired @@ -137,7 +149,7 @@ public class GroupTest extends AbstractTest { } @Test - public void dynMembership() { + public void udynMembership() { // 0. create user matching the condition below User user = entityFactory.newEntity(User.class); user.setUsername("username"); @@ -215,4 +227,97 @@ public class GroupTest extends AbstractTest { assertTrue(dynGroupMemberships.isEmpty()); } + /** + * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO} method with same signature: + * required for avoiding creating of a new transaction - good for general use case but bad for the way how + * this test class is architected. + */ + private List<Group> findDynGroupMemberships(final AnyObject anyObject) { + TypedQuery<Group> query = entityManager.createQuery( + "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName() + + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class); + query.setParameter("anyObject", anyObject); + + return query.getResultList(); + } + + @Test + public void adynMembership() { + // 0. create any object matching the condition below + AnyObject anyObject = entityFactory.newEntity(AnyObject.class); + anyObject.setType(anyTypeDAO.find("OTHER")); + anyObject.setRealm(realmDAO.find("/even/two")); + + APlainAttr attribute = entityFactory.newEntity(APlainAttr.class); + attribute.setSchema(plainSchemaDAO.find("cool")); + attribute.setOwner(anyObject); + attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT)); + anyObject.add(attribute); + + anyObject = anyObjectDAO.save(anyObject); + Long newAnyObjectKey = anyObject.getKey(); + assertNotNull(newAnyObjectKey); + + // 1. create group with dynamic membership + Group group = entityFactory.newEntity(Group.class); + group.setRealm(realmDAO.getRoot()); + group.setName("new"); + + ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class); + dynMembership.setFIQLCond("cool==true"); + dynMembership.setGroup(group); + + group.setADynMembership(dynMembership); + + Group actual = groupDAO.save(group); + assertNotNull(actual); + + groupDAO.flush(); + + // 2. verify that dynamic membership is there + actual = groupDAO.find(actual.getKey()); + assertNotNull(actual); + assertNotNull(actual.getADynMembership()); + assertNotNull(actual.getADynMembership().getKey()); + assertEquals(actual, actual.getADynMembership().getGroup()); + + // 3. verify that expected any objects have the created group dynamically assigned + assertEquals(2, actual.getADynMembership().getMembers().size()); + assertEquals(new HashSet<>(Arrays.asList(2L, newAnyObjectKey)), + CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() { + + @Override + public Long transform(final AnyObject input) { + return input.getKey(); + } + }, new HashSet<Long>())); + + anyObject = anyObjectDAO.find(2L); + assertNotNull(anyObject); + Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject); + assertEquals(1, dynGroupMemberships.size()); + assertTrue(dynGroupMemberships.contains(actual.getADynMembership().getGroup())); + + // 4. delete the new any object and verify that dynamic membership was updated + anyObjectDAO.delete(newAnyObjectKey); + + anyObjectDAO.flush(); + + actual = groupDAO.find(actual.getKey()); + assertEquals(1, actual.getADynMembership().getMembers().size()); + assertEquals(2L, actual.getADynMembership().getMembers().get(0).getKey(), 0); + + // 5. delete group and verify that dynamic membership was also removed + Long dynMembershipKey = actual.getADynMembership().getKey(); + + groupDAO.delete(actual); + + groupDAO.flush(); + + assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey)); + + dynGroupMemberships = findDynGroupMemberships(anyObject); + assertTrue(dynGroupMemberships.isEmpty()); + } + } http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java index f038917..5a12044 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java @@ -18,11 +18,14 @@ */ package org.apache.syncope.core.persistence.jpa.relationship; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.List; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO; import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; @@ -31,6 +34,8 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.user.URelationship; +import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.persistence.jpa.AbstractTest; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -40,6 +45,9 @@ import org.springframework.transaction.annotation.Transactional; public class UserTest extends AbstractTest { @Autowired + private AnyObjectDAO anyObjectDAO; + + @Autowired private UserDAO userDAO; @Autowired @@ -55,7 +63,12 @@ public class UserTest extends AbstractTest { private PlainAttrValueDAO plainAttrValueDAO; @Test - public void test() { + public void delete() { + List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L)); + assertFalse(memberships.isEmpty()); + List<URelationship> relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L)); + assertFalse(relationships.isEmpty()); + userDAO.delete(4L); userDAO.flush(); @@ -65,7 +78,49 @@ public class UserTest extends AbstractTest { assertNull(plainAttrValueDAO.find(22L, UPlainAttrValue.class)); assertNotNull(plainSchemaDAO.find("loginDate")); - List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L)); + memberships = groupDAO.findUMemberships(groupDAO.find(7L)); assertTrue(memberships.isEmpty()); + relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L)); + assertTrue(relationships.isEmpty()); + } + + @Test + public void ships() { + User user = userDAO.find(4L); + assertNotNull(user); + assertEquals(1, user.getMemberships().size()); + assertEquals(7L, user.getMemberships().get(0).getRightEnd().getKey(), 0); + + user.remove(user.getMemberships().get(0)); + + UMembership newM = entityFactory.newEntity(UMembership.class); + newM.setLeftEnd(user); + newM.setRightEnd(groupDAO.find(13L)); + user.add(newM); + + userDAO.save(user); + + userDAO.flush(); + + user = userDAO.find(4L); + assertEquals(1, user.getMemberships().size()); + assertEquals(13L, user.getMemberships().get(0).getRightEnd().getKey(), 0); + assertEquals(1, user.getRelationships().size()); + assertEquals(1L, user.getRelationships().get(0).getRightEnd().getKey(), 0); + + user.remove(user.getRelationships().get(0)); + + URelationship newR = entityFactory.newEntity(URelationship.class); + newR.setLeftEnd(user); + newR.setRightEnd(anyObjectDAO.find(2L)); + user.add(newR); + + userDAO.save(user); + + userDAO.flush(); + + user = userDAO.find(4L); + assertEquals(1, user.getRelationships().size()); + assertEquals(2L, user.getRelationships().get(0).getRightEnd().getKey(), 0); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/resources/content.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/resources/content.xml b/core/persistence-jpa/src/test/resources/content.xml index fa63e84..8d2ef54 100644 --- a/core/persistence-jpa/src/test/resources/content.xml +++ b/core/persistence-jpa/src/test/resources/content.xml @@ -112,10 +112,24 @@ under the License. <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"groupAltSearchSchemas":[]}'/> + <AnyTypeClass name="generic membership"/> + <AnyType name="USER" kind="USER"/> + <AnyTypeClass name="minimal user"/> + <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/> + <AnyTypeClass name="other"/> + <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/> + <AnyType name="GROUP" kind="GROUP"/> + <AnyTypeClass name="minimal group"/> + <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/> + <AnyType name="OTHER" kind="ANY_OBJECT"/> + <AnyTypeClass name="minimal other"/> + <AnyType_AnyTypeClass anyType_name="OTHER" anyTypeClass_name="minimal other"/> + <AnyTypeClass name="csv"/> + <Realm id="1" name="/" passwordPolicy_id="4"/> <Realm id="2" name="odd" parent_id="1" accountPolicy_id="6"/> <Realm id="3" name="even" parent_id="1"/> @@ -229,14 +243,18 @@ under the License. realm_id="1" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> + <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/> <SyncopeGroup id="13" name="bGroupForPropagation" realm_id="1" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> + <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/> <SyncopeGroup id="14" name="artDirector" realm_id="1" creator="admin" lastModifier="admin" creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/> + + <URelationship id="1" user_id="4" anyObject_id="1"/> <UMembership id="1" user_id="1" group_id="1"/> <UMembership id="2" user_id="2" group_id="1"/> @@ -246,84 +264,90 @@ under the License. <UMembership id="6" user_id="2" group_id="3"/> <UMembership id="7" user_id="5" group_id="14"/> - <PlainSchema name="fullname" type="String" + <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user" mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/> - <PlainSchema name="userId" type="String" + <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user" mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0" validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/> - <PlainSchema name="loginDate" type="Date" + <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other" mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0" conversionPattern="yyyy-MM-dd"/> - <PlainSchema name="firstname" type="String" + <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="surname" type="String" + <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user" mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="type" type="String" + <PlainSchema name="type" type="String" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="email" type="String" + <PlainSchema name="email" type="String" anyTypeClass_name="minimal user" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/> - <PlainSchema name="activationDate" type="Date" + <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/> - <PlainSchema name="uselessReadonly" type="String" + <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/> - <PlainSchema name="cool" type="Boolean" + <PlainSchema name="cool" type="Boolean" anyTypeClass_name="minimal other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="gender" type="Enum" + <PlainSchema name="gender" type="Enum" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" enumerationValues="M;F"/> - <PlainSchema name="aLong" type="Long" + <PlainSchema name="aLong" type="Long" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="makeItDouble" type="Long" + <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="obscure" type="Encrypted" + <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/> - <PlainSchema name="photo" type="Binary" + <PlainSchema name="photo" type="Binary" anyTypeClass_name="other" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" mimeType="image/jpeg"/> - <DerSchema name="csvuserid" expression="firstname + ',' + surname"/> - <DerSchema name="cn" expression="surname + ', ' + firstname"/> - <DerSchema name="noschema" expression="surname + ', ' + notfound"/> + <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/> + <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/> + <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/> - <VirSchema name="virtualdata"/> + <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/> - <PlainSchema name="icon" type="String" + <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="show" type="Boolean" + <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="rderived_sx" type="String" + <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="rderived_dx" type="String" + <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="title" type="String" + <PlainSchema name="title" type="String" anyTypeClass_name="minimal group" mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/> - <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"/> - <DerSchema name="displayProperty" expression="icon + ': ' + show"/> - <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"/> + <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx" + anyTypeClass_name="minimal group"/> + <DerSchema name="displayProperty" expression="icon + ': ' + show" + anyTypeClass_name="minimal group"/> + <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx" + anyTypeClass_name="minimal group"/> - <VirSchema name="rvirtualdata"/> + <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/> - <!-- rderiveddata is used to verify der schema deletion --> <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/> - <PlainSchema name="subscriptionDate" type="Date" + <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0" conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/> - <PlainSchema name="mderived_sx" type="String" + <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="mderived_dx" type="String" + <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> - <PlainSchema name="postalAddress" type="String" + <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership" mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/> <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/> - <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx"/> + <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" + anyTypeClass_name="generic membership"/> <VirSchema name="mvirtualdata"/> + + <APlainAttr id="1" owner_id="2" schema_name="cool"/> + <APlainAttrValue id="1" attribute_id="1" booleanValue="1"/> <UPlainAttr id="99" owner_id="1" schema_name="type"/> <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/> @@ -1035,13 +1059,13 @@ under the License. <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" sender="[email protected]" subject="Password Reset request" template="requestPasswordReset" - traceLevel="FAILURES" userAbout="token!=$null"/> + traceLevel="FAILURES"/> <AnyAbout id="1" anyType_name="USER" notification_id="1" about="token!=$null"/> <Notification_events Notification_id="1" event="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/> <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" sender="[email protected]" subject="Password Reset successful" template="confirmPasswordReset" - traceLevel="FAILURES" userAbout="token!=$null"/> + traceLevel="FAILURES"/> <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/> <Notification id="10" sender="[email protected]" subject="Test subject" template="test" selfAsRecipient="0"
