diff --git a/ccm-core/src/main/java/org/libreccm/core/Role.java b/ccm-core/src/main/java/org/libreccm/core/Role.java
index 15e16d167..776fead11 100644
--- a/ccm-core/src/main/java/org/libreccm/core/Role.java
+++ b/ccm-core/src/main/java/org/libreccm/core/Role.java
@@ -20,6 +20,7 @@ package org.libreccm.core;
import java.io.Serializable;
import java.util.Objects;
+
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -28,14 +29,33 @@ import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
+
import org.hibernate.validator.constraints.NotBlank;
+import javax.persistence.JoinColumn;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+
/**
*
* @author Jens Pelzetter
*/
@Entity
@Table(name = "ccm_roles")
+@NamedQueries({
+ @NamedQuery(name = "findRolesForName",
+ query = "SELECT r FROM Role r "
+ + "WHERE r.name = :roleName "
+ + "ORDER BY r.name"),
+ @NamedQuery(name = "findRolesForSourceGroup",
+ query = "SELECT r FROM Role r "
+ + "WHERE r.sourceGroup = :sourceGroup "
+ + "ORDER BY r.name"),
+ @NamedQuery(name = "findRolesForImplicitGroup",
+ query = "SELECT r FROM Role r "
+ + "WHERE r.implicitGroup = :implicitGroup "
+ + "ORDER BY r.name")
+})
@SuppressWarnings("PMD.ShortClassName") //Role is perfectly fine name.
public class Role implements Serializable {
@@ -51,9 +71,11 @@ public class Role implements Serializable {
private String name;
@ManyToOne
+ @JoinColumn(name = "source_group_id")
private Group sourceGroup;
@OneToOne
+ @JoinColumn(name = "implicit_group_id")
private Group implicitGroup;
@Column(name = "description")
diff --git a/ccm-core/src/main/java/org/libreccm/core/RoleRepository.java b/ccm-core/src/main/java/org/libreccm/core/RoleRepository.java
new file mode 100644
index 000000000..6b5cbd708
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/core/RoleRepository.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.core;
+
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class RoleRepository extends AbstractEntityRepository {
+
+ @Inject
+ private transient EntityManager entityManager;
+
+ @Override
+ public Class getEntityClass() {
+ return Role.class;
+ }
+
+ @Override
+ public boolean isNew(final Role entity) {
+ if (entity == null) {
+ throw new IllegalArgumentException("Role to save can't be null.");
+ }
+ return entity.getRoleId() == 0;
+ }
+
+ /**
+ * Find role(s) by name. There can be several roles with the same name.
+ *
+ * @param roleName
+ * @return A list of roles identified by name.
+ */
+ public List findRolesForName(final String roleName) {
+ final TypedQuery query = entityManager.createNamedQuery(
+ "findRolesForName", Role.class);
+ query.setParameter("roleName", roleName);
+
+ return query.getResultList();
+ }
+
+ public List findRolesForSourceGroup(final Group group) {
+ final TypedQuery query = entityManager.createNamedQuery(
+ "findRolesForSourceGroup", Role.class);
+ query.setParameter("sourceGroup", group);
+
+ return query.getResultList();
+ }
+
+ public List findRolesForImplicitGroup(final Group group) {
+ final TypedQuery query = entityManager.createNamedQuery(
+ "findRolesForImplicitGroup", Role.class);
+ query.setParameter("implicitGroup", group);
+
+ return query.getResultList();
+ }
+
+}
diff --git a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
index da67dc916..b990bc0d4 100644
--- a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
+++ b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
@@ -54,6 +54,10 @@ public class DatasetsTest extends DatasetsVerifier {
"/datasets/org/libreccm/core/GroupRepositoryTest/after-delete.json",
"/datasets/org/libreccm/core/GroupRepositoryTest/after-save-changed.json",
"/datasets/org/libreccm/core/GroupRepositoryTest/after-save-new.json",
+ "/datasets/org/libreccm/core/RoleRepositoryTest/data.json",
+ "/datasets/org/libreccm/core/RoleRepositoryTest/after-delete.json",
+ "/datasets/org/libreccm/core/RoleRepositoryTest/after-save-changed.json",
+ "/datasets/org/libreccm/core/RoleRepositoryTest/after-save-new.json",
"/datasets/org/libreccm/core/UserManagerTest/verify-password.json",
"/datasets/org/libreccm/core/UserRepositoryTest/data.json",
"/datasets/org/libreccm/core/UserRepositoryTest/after-delete.json",
diff --git a/ccm-core/src/test/java/org/libreccm/core/RoleRepositoryTest.java b/ccm-core/src/test/java/org/libreccm/core/RoleRepositoryTest.java
new file mode 100644
index 000000000..c8449d327
--- /dev/null
+++ b/ccm-core/src/test/java/org/libreccm/core/RoleRepositoryTest.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.core;
+
+import static org.hamcrest.Matchers.*;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.ShouldThrowException;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.junit.InSequence;
+import org.jboss.arquillian.persistence.PersistenceTest;
+import org.jboss.arquillian.persistence.ShouldMatchDataSet;
+import org.jboss.arquillian.persistence.UsingDataSet;
+import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
+import org.jboss.arquillian.transaction.api.annotation.Transactional;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
+import org.junit.After;
+import org.junit.AfterClass;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.libreccm.tests.categories.IntegrationTest;
+
+import java.io.File;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Category(IntegrationTest.class)
+@RunWith(Arquillian.class)
+@PersistenceTest
+@Transactional(TransactionMode.COMMIT)
+public class RoleRepositoryTest {
+
+ @Inject
+ private transient RoleRepository roleRepository;
+
+ @Inject
+ private transient GroupRepository groupRepository;
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ final PomEquippedResolveStage pom = Maven
+ .resolver()
+ .loadPomFromFile("pom.xml");
+ final PomEquippedResolveStage dependencies = pom.
+ importCompileAndRuntimeDependencies();
+ final File[] libs = dependencies.resolve().withTransitivity().asFile();
+
+ for (File lib : libs) {
+ System.err.printf("Adding file '%s' to test archive...%n",
+ lib.getName());
+ }
+
+ return ShrinkWrap
+ .create(WebArchive.class,
+ "LibreCCM-org.libreccm.core.RoleRepositoryTest.war")
+ .addPackage(User.class.getPackage())
+ .addPackage(org.libreccm.web.Application.class.getPackage())
+ .addPackage(org.libreccm.categorization.Category.class.
+ getPackage())
+ .addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
+ addPackage(org.libreccm.jpa.EntityManagerProducer.class
+ .getPackage())
+ .addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
+ .getPackage())
+ .addPackage(org.libreccm.testutils.EqualsVerifier.class.
+ getPackage())
+ .addPackage(org.libreccm.tests.categories.IntegrationTest.class
+ .getPackage())
+ .addAsLibraries(libs)
+ .addAsResource("test-persistence.xml",
+ "META-INF/persistence.xml")
+ .addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
+ }
+
+ private void verifyAuthor(final Role author) {
+ assertThat(author, is(not(nullValue())));
+ assertThat(author.getName(), is(equalTo("Author")));
+ assertThat(author.getDescription(),
+ is(equalTo("Creates new content")));
+ assertThat(author.getImplicitGroup().getName(),
+ is(equalTo("info Administration Author")));
+ assertThat(author.getSourceGroup().getName(),
+ is(equalTo("info Administration")));
+ }
+
+ private void verifyEditor(final Role editor) {
+ assertThat(editor, is(not(nullValue())));
+ assertThat(editor.getName(), is(equalTo("Editor")));
+ assertThat(editor.getDescription(),
+ is(equalTo("Reviews and approves the author's work")));
+ assertThat(editor.getImplicitGroup().getName(),
+ is(equalTo("info Administration Editor")));
+ assertThat(editor.getSourceGroup().getName(),
+ is(equalTo("info Administration")));
+ }
+
+ private void verifyPublisher(final Role publisher) {
+ assertThat(publisher, is(not(nullValue())));
+ assertThat(publisher.getName(), is(equalTo("Publisher")));
+ assertThat(publisher.getDescription(),
+ is(equalTo("Deploys the content to the web site")));
+ assertThat(publisher.getImplicitGroup().getName(),
+ is(equalTo("info Administration Publisher")));
+ assertThat(publisher.getSourceGroup().getName(),
+ is(equalTo("info Administration")));
+ }
+
+ private void verifyManager(final Role manager) {
+ assertThat(manager, is(not(nullValue())));
+ assertThat(manager.getName(), is(equalTo("Manager")));
+ assertThat(manager.getDescription(),
+ is(equalTo("Manages the overall content section")));
+ assertThat(manager.getImplicitGroup().getName(),
+ is(equalTo("info Administration Manager")));
+ assertThat(manager.getSourceGroup().getName(),
+ is(equalTo("info Administration")));
+ }
+
+ private void verifyTrustedUser(final Role trustedUser) {
+ assertThat(trustedUser, is(not(nullValue())));
+ assertThat(trustedUser.getName(), is(equalTo("Trusted User")));
+ assertThat(trustedUser.getDescription(),
+ is(equalTo("A trusted user is allowed to create and publish "
+ + "items without review")));
+ assertThat(trustedUser.getImplicitGroup().getName(),
+ is(equalTo("info Administration Trusted User")));
+ assertThat(trustedUser.getSourceGroup().getName(),
+ is(equalTo("info Administration")));
+ }
+
+ private void verifyContentReader(final Role contentReader) {
+ assertThat(contentReader, is(not(nullValue())));
+ assertThat(contentReader.getName(), is(equalTo("Content Reader")));
+ assertThat(contentReader.getDescription(),
+ is(equalTo("Can view published pages within this section")));
+ assertThat(contentReader.getImplicitGroup().getName(),
+ is(equalTo("info Viewers Content Reader")));
+ assertThat(contentReader.getSourceGroup().getName(),
+ is(equalTo("info Viewers")));
+ }
+
+ private void verifyAlertRecipient(final Role alertRecipient) {
+ assertThat(alertRecipient, is(not(nullValue())));
+ assertThat(alertRecipient.getName(), is(equalTo("Alert Recipient")));
+ assertThat(alertRecipient.getDescription(),
+ is(equalTo("Receive alerts regarding expiration of "
+ + "published content")));
+ assertThat(alertRecipient.getImplicitGroup().getName(),
+ is(equalTo("info Administration Alert Recipient")));
+ assertThat(alertRecipient.getSourceGroup().getName(),
+ is(equalTo("info Viewers")));
+ }
+
+ @Test
+ @InSequence(10)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ public void findRoleById() {
+ final Role author = roleRepository.findById(-10L);
+ final Role editor = roleRepository.findById(-20L);
+ final Role publisher = roleRepository.findById(-30L);
+ final Role manager = roleRepository.findById(-40L);
+ final Role trustedUser = roleRepository.findById(-50L);
+ final Role contentReader = roleRepository.findById(-60L);
+ final Role alertRecipient = roleRepository.findById(-70L);
+
+ verifyAuthor(author);
+ verifyEditor(editor);
+ verifyPublisher(publisher);
+ verifyManager(manager);
+ verifyTrustedUser(trustedUser);
+ verifyContentReader(contentReader);
+ verifyAlertRecipient(alertRecipient);
+ }
+
+ @Test
+ @InSequence(20)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ public void findRoleByName() {
+ final List authors = roleRepository.findRolesForName("Author");
+ final List editors = roleRepository.findRolesForName("Editor");
+ final List publishers = roleRepository.findRolesForName(
+ "Publisher");
+ final List managers = roleRepository.findRolesForName("Manager");
+ final List trustedUsers = roleRepository.findRolesForName(
+ "Trusted User");
+ final List contentReaders = roleRepository.findRolesForName(
+ "Content Reader");
+ final List alertRecipients = roleRepository.findRolesForName(
+ "Alert Recipient");
+
+ assertThat(authors.size(), is(1));
+ assertThat(editors.size(), is(1));
+ assertThat(publishers.size(), is(1));
+ assertThat(managers.size(), is(1));
+ assertThat(trustedUsers.size(), is(1));
+ assertThat(contentReaders.size(), is(1));
+ assertThat(alertRecipients.size(), is(1));
+
+ final Role author = authors.get(0);
+ final Role editor = editors.get(0);
+ final Role publisher = publishers.get(0);
+ final Role manager = managers.get(0);
+ final Role trustedUser = trustedUsers.get(0);
+ final Role contentReader = contentReaders.get(0);
+ final Role alertRecipient = alertRecipients.get(0);
+
+ verifyAuthor(author);
+ verifyEditor(editor);
+ verifyPublisher(publisher);
+ verifyManager(manager);
+ verifyTrustedUser(trustedUser);
+ verifyContentReader(contentReader);
+ verifyAlertRecipient(alertRecipient);
+ }
+
+ @Test
+ @InSequence(30)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ public void findRolesForSourceGroup() {
+ final Group group = groupRepository.findByGroupName(
+ "info Administration");
+
+ assertThat(group, is(not(nullValue())));
+
+ final List roles = roleRepository.findRolesForSourceGroup(group);
+
+ assertThat(roles.size(), is(5));
+
+ verifyAuthor(roles.get(0));
+ verifyEditor(roles.get(1));
+ verifyManager(roles.get(2));
+ verifyPublisher(roles.get(3));
+ verifyTrustedUser(roles.get(4));
+ }
+
+ @Test
+ @InSequence(40)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ public void findRolesForImplicitGroup() {
+ final Group authorsGroup = groupRepository.findByGroupName(
+ "info Administration Author");
+ assertThat(authorsGroup, is(not(nullValue())));
+ final List authors = roleRepository.findRolesForImplicitGroup(
+ authorsGroup);
+ assertThat(authors.size(), is(1));
+ verifyAuthor(authors.get(0));
+
+ final Group editorsGroup = groupRepository.findByGroupName(
+ "info Administration Editor");
+ assertThat(editorsGroup, is(not(nullValue())));
+ final List editors = roleRepository.findRolesForImplicitGroup(
+ editorsGroup);
+ assertThat(editors.size(), is(1));
+ verifyEditor(editors.get(0));
+
+ final Group publisherGroup = groupRepository.findByGroupName(
+ "info Administration Publisher");
+ assertThat(publisherGroup, is(not(nullValue())));
+ final List publishers = roleRepository.findRolesForImplicitGroup(
+ publisherGroup);
+ assertThat(publishers.size(), is(1));
+ verifyPublisher(publishers.get(0));
+ }
+
+ @Test
+ @InSequence(50)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ @ShouldMatchDataSet(value = "datasets/org/libreccm/core/RoleRepositoryTest/"
+ + "after-save-new.json",
+ excludeColumns = {"role_id"})
+ public void saveNewRole() {
+ final Group infoAdmin = groupRepository.findByGroupName(
+ "info Administration");
+ final Group readers = groupRepository.findByGroupName(
+ "info Viewers Content Reader");
+
+ final Role role = new Role();
+ role.setName("Test");
+ role.setDescription("New role for testing");
+ role.setImplicitGroup(infoAdmin);
+ role.setSourceGroup(readers);
+
+ roleRepository.save(role);
+ }
+
+ @Test
+ @InSequence(60)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ @ShouldMatchDataSet(value = "datasets/org/libreccm/core/RoleRepositoryTest/"
+ + "after-save-changed.json",
+ excludeColumns = {"role_id"})
+ public void saveChangedRole() {
+ final Role role = roleRepository.findById(-60L);
+ role.setName("Reader");
+
+ roleRepository.save(role);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ @ShouldThrowException(IllegalArgumentException.class)
+ @InSequence(70)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ public void saveNullValue() {
+ roleRepository.save(null);
+ }
+
+ @Test
+ @InSequence(80)
+ @UsingDataSet("datasets/org/libreccm/core/RoleRepositoryTest/data.json")
+ @ShouldMatchDataSet("datasets/org/libreccm/core/RoleRepositoryTest/"
+ + "after-delete.json")
+ public void deleteRole() {
+ final Role role = roleRepository.findById(-50L);
+
+ roleRepository.delete(role);
+ }
+
+}
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-delete.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-delete.json
new file mode 100644
index 000000000..4336a6afc
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-delete.json
@@ -0,0 +1,124 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ },
+ {
+ "subject_id": -60
+ },
+ {
+ "subject_id": -70
+ },
+ {
+ "subject_id": -80
+ },
+ {
+ "subject_id": -90
+ },
+ {
+ "subject_id": -100
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "Site-wide Administrators",
+ "subject_id": -10
+ },
+ {
+ "name": "info Administration",
+ "subject_id": -20
+ },
+ {
+ "name": "info Viewers",
+ "subject_id": -30
+ },
+ {
+ "name": "info Administration Author",
+ "subject_id": -40
+ },
+ {
+ "name": "info Administration Editor",
+ "subject_id": -50
+ },
+ {
+ "name": "info Administration Publisher",
+ "subject_id": -60
+ },
+ {
+ "name": "info Administration Manager",
+ "subject_id": -70
+ },
+ {
+ "name": "info Administration Trusted User",
+ "subject_id": -80
+ },
+ {
+ "name": "info Viewers Content Reader",
+ "subject_id": -90
+ },
+ {
+ "name": "info Administration Alert Recipient",
+ "subject_id": -100
+ }
+ ],
+ "ccm_roles":
+ [
+ {
+ "role_id": -10,
+ "description": "Creates new content",
+ "name": "Author",
+ "implicit_group_id": -40,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -20,
+ "description": "Reviews and approves the author's work",
+ "name": "Editor",
+ "implicit_group_id": -50,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -30,
+ "description": "Deploys the content to the web site",
+ "name": "Publisher",
+ "implicit_group_id": -60,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -40,
+ "description": "Manages the overall content section",
+ "name": "Manager",
+ "implicit_group_id": -70,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -60,
+ "description": "Can view published pages within this section",
+ "name": "Content Reader",
+ "implicit_group_id": -90,
+ "source_group_id": -30
+ },
+ {
+ "role_id": -70,
+ "description": "Receive alerts regarding expiration of published content",
+ "name": "Alert Recipient",
+ "implicit_group_id": -100,
+ "source_group_id": -30
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-changed.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-changed.json
new file mode 100644
index 000000000..63da8e88c
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-changed.json
@@ -0,0 +1,131 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ },
+ {
+ "subject_id": -60
+ },
+ {
+ "subject_id": -70
+ },
+ {
+ "subject_id": -80
+ },
+ {
+ "subject_id": -90
+ },
+ {
+ "subject_id": -100
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "Site-wide Administrators",
+ "subject_id": -10
+ },
+ {
+ "name": "info Administration",
+ "subject_id": -20
+ },
+ {
+ "name": "info Viewers",
+ "subject_id": -30
+ },
+ {
+ "name": "info Administration Author",
+ "subject_id": -40
+ },
+ {
+ "name": "info Administration Editor",
+ "subject_id": -50
+ },
+ {
+ "name": "info Administration Publisher",
+ "subject_id": -60
+ },
+ {
+ "name": "info Administration Manager",
+ "subject_id": -70
+ },
+ {
+ "name": "info Administration Trusted User",
+ "subject_id": -80
+ },
+ {
+ "name": "info Viewers Content Reader",
+ "subject_id": -90
+ },
+ {
+ "name": "info Administration Alert Recipient",
+ "subject_id": -100
+ }
+ ],
+ "ccm_roles":
+ [
+ {
+ "role_id": -10,
+ "description": "Creates new content",
+ "name": "Author",
+ "implicit_group_id": -40,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -20,
+ "description": "Reviews and approves the author's work",
+ "name": "Editor",
+ "implicit_group_id": -50,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -30,
+ "description": "Deploys the content to the web site",
+ "name": "Publisher",
+ "implicit_group_id": -60,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -40,
+ "description": "Manages the overall content section",
+ "name": "Manager",
+ "implicit_group_id": -70,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -50,
+ "description": "A trusted user is allowed to create and publish items without review",
+ "name": "Trusted User",
+ "implicit_group_id": -80,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -60,
+ "description": "Can view published pages within this section",
+ "name": "Reader",
+ "implicit_group_id": -90,
+ "source_group_id": -30
+ },
+ {
+ "role_id": -70,
+ "description": "Receive alerts regarding expiration of published content",
+ "name": "Alert Recipient",
+ "implicit_group_id": -100,
+ "source_group_id": -30
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-new.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-new.json
new file mode 100644
index 000000000..ea764e134
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/after-save-new.json
@@ -0,0 +1,137 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ },
+ {
+ "subject_id": -60
+ },
+ {
+ "subject_id": -70
+ },
+ {
+ "subject_id": -80
+ },
+ {
+ "subject_id": -90
+ },
+ {
+ "subject_id": -100
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "Site-wide Administrators",
+ "subject_id": -10
+ },
+ {
+ "name": "info Administration",
+ "subject_id": -20
+ },
+ {
+ "name": "info Viewers",
+ "subject_id": -30
+ },
+ {
+ "name": "info Administration Author",
+ "subject_id": -40
+ },
+ {
+ "name": "info Administration Editor",
+ "subject_id": -50
+ },
+ {
+ "name": "info Administration Publisher",
+ "subject_id": -60
+ },
+ {
+ "name": "info Administration Manager",
+ "subject_id": -70
+ },
+ {
+ "name": "info Administration Trusted User",
+ "subject_id": -80
+ },
+ {
+ "name": "info Viewers Content Reader",
+ "subject_id": -90
+ },
+ {
+ "name": "info Administration Alert Recipient",
+ "subject_id": -100
+ }
+ ],
+ "ccm_roles":
+ [
+ {
+ "role_id": -10,
+ "description": "Creates new content",
+ "name": "Author",
+ "implicit_group_id": -40,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -20,
+ "description": "Reviews and approves the author's work",
+ "name": "Editor",
+ "implicit_group_id": -50,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -30,
+ "description": "Deploys the content to the web site",
+ "name": "Publisher",
+ "implicit_group_id": -60,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -40,
+ "description": "Manages the overall content section",
+ "name": "Manager",
+ "implicit_group_id": -70,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -50,
+ "description": "A trusted user is allowed to create and publish items without review",
+ "name": "Trusted User",
+ "implicit_group_id": -80,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -60,
+ "description": "Can view published pages within this section",
+ "name": "Content Reader",
+ "implicit_group_id": -90,
+ "source_group_id": -30
+ },
+ {
+ "role_id": -70,
+ "description": "Receive alerts regarding expiration of published content",
+ "name": "Alert Recipient",
+ "implicit_group_id": -100,
+ "source_group_id": -30
+ },
+ {
+ "role_id": -80,
+ "description": "New role for testing",
+ "name": "Test",
+ "implicit_group_id": -20,
+ "source_group_id": -90
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/data.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/data.json
new file mode 100644
index 000000000..8c514f721
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/RoleRepositoryTest/data.json
@@ -0,0 +1,131 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ },
+ {
+ "subject_id": -60
+ },
+ {
+ "subject_id": -70
+ },
+ {
+ "subject_id": -80
+ },
+ {
+ "subject_id": -90
+ },
+ {
+ "subject_id": -100
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "Site-wide Administrators",
+ "subject_id": -10
+ },
+ {
+ "name": "info Administration",
+ "subject_id": -20
+ },
+ {
+ "name": "info Viewers",
+ "subject_id": -30
+ },
+ {
+ "name": "info Administration Author",
+ "subject_id": -40
+ },
+ {
+ "name": "info Administration Editor",
+ "subject_id": -50
+ },
+ {
+ "name": "info Administration Publisher",
+ "subject_id": -60
+ },
+ {
+ "name": "info Administration Manager",
+ "subject_id": -70
+ },
+ {
+ "name": "info Administration Trusted User",
+ "subject_id": -80
+ },
+ {
+ "name": "info Viewers Content Reader",
+ "subject_id": -90
+ },
+ {
+ "name": "info Administration Alert Recipient",
+ "subject_id": -100
+ }
+ ],
+ "ccm_roles":
+ [
+ {
+ "role_id": -10,
+ "description": "Creates new content",
+ "name": "Author",
+ "implicit_group_id": -40,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -20,
+ "description": "Reviews and approves the author's work",
+ "name": "Editor",
+ "implicit_group_id": -50,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -30,
+ "description": "Deploys the content to the web site",
+ "name": "Publisher",
+ "implicit_group_id": -60,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -40,
+ "description": "Manages the overall content section",
+ "name": "Manager",
+ "implicit_group_id": -70,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -50,
+ "description": "A trusted user is allowed to create and publish items without review",
+ "name": "Trusted User",
+ "implicit_group_id": -80,
+ "source_group_id": -20
+ },
+ {
+ "role_id": -60,
+ "description": "Can view published pages within this section",
+ "name": "Content Reader",
+ "implicit_group_id": -90,
+ "source_group_id": -30
+ },
+ {
+ "role_id": -70,
+ "description": "Receive alerts regarding expiration of published content",
+ "name": "Alert Recipient",
+ "implicit_group_id": -100,
+ "source_group_id": -30
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/scripts/h2-cleanup.sql b/ccm-core/src/test/resources/scripts/h2-cleanup.sql
index caea7c126..adbf243eb 100644
--- a/ccm-core/src/test/resources/scripts/h2-cleanup.sql
+++ b/ccm-core/src/test/resources/scripts/h2-cleanup.sql
@@ -1,5 +1,7 @@
DELETE FROM ccm_objects;
+DELETE FROM ccm_roles;
+
DELETE FROM group_memberships;
DELETE FROM ccm_groups;
diff --git a/ccm-core/src/test/resources/scripts/mysql-cleanup.sql b/ccm-core/src/test/resources/scripts/mysql-cleanup.sql
index 60316db64..adbf243eb 100644
--- a/ccm-core/src/test/resources/scripts/mysql-cleanup.sql
+++ b/ccm-core/src/test/resources/scripts/mysql-cleanup.sql
@@ -1,11 +1,13 @@
DELETE FROM ccm_objects;
-DELETE FROM subject_email_addresses;
+DELETE FROM ccm_roles;
DELETE FROM group_memberships;
DELETE FROM ccm_groups;
+DELETE FROM user_email_addresses;
+
DELETE FROM ccm_users;
DELETE FROM subjects;
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/scripts/pgsql-cleanup.sql b/ccm-core/src/test/resources/scripts/pgsql-cleanup.sql
index 60316db64..adbf243eb 100644
--- a/ccm-core/src/test/resources/scripts/pgsql-cleanup.sql
+++ b/ccm-core/src/test/resources/scripts/pgsql-cleanup.sql
@@ -1,11 +1,13 @@
DELETE FROM ccm_objects;
-DELETE FROM subject_email_addresses;
+DELETE FROM ccm_roles;
DELETE FROM group_memberships;
DELETE FROM ccm_groups;
+DELETE FROM user_email_addresses;
+
DELETE FROM ccm_users;
DELETE FROM subjects;
\ No newline at end of file