You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/01/12 17:31:55 UTC

[16/52] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Unit tests all in

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/MembershipTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/MembershipTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/MembershipTest.java
new file mode 100644
index 0000000..7ae8fb5
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/MembershipTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.server.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class MembershipTest extends AbstractTest {
+
+    @Autowired
+    private MembershipDAO membershipDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Test
+    public void findAll() {
+        List<Membership> list = membershipDAO.findAll();
+        assertEquals(7, list.size());
+    }
+
+    @Test
+    public void find() {
+        Membership membership = membershipDAO.find(1L);
+        assertNotNull("did not find expected membership", membership);
+    }
+
+    @Test
+    public void save() {
+        User user = userDAO.find(4L);
+        Role role = roleDAO.find(1L);
+
+        Membership membership = entityFactory.newEntity(Membership.class);
+        membership.setUser(user);
+        membership.setRole(role);
+
+        membership = membershipDAO.save(membership);
+
+        Membership actual = membershipDAO.find(membership.getKey());
+        assertNotNull("expected save to work", actual);
+    }
+
+    @Test
+    public void delete() {
+        Membership membership = membershipDAO.find(4L);
+        membershipDAO.delete(membership.getKey());
+
+        Membership actual = membershipDAO.find(4L);
+        assertNull("delete did not work", actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
new file mode 100644
index 0000000..7cd9eae
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.server.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.server.persistence.api.entity.Notification;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class NotificationTest extends AbstractTest {
+
+    @Autowired
+    private NotificationDAO notificationDAO;
+
+    @Test
+    public void find() {
+        Notification notification = notificationDAO.find(10L);
+        assertNotNull(notification);
+        assertNotNull(notification.getEvents());
+        assertFalse(notification.getEvents().isEmpty());
+        assertNotNull(notification.getUserAbout());
+        assertNotNull(notification.getRecipients());
+
+    }
+
+    @Test
+    public void findAll() {
+        List<Notification> notifications = notificationDAO.findAll();
+        assertNotNull(notifications);
+        assertFalse(notifications.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.addEvent("save");
+
+        notification.setUserAbout("fake search condition");
+
+        notification.setRecipients("fake search condition");
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+    }
+
+    @Test
+    public void delete() {
+        notificationDAO.delete(10L);
+        assertNull(notificationDAO.find(10L));
+    }
+
+    @Test
+    public void issueSYNCOPE445() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.addEvent("save");
+
+        notification.setUserAbout("fake search condition");
+
+        notification.setRecipients("fake search condition");
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+        notification.addStaticRecipient("syncope445@syncope.apache.org");
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        assertNotNull(actual.getStaticRecipients());
+        assertFalse(actual.getStaticRecipients().isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE446() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.addEvent("[REST]:[RoleController]:[]:[create]:[SUCCESS]");
+
+        notification.setRoleAbout("fake search condition");
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserSchema);
+
+        notification.addStaticRecipient("syncope446@syncope.apache.org");
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        assertNotNull(actual.getStaticRecipients());
+        assertFalse(actual.getStaticRecipients().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PlainSchemaTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PlainSchemaTest.java
new file mode 100644
index 0000000..22e53dd
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PlainSchemaTest.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+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 static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PlainSchemaTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<UPlainSchema> userList = plainSchemaDAO.findAll(UPlainSchema.class);
+        assertEquals(15, userList.size());
+
+        List<RPlainSchema> roleList = plainSchemaDAO.findAll(RPlainSchema.class);
+        assertEquals(5, roleList.size());
+    }
+
+    @Test
+    public void findByName() {
+        UPlainSchema schema = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        assertNotNull("did not find expected attribute schema", schema);
+    }
+
+    @Test
+    public void findAttrs() {
+        List<RPlainSchema> schemas = plainSchemaDAO.findAll(RPlainSchema.class);
+        assertNotNull(schemas);
+        assertFalse(schemas.isEmpty());
+
+        for (RPlainSchema schema : schemas) {
+            List<RPlainAttr> attrs = plainSchemaDAO.findAttrs(schema, RPlainAttr.class);
+            assertNotNull(attrs);
+            assertFalse(attrs.isEmpty());
+        }
+    }
+
+    @Test
+    public void save() {
+        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        schema.setKey("secondaryEmail");
+        schema.setType(AttrSchemaType.String);
+        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
+        schema.setMandatoryCondition("false");
+        schema.setMultivalue(true);
+
+        plainSchemaDAO.save(schema);
+
+        UPlainSchema actual = plainSchemaDAO.find("secondaryEmail", UPlainSchema.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(schema, actual);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveNonValid() {
+        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        schema.setKey("secondaryEmail");
+        schema.setType(AttrSchemaType.String);
+        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
+        schema.setMandatoryCondition("false");
+        schema.setMultivalue(true);
+        schema.setUniqueConstraint(true);
+
+        plainSchemaDAO.save(schema);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        RPlainSchema schema = entityFactory.newEntity(RPlainSchema.class);
+        schema.setType(AttrSchemaType.Enum);
+        schema.setKey("color");
+
+        Exception ex = null;
+        try {
+            plainSchemaDAO.save(schema);
+        } catch (Exception e) {
+            ex = e;
+        }
+        assertNotNull(ex);
+
+        schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+        schema.setEnumerationKeys("1" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "2");
+
+        plainSchemaDAO.save(schema);
+
+        RPlainSchema actual = plainSchemaDAO.find(schema.getKey(), RPlainSchema.class);
+        assertNotNull(actual);
+        assertNotNull(actual.getEnumerationKeys());
+        assertFalse(actual.getEnumerationKeys().isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidSchema() {
+        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        schema.setKey("username");
+        plainSchemaDAO.save(schema);
+    }
+
+    @Test
+    public void delete() {
+        UPlainSchema fullnam = plainSchemaDAO.find("fullname", UPlainSchema.class);
+
+        plainSchemaDAO.delete(fullnam.getKey(), attrUtilFactory.getInstance(AttributableType.USER));
+
+        UPlainSchema actual = plainSchemaDAO.find("fullname", UPlainSchema.class);
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        UPlainSchema schema = entityFactory.newEntity(UPlainSchema.class);
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            plainSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PolicyTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PolicyTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PolicyTest.java
new file mode 100644
index 0000000..890aa96
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/PolicyTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+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 java.util.List;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.SyncPolicy;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PolicyTest extends AbstractTest {
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Test
+    public void findAll() {
+        List<Policy> policies = policyDAO.findAll();
+        assertNotNull(policies);
+        assertFalse(policies.isEmpty());
+    }
+
+    @Test
+    public void findById() {
+        Policy policy = policyDAO.find(1L);
+        assertNotNull("findById did not work", policy);
+    }
+
+    @Test
+    public void findByType() {
+        List<? extends Policy> policies = policyDAO.find(PolicyType.SYNC);
+        assertNotNull("findById did not work", policies);
+        assertFalse(policies.isEmpty());
+    }
+
+    @Test
+    public void findGlobalPasswordPolicy() {
+        PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy();
+        assertNotNull("findById did not work", policy);
+
+        assertEquals(PolicyType.GLOBAL_PASSWORD, policy.getType());
+
+        assertEquals("invalid policy values", 8, (policy.getSpecification(PasswordPolicySpec.class)).getMinLength());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidPolicy() {
+        PasswordPolicySpec passwordPolicy = new PasswordPolicySpec();
+        passwordPolicy.setMaxLength(8);
+        passwordPolicy.setMinLength(6);
+
+        SyncPolicy policy = entityFactory.newPolicy(SyncPolicy.class, false);
+        policy.setSpecification(passwordPolicy);
+        policy.setDescription("sync policy");
+
+        policyDAO.save(policy);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveSecondPasswordPolicy() {
+        PasswordPolicySpec passwordPolicy = new PasswordPolicySpec();
+        passwordPolicy.setMaxLength(8);
+        passwordPolicy.setMinLength(6);
+
+        PasswordPolicy policy = entityFactory.newPolicy(PasswordPolicy.class, true);
+        policy.setSpecification(passwordPolicy);
+        policy.setDescription("global password policy");
+
+        policyDAO.save(policy);
+    }
+
+    @Test
+    public void create() {
+        SyncPolicy policy = entityFactory.newPolicy(SyncPolicy.class, false);
+
+        final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
+        final String syncRRuleName = "net.tirasa.sync.correlation.TirasaRRule";
+
+        SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
+        syncPolicySpec.setUserJavaRule(syncURuleName);
+        syncPolicySpec.setRoleJavaRule(syncRRuleName);
+
+        policy.setSpecification(syncPolicySpec);
+        policy.setDescription("Sync policy");
+
+        policy = policyDAO.save(policy);
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.SYNC, policy.getType());
+        assertEquals(syncURuleName, (policy.getSpecification(SyncPolicySpec.class)).getUserJavaRule());
+        assertEquals(syncRRuleName, (policy.getSpecification(SyncPolicySpec.class)).getRoleJavaRule());
+    }
+
+    @Test
+    public void update() {
+        PasswordPolicySpec specification = new PasswordPolicySpec();
+        specification.setMaxLength(8);
+        specification.setMinLength(6);
+
+        Policy policy = policyDAO.getGlobalPasswordPolicy();
+        assertNotNull(policy);
+        policy.setSpecification(specification);
+
+        policy = policyDAO.save(policy);
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.GLOBAL_PASSWORD, policy.getType());
+        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMaxLength(), 8);
+        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMinLength(), 6);
+    }
+
+    @Test
+    public void delete() {
+        Policy policy = policyDAO.find(1L);
+        assertNotNull("find to delete did not work", policy);
+
+        policyDAO.delete(policy);
+
+        Policy actual = policyDAO.find(1L);
+        assertNull("delete did not work", actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ReportTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ReportTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ReportTest.java
new file mode 100644
index 0000000..7cc897f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ReportTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.report.UserReportletConf;
+import org.apache.syncope.server.persistence.api.dao.ReportDAO;
+import org.apache.syncope.server.persistence.api.entity.Report;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class ReportTest extends AbstractTest {
+
+    @Autowired
+    private ReportDAO reportDAO;
+
+    @Test
+    public void find() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        report = reportDAO.find(10L);
+        assertNull(report);
+    }
+
+    @Test
+    public void findAll() {
+        List<Report> reports = reportDAO.findAll();
+        assertNotNull(reports);
+        assertEquals(1, reports.size());
+    }
+
+    @Test
+    public void save() {
+        int beforeCount = reportDAO.count();
+
+        Report report = entityFactory.newEntity(Report.class);
+        report.setName("new report");
+        report.addReportletConf(new UserReportletConf("first"));
+        report.addReportletConf(new UserReportletConf("second"));
+
+        report = reportDAO.save(report);
+        assertNotNull(report);
+        assertNotNull(report.getKey());
+
+        int afterCount = reportDAO.count();
+        assertEquals(afterCount, beforeCount + 1);
+    }
+
+    @Test
+    public void delete() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        reportDAO.delete(1L);
+
+        report = reportDAO.find(1L);
+        assertNull(report);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
new file mode 100644
index 0000000..c1c2355
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+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 static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.server.persistence.api.entity.ConnInstance;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.user.UMapping;
+import org.apache.syncope.server.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class ResourceTest extends AbstractTest {
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Test
+    public void findById() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull("findById did not work", resource);
+
+        ConnInstance connector = resource.getConnector();
+        assertNotNull("connector not found", connector);
+        assertEquals("invalid connector name",
+                "net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
+        assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connector.getBundleName());
+
+        assertFalse("no mapping specified", resource.getUmapping().getItems().isEmpty());
+
+        List<Long> mappingIds = new ArrayList<>();
+        for (UMappingItem item : resource.getUmapping().getItems()) {
+            mappingIds.add(item.getKey());
+        }
+        assertTrue(mappingIds.contains(100L));
+    }
+
+    @Test
+    public void findAll() {
+        List<ExternalResource> resources = resourceDAO.findAll();
+        assertNotNull(resources);
+        assertEquals(18, resources.size());
+    }
+
+    @Test
+    public void findAllByPriority() {
+        List<ExternalResource> resources = resourceDAO.findAllByPriority();
+        assertNotNull(resources);
+        assertFalse(resources.isEmpty());
+    }
+
+    @Test
+    public void getAccountId() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
+        assertNotNull(resource);
+        assertEquals("fullname", resource.getUmapping().getAccountIdItem().getIntAttrName());
+    }
+
+    @Test
+    public void save() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save");
+        resource.setPropagationPriority(2);
+        resource.setPropagationPrimary(true);
+
+        UMapping mapping = entityFactory.newEntity(UMapping.class);
+        resource.setUmapping(mapping);
+
+        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
+        accountId.setExtAttrName("username");
+        accountId.setIntAttrName("fullname");
+        accountId.setIntMappingType(IntMappingType.UserId);
+        accountId.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(accountId);
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getConnector());
+        assertNotNull(actual.getUmapping());
+        assertFalse(actual.getUmapping().getItems().isEmpty());
+        assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
+        assertTrue(actual.isPropagationPrimary());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidMappingIntAttr() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save-invalid");
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        UMapping mapping = entityFactory.newEntity(UMapping.class);
+        resource.setUmapping(mapping);
+
+        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
+        accountId.setAccountid(true);
+        accountId.setIntMappingType(IntMappingType.UserSchema);
+        mapping.addItem(accountId);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void saveInvalidAccountIdMapping() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save-invalid");
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        UMapping mapping = entityFactory.newEntity(UMapping.class);
+        resource.setUmapping(mapping);
+
+        UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
+        accountId.setAccountid(true);
+        accountId.setIntMappingType(IntMappingType.UserVirtualSchema);
+        mapping.setAccountIdItem(accountId);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidMappingExtAttr() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save-invalid");
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        UMapping mapping = entityFactory.newEntity(UMapping.class);
+        resource.setUmapping(mapping);
+
+        UMappingItem item = entityFactory.newEntity(UMappingItem.class);
+        item.setAccountid(true);
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserSchema);
+        mapping.addItem(item);
+
+        item = entityFactory.newEntity(UMappingItem.class);
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserSchema);
+        mapping.addItem(item);
+
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void saveWithRoleMappingType() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save-invalid");
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        UMapping mapping = entityFactory.newEntity(UMapping.class);
+        resource.setUmapping(mapping);
+
+        UMappingItem item = entityFactory.newEntity(UMappingItem.class);
+        item.setIntAttrName("fullname");
+        item.setExtAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setAccountIdItem(item);
+
+        item = entityFactory.newEntity(UMappingItem.class);
+        item.setIntAttrName("icon");
+        item.setExtAttrName("icon");
+        item.setIntMappingType(IntMappingType.RoleSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        item = entityFactory.newEntity(UMappingItem.class);
+        item.setIntAttrName("mderiveddata");
+        item.setExtAttrName("mderiveddata");
+        item.setIntMappingType(IntMappingType.MembershipDerivedSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.addItem(item);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+
+        int items = 0;
+        for (UMappingItem mapItem : actual.getUmapping().getItems()) {
+            items++;
+
+            if ("icon".equals(mapItem.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(AttributableType.ROLE,
+                        mapItem.getIntMappingType().toString()));
+            }
+            if ("mderiveddata".equals(mapItem.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(AttributableType.MEMBERSHIP,
+                        mapItem.getIntMappingType().toString()));
+            }
+        }
+        assertEquals(3, items);
+    }
+
+    @Test
+    public void delete() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
+        assertNotNull(resource);
+
+        resourceDAO.delete(resource.getKey());
+
+        ExternalResource actual = resourceDAO.find("ws-target-resource-2");
+        assertNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            resourceDAO.save(resource);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/RoleTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/RoleTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/RoleTest.java
new file mode 100644
index 0000000..de2d498
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/RoleTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.server.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class RoleTest extends AbstractTest {
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Test
+    public void findAll() {
+        List<Role> list = roleDAO.findAll();
+        assertEquals("did not get expected number of roles ", 14, list.size());
+    }
+
+    @Test
+    public void findChildren() {
+        assertEquals(3, roleDAO.findChildren(roleDAO.find(4L)).size());
+    }
+
+    @Test
+    public void find() {
+        Role role = roleDAO.find("root", null);
+        assertNotNull("did not find expected role", role);
+        role = roleDAO.find(null, null);
+        assertNull("found role but did not expect it", role);
+    }
+
+    @Test
+    public void inheritedAttributes() {
+        Role director = roleDAO.find(7L);
+
+        assertEquals(1, director.findLastInheritedAncestorPlainAttrs().size());
+    }
+
+    @Test
+    public void inheritedDerivedAttributes() {
+        Role director = roleDAO.find(7L);
+
+        assertEquals(1, director.findLastInheritedAncestorDerAttrs().size());
+    }
+
+    @Test
+    public void inheritedVirtualAttributes() {
+        Role director = roleDAO.find(7L);
+
+        assertEquals(1, director.findLastInheritedAncestorVirAttrs().size());
+    }
+
+    @Test
+    public void inheritedPolicy() {
+        Role role = roleDAO.find(7L);
+
+        assertNotNull(role);
+
+        assertNotNull(role.getAccountPolicy());
+        assertNotNull(role.getPasswordPolicy());
+
+        assertEquals(4, role.getPasswordPolicy().getKey(), 0);
+
+        role = roleDAO.find(5L);
+
+        assertNotNull(role);
+
+        assertNull(role.getAccountPolicy());
+        assertNull(role.getPasswordPolicy());
+    }
+
+    @Test
+    public void save() {
+        Role role = entityFactory.newEntity(Role.class);
+        role.setName("secondChild");
+
+        // verify inheritance password and account policies
+        role.setInheritAccountPolicy(false);
+        // not inherited so setter execution shouldn't be ignored
+        role.setAccountPolicy((AccountPolicy) policyDAO.find(6L));
+
+        role.setInheritPasswordPolicy(true);
+        // inherited so setter execution should be ignored
+        role.setPasswordPolicy((PasswordPolicy) policyDAO.find(4L));
+
+        Role rootRole = roleDAO.find("root", null);
+        role.setParent(rootRole);
+
+        role = roleDAO.save(role);
+
+        Role actual = roleDAO.find(role.getKey());
+        assertNotNull("expected save to work", actual);
+
+        assertNull(role.getPasswordPolicy());
+        assertNotNull(role.getAccountPolicy());
+        assertEquals(Long.valueOf(6), role.getAccountPolicy().getKey());
+    }
+
+    @Test
+    public void delete() {
+        Role role = roleDAO.find(4L);
+        roleDAO.delete(role.getKey());
+
+        Role actual = roleDAO.find(4L);
+        assertNull("delete did not work", actual);
+
+        Role children = roleDAO.find(7L);
+        assertNull("delete of successors did not work", children);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/SecurityQuestionTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/SecurityQuestionTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/SecurityQuestionTest.java
new file mode 100644
index 0000000..b6ba5d6
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/SecurityQuestionTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.server.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.server.persistence.api.entity.user.SecurityQuestion;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class SecurityQuestionTest extends AbstractTest {
+
+    @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Test
+    public void find() {
+        SecurityQuestion securityQuestion = securityQuestionDAO.find(1L);
+        assertNotNull(securityQuestion);
+        assertNotNull(securityQuestion.getContent());
+    }
+
+    @Test
+    public void findAll() {
+        List<SecurityQuestion> securityQuestions = securityQuestionDAO.findAll();
+        assertNotNull(securityQuestions);
+        assertFalse(securityQuestions.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        SecurityQuestion securityQuestion = entityFactory.newEntity(SecurityQuestion.class);
+        securityQuestion.setContent("What is your favorite pet's name?");
+
+        SecurityQuestion actual = securityQuestionDAO.save(securityQuestion);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+    }
+
+    @Test
+    public void delete() {
+        securityQuestionDAO.delete(1L);
+        assertNull(securityQuestionDAO.find(1L));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskExecTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskExecTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskExecTest.java
new file mode 100644
index 0000000..02f43ea
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskExecTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.dao.TaskDAO;
+import org.apache.syncope.server.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskExecTest extends AbstractTest {
+
+    @Autowired
+    private TaskExecDAO taskExecDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Test
+    public void findAll() {
+        List<TaskExec> list = taskExecDAO.findAll(TaskType.PROPAGATION);
+        assertEquals(2, list.size());
+
+        list = taskExecDAO.findAll(TaskType.SCHEDULED);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.SYNCHRONIZATION);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.NOTIFICATION);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void findLatestStarted() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        TaskExec latestStarted = taskExecDAO.findLatestStarted(task);
+        assertNotNull(latestStarted);
+        assertEquals(Long.valueOf(1L), latestStarted.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE214() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        String faultyMessage = "A faulty message";
+        faultyMessage = faultyMessage.replace('a', '\0');
+
+        TaskExec exec = entityFactory.newEntity(TaskExec.class);
+        exec.setStartDate(new Date());
+        exec.setEndDate(new Date());
+        exec.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+        exec.setMessage(faultyMessage);
+
+        task.addExec(exec);
+        exec.setTask(task);
+
+        exec = taskExecDAO.save(exec);
+        assertNotNull(exec);
+
+        assertEquals(faultyMessage.replace('\0', '\n'), exec.getMessage());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskTest.java
new file mode 100644
index 0000000..cfae122
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/TaskTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+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 java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.server.persistence.api.dao.TaskDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskTest extends AbstractTest {
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void findWithoutExecs() {
+        List<PropagationTask> tasks = taskDAO.findToExec(TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertEquals(2, tasks.size());
+    }
+
+    @Test
+    public void findAll() {
+        assertEquals(4, taskDAO.findAll(TaskType.PROPAGATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
+        assertEquals(9, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
+    }
+
+    @Test
+    public void savePropagationTask() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+
+        User user = userDAO.find(2L);
+        assertNotNull(user);
+
+        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
+        task.setResource(resource);
+        task.setSubjectType(AttributableType.USER);
+        task.setPropagationMode(PropagationMode.TWO_PHASES);
+        task.setPropagationOperation(ResourceOperation.CREATE);
+        task.setAccountId("one@two.com");
+
+        Set<Attribute> attributes = new HashSet<Attribute>();
+        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
+        attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
+        task.setAttributes(attributes);
+
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        PropagationTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+    }
+
+    @Test
+    public void delete() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        ExternalResource resource = task.getResource();
+        assertNotNull(resource);
+
+        taskDAO.delete(task);
+        task = taskDAO.find(1L);
+        assertNull(task);
+
+        resource = resourceDAO.find(resource.getKey());
+        assertNotNull(resource);
+        assertFalse(taskDAO.findAll(resource, TaskType.PROPAGATION).contains(task));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/UserTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/UserTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/UserTest.java
new file mode 100644
index 0000000..ff2482f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/UserTest.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.apache.syncope.server.misc.policy.InvalidPasswordPolicySpecException;
+import org.apache.syncope.server.misc.security.PasswordGenerator;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class UserTest extends AbstractTest {
+
+    @Autowired
+    private PasswordGenerator passwordGenerator;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    @Test
+    public void findAll() {
+        List<User> list = userDAO.findAll(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()), 1, 100);
+        assertEquals("did not get expected number of users ", 5, list.size());
+    }
+
+    @Test
+    public void count() {
+        Integer count = userDAO.count(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()));
+        assertNotNull(count);
+        assertEquals(5, count.intValue());
+    }
+
+    @Test
+    public void findAllByPageAndSize() {
+        Set<Long> allRoleIds = RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll());
+
+        // get first page
+        List<User> list = userDAO.findAll(allRoleIds, 1, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page
+        list = userDAO.findAll(allRoleIds, 2, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page with uncomplete set
+        list = userDAO.findAll(allRoleIds, 2, 3);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get unexistent page
+        list = userDAO.findAll(allRoleIds, 3, 2);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByDerAttributeValue() {
+        final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio");
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrValue() {
+        userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrExpression() {
+        userDAO.findByDerAttrValue("noschema", "Antonio, Maria");
+    }
+
+    @Test
+    public void findByAttributeValue() {
+        final UPlainAttrValue fullnameValue = entityFactory.newEntity(UPlainAttrValue.class);
+        fullnameValue.setStringValue("Gioacchino Rossini");
+
+        final List<User> list = userDAO.findByAttrValue("fullname", fullnameValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByAttributeBooleanValue() {
+        final UPlainAttrValue coolValue = entityFactory.newEntity(UPlainAttrValue.class);
+        coolValue.setBooleanValue(true);
+
+        final List<User> list = userDAO.findByAttrValue("cool", coolValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findById() {
+        User user = userDAO.find(1L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(3L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(6L);
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void findByUsername() {
+        User user = userDAO.find("rossini");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("vivaldi");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("user6");
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void save() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setCreationDate(new Date());
+
+        user.setPassword("pass", CipherAlgorithm.SHA256);
+
+        Throwable t = null;
+        try {
+            userDAO.save(user);
+        } catch (InvalidEntityException e) {
+            t = e;
+        }
+        assertNotNull(t);
+
+        user.setPassword("password", CipherAlgorithm.SHA256);
+
+        user.setUsername("username!");
+
+        t = null;
+        try {
+            userDAO.save(user);
+        } catch (InvalidEntityException e) {
+            t = e;
+        }
+        assertNotNull(t);
+
+        user.setUsername("username");
+
+        User actual = userDAO.save(user);
+        assertNotNull("expected save to work", actual);
+        assertEquals(1, actual.getPasswordHistory().size());
+    }
+
+    @Test
+    public void delete() {
+        User user = userDAO.find(3L);
+
+        userDAO.delete(user.getKey());
+
+        User actual = userDAO.find(3L);
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issue237() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setCreationDate(new Date());
+
+        user.setPassword("password", CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE391() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setPassword(null, CipherAlgorithm.AES);
+
+        User actual = null;
+        Throwable t = null;
+        try {
+            actual = userDAO.save(user);
+        } catch (InvalidEntityException e) {
+            t = e;
+        }
+        assertNull(t);
+        assertNull(user.getPassword());
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE226() {
+        User user = userDAO.find(5L);
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+
+        user.setPassword(password, CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void testPasswordGenerator() {
+        User user = userDAO.find(5L);
+
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+        user.setPassword(password, CipherAlgorithm.SHA);
+        userDAO.save(user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirAttrTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirAttrTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirAttrTest.java
new file mode 100644
index 0000000..53ba160
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirAttrTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.server.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.dao.VirAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.UVirAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class VirAttrTest extends AbstractTest {
+
+    @Autowired
+    private VirAttrDAO virAttrDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private MembershipDAO membershipDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<UVirAttr> list = virAttrDAO.findAll(UVirAttr.class);
+        assertEquals("did not get expected number of derived attributes ", 1, list.size());
+    }
+
+    @Test
+    public void findById() {
+        UVirAttr attribute = virAttrDAO.find(1000L, UVirAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void saveUVirAttribute() {
+        UVirSchema virSchema = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        assertNotNull(virSchema);
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UVirAttr virAttr = entityFactory.newEntity(UVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setSchema(virSchema);
+
+        virAttr = virAttrDAO.save(virAttr);
+
+        UVirAttr actual = virAttrDAO.find(virAttr.getKey(), UVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void saveMVirAttribute() {
+        Membership owner = membershipDAO.find(3L);
+        assertNotNull("did not get expected membership", owner);
+
+        MVirAttr virAttr = entityFactory.newEntity(MVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setTemplate(owner.getRole().getAttrTemplate(MVirAttrTemplate.class, "mvirtualdata"));
+
+        virAttr = virAttrDAO.save(virAttr);
+        assertNotNull(virAttr.getTemplate());
+
+        MVirAttr actual = virAttrDAO.find(virAttr.getKey(), MVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void saveRVirAttribute() {
+        Role owner = roleDAO.find(3L);
+        assertNotNull("did not get expected membership", owner);
+
+        RVirAttr virAttr = entityFactory.newEntity(RVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setTemplate(owner.getAttrTemplate(RVirAttrTemplate.class, "rvirtualdata"));
+
+        virAttr = virAttrDAO.save(virAttr);
+        assertNotNull(virAttr.getTemplate());
+
+        RVirAttr actual = virAttrDAO.find(virAttr.getKey(), RVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void delete() {
+        UVirAttr attribute = virAttrDAO.find(1000L, UVirAttr.class);
+        String attributeSchemaName = attribute.getSchema().getKey();
+
+        virAttrDAO.delete(attribute.getKey(), UVirAttr.class);
+
+        UVirAttr actual = virAttrDAO.find(1000L, UVirAttr.class);
+        assertNull("delete did not work", actual);
+
+        UVirSchema attributeSchema = virSchemaDAO.find(attributeSchemaName, UVirSchema.class);
+
+        assertNotNull("user virtual attribute schema deleted " + "when deleting values", attributeSchema);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirSchemaTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirSchemaTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirSchemaTest.java
new file mode 100644
index 0000000..cd79937
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/VirSchemaTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.server.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.server.persistence.api.entity.VirSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RVirSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class VirSchemaTest extends AbstractTest {
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<UVirSchema> list = virSchemaDAO.findAll(UVirSchema.class);
+        assertEquals(2, list.size());
+    }
+
+    @Test
+    public void findByName() {
+        UVirSchema attributeSchema = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        assertNotNull("did not find expected virtual attribute schema", attributeSchema);
+    }
+
+    @Test
+    public void save() {
+        UVirSchema virtualAttributeSchema = entityFactory.newEntity(UVirSchema.class);
+        virtualAttributeSchema.setKey("virtual");
+        virtualAttributeSchema.setReadonly(true);
+
+        virSchemaDAO.save(virtualAttributeSchema);
+
+        UVirSchema actual = virSchemaDAO.find("virtual", UVirSchema.class);
+        assertNotNull("expected save to work", actual);
+        assertTrue(actual.isReadonly());
+    }
+
+    @Test
+    public void delete() {
+        UVirSchema virtualdata = virSchemaDAO.find("virtualdata", UVirSchema.class);
+
+        virSchemaDAO.delete(virtualdata.getKey(), attrUtilFactory.getInstance(AttributableType.USER));
+
+        VirSchema actual = virSchemaDAO.find("virtualdata", UVirSchema.class);
+        assertNull("delete did not work", actual);
+
+        // ------------- //
+        RVirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata", RVirSchema.class);
+        assertNotNull(rvirtualdata);
+
+        virSchemaDAO.delete(rvirtualdata.getKey(), attrUtilFactory.getInstance(AttributableType.ROLE));
+
+        actual = virSchemaDAO.find("rvirtualdata", RVirSchema.class);
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        UVirSchema schema = entityFactory.newEntity(UVirSchema.class);
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            virSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttrTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttrTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttrTest.java
new file mode 100644
index 0000000..1fb9a85
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttrTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.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 org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.server.persistence.api.dao.DerAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.server.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.server.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.server.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.server.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.UserDAO;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.UDerAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AttrTest extends AbstractTest {
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private MembershipDAO membershipDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void deleteAttribute() {
+        plainAttrDAO.delete(117L, UPlainAttr.class);
+
+        plainAttrDAO.flush();
+
+        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
+    }
+
+    @Test
+    public void deleteAttributeValue() {
+        UPlainAttrValue value = plainAttrValueDAO.find(14L, UPlainAttrValue.class);
+        int attributeValueNumber = value.getAttr().getValues().size();
+
+        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
+
+        plainAttrValueDAO.flush();
+
+        assertNull(plainAttrValueDAO.find(value.getKey(), UPlainAttrValue.class));
+
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        User user = userDAO.find(1L);
+        Membership membership = user.getMembership(1L);
+        assertNotNull(membership);
+
+        MPlainSchema schema = entityFactory.newEntity(MPlainSchema.class);
+        schema.setType(AttrSchemaType.Enum);
+        schema.setKey("color");
+        schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+
+        MPlainSchema actualSchema = plainSchemaDAO.save(schema);
+        assertNotNull(actualSchema);
+
+        MPlainAttrTemplate template = entityFactory.newEntity(MPlainAttrTemplate.class);
+        template.setSchema(actualSchema);
+        membership.getRole().getAttrTemplates(MPlainAttrTemplate.class).add(template);
+
+        MPlainAttr attr = entityFactory.newEntity(MPlainAttr.class);
+        attr.setTemplate(template);
+        attr.setOwner(membership);
+        attr.addValue("yellow", attrUtilFactory.getInstance(AttributableType.MEMBERSHIP));
+        membership.addPlainAttr(attr);
+
+        MPlainAttr actualAttribute = userDAO.save(user).getMembership(1L).getPlainAttr("color");
+        assertNotNull(actualAttribute);
+
+        membership = membershipDAO.find(1L);
+        assertNotNull(membership);
+        assertNotNull(membership.getPlainAttr(schema.getKey()));
+        assertNotNull(membership.getPlainAttr(schema.getKey()).getValues());
+
+        assertEquals(membership.getPlainAttr(schema.getKey()).getValues().size(), 1);
+    }
+
+    @Test
+    public void derAttrFromSpecialAttrs() {
+        UDerSchema sderived = entityFactory.newEntity(UDerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
+
+        sderived = derSchemaDAO.save(sderived);
+        derSchemaDAO.flush();
+
+        UDerSchema actual = derSchemaDAO.find("sderived", UDerSchema.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(sderived, actual);
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
+        assertTrue(value.endsWith("[0]"));
+    }
+
+    @Test
+    public void unmatchedRoleAttr() {
+        Role role = roleDAO.find(1L);
+        assertNotNull(role);
+
+        assertNotNull(role.getAttrTemplate(RPlainAttrTemplate.class, "icon"));
+        assertNotNull(role.getPlainAttr("icon"));
+
+        assertTrue(role.getAttrTemplates(RPlainAttrTemplate.class).
+                remove(role.getAttrTemplate(RPlainAttrTemplate.class, "icon")));
+
+        role = roleDAO.save(role);
+        roleDAO.flush();
+
+        assertNull(role.getAttrTemplate(RPlainAttrTemplate.class, "icon"));
+        assertNull(role.getPlainAttr("icon"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttributableSearchTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttributableSearchTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttributableSearchTest.java
new file mode 100644
index 0000000..ec52f92
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/AttributableSearchTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.server.persistence.jpa.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.server.persistence.api.RoleEntitlementUtil;
+import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.server.persistence.api.dao.RoleDAO;
+import org.apache.syncope.server.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.server.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.server.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AttributableSearchTest extends AbstractTest {
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private SubjectSearchDAO searchDAO;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    @Test
+    public void issueSYNCOPE95() {
+        Set<Role> roles = new HashSet<>(roleDAO.findAll());
+        for (Role role : roles) {
+            roleDAO.delete(role.getKey());
+        }
+        roleDAO.flush();
+
+        final AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        final SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        final List<User> users =
+                searchDAO.search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()), cond, SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(Long.valueOf(4L), users.get(0).getKey());
+    }
+}