From 19596e348412cfeed2db55f25f8c2c21c60d83cb Mon Sep 17 00:00:00 2001 From: Tom Page Date: Thu, 16 Apr 2015 10:07:07 +0000 Subject: [PATCH] RM-2045 Create Java API to classify a document. Create dedicated objects to handle queries against the list of configured classification levels and reasons. +review RM-25 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@101986 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../ClassificationLevelManager.java | 76 +++++++++++++++++++ .../ClassificationReasonManager.java | 70 +++++++++++++++++ .../classification/ClassificationService.java | 12 ++- .../ClassificationServiceException.java | 26 ++++++- .../ClassificationServiceImpl.java | 56 ++++++++++---- .../ClassificationLevelManagerUnitTest.java | 65 ++++++++++++++++ .../ClassificationReasonManagerUnitTest.java | 59 ++++++++++++++ .../ClassificationServiceImplUnitTest.java | 61 +++++++++++++-- .../classification/ClassificationSuite.java | 2 + 9 files changed, 400 insertions(+), 27 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManager.java create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManager.java create mode 100644 rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManagerUnitTest.java create mode 100644 rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManagerUnitTest.java diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManager.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManager.java new file mode 100644 index 0000000000..cfef0dec6c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManager.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification; + +import java.util.List; + +import com.google.common.collect.ImmutableList; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.LevelIdNotFound; + +/** + * Container for the configured {@link ClassificationLevel} objects. + * + * @author tpage + */ +public class ClassificationLevelManager +{ + /** An immutable list of classification levels ordered from most to least secure. */ + private ImmutableList classificationLevels; + + /** + * Constructor that stores an immutable copy of the given levels. + * + * @param classificationLevels A list of classification levels ordered from most to least secure. + */ + public ClassificationLevelManager(List classificationLevels) + { + this.classificationLevels = ImmutableList.copyOf(classificationLevels); + } + + /** @return the highest security classification level. */ + public ClassificationLevel getMostSecureLevel() + { + return classificationLevels.get(0); + } + + /** @return An immutable list of classification levels ordered from most to least secure. */ + public ImmutableList getClassificationLevels() + { + return classificationLevels; + } + + /** + * Get a ClassificationLevel using its id. + * + * @param id The id of a classification level. + * @return The classification level. + * @throws LevelIdNotFound If the classification level cannot be found. + */ + public ClassificationLevel findLevelById(String id) throws LevelIdNotFound + { + for (ClassificationLevel classificationLevel : classificationLevels) + { + if (classificationLevel.getId().equals(id)) + { + return classificationLevel; + } + } + throw new LevelIdNotFound(id); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManager.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManager.java new file mode 100644 index 0000000000..76b19269e1 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManager.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification; + +import java.util.Collection; + +import com.google.common.collect.ImmutableList; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.ReasonIdNotFound; + +/** + * Container for the configured {@link ClassificationReason} objects. + * + * @author tpage + */ +public class ClassificationReasonManager +{ + /** An immutable list of classification reasons. */ + private ImmutableList classificationReasons; + + /** + * Constructor that stores an immutable copy of the given reasons. + * + * @param classificationReasons The classification reasons. + */ + public ClassificationReasonManager(Collection classificationReasons) + { + this.classificationReasons = ImmutableList.copyOf(classificationReasons); + } + + /** @return An immutable list of classification reasons. */ + public ImmutableList getClassificationReasons() + { + return classificationReasons; + } + + /** + * Get a ClassificationReason using its id. + * + * @param id The id of a classification reason. + * @return The classification reason. + * @throws ReasonIdNotFound If the classification reason cannot be found. + */ + public ClassificationReason findReasonById(String id) throws ReasonIdNotFound + { + for (ClassificationReason classificationReason : classificationReasons) + { + if (classificationReason.getId().equals(id)) + { + return classificationReason; + } + } + throw new ReasonIdNotFound(id); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationService.java index bf5988b802..743bb0d1d7 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationService.java @@ -21,6 +21,8 @@ package org.alfresco.module.org_alfresco_module_rm.classification; import java.util.List; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.LevelIdNotFound; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.ReasonIdNotFound; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -50,11 +52,13 @@ public interface ClassificationService /** * Classify a document. * - * @param classificationLevel The security clearance needed to access the document. + * @param classificationLevelId The security clearance needed to access the document. * @param classificationAuthority The name of the authority responsible for the classification of this document. - * @param classificationReasons A non-empty set of reasons for classifying the document in this way. + * @param classificationReasonIds A non-empty set of ids of reasons for classifying the document in this way. * @param document The node to classify. + * @throws LevelIdNotFound If the supplied level id is not found. + * @throws ReasonIdNotFound If any of the supplied reason ids are not found. */ - void addClassificationToDocument(ClassificationLevel classificationLevel, String classificationAuthority, - Set classificationReasons, NodeRef document); + void addClassificationToDocument(String classificationLevelId, String classificationAuthority, + Set classificationReasonIds, NodeRef document) throws LevelIdNotFound, ReasonIdNotFound; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceException.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceException.java index b849327e77..30f75f8981 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceException.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceException.java @@ -59,8 +59,32 @@ public class ClassificationServiceException extends AlfrescoRuntimeException { /** serial version uid */ private static final long serialVersionUID = 8191162359241035026L; - + public MalformedConfiguration(String msgId) { super(msgId); } public MalformedConfiguration(String msgId, Throwable cause) { super(msgId, cause); } } + + /** The supplied classification level id was not found in the configured list. */ + public static class LevelIdNotFound extends ClassificationServiceException + { + /** serial version uid */ + private static final long serialVersionUID = -8507186704795004383L; + + public LevelIdNotFound(String levelId) + { + super("Could not find classification level with id " + levelId); + } + } + + /** The supplied classification reason id was not found in the configured list. */ + public static class ReasonIdNotFound extends ClassificationServiceException + { + /** serial version uid */ + private static final long serialVersionUID = -643842413653375433L; + + public ReasonIdNotFound(String reasonId) + { + super("Could not find classification reason with id " + reasonId); + } + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImpl.java index 00d97a0ac2..7eaa75cce0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImpl.java @@ -20,14 +20,22 @@ package org.alfresco.module.org_alfresco_module_rm.classification; import java.io.Serializable; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.LevelIdNotFound; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MissingConfiguration; +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.ReasonIdNotFound; +import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +44,7 @@ import org.slf4j.LoggerFactory; * @since 3.0 */ public class ClassificationServiceImpl extends ServiceBaseImpl - implements ClassificationService + implements ClassificationService, ClassifiedContentModel { private static final Serializable[] LEVELS_KEY = new String[] { "org.alfresco", "module.org_alfresco_module_rm", @@ -47,14 +55,16 @@ public class ClassificationServiceImpl extends ServiceBaseImpl private static final Logger LOGGER = LoggerFactory.getLogger(ClassificationServiceImpl.class); private AttributeService attributeService; // TODO What about other code (e.g. REST API) accessing the AttrService? + private NodeService nodeService; private ClassificationServiceDAO classificationServiceDao; /** The classification levels currently configured in this server. */ - private List configuredLevels; + private ClassificationLevelManager levelManager; /** The classification reasons currently configured in this server. */ - private List configuredReasons; + private ClassificationReasonManager reasonManager; public void setAttributeService(AttributeService service) { this.attributeService = service; } + public void setNodeService(NodeService service) { this.nodeService = service; } /** Set the object from which configuration options will be read. */ public void setClassificationServiceDAO(ClassificationServiceDAO classificationServiceDao) { this.classificationServiceDao = classificationServiceDao; } @@ -75,11 +85,11 @@ public class ClassificationServiceImpl extends ServiceBaseImpl else if (!configurationLevels.equals(allPersistedLevels)) { attributeService.setAttribute((Serializable) configurationLevels, LEVELS_KEY); - this.configuredLevels = configurationLevels; + this.levelManager = new ClassificationLevelManager(configurationLevels); } else { - this.configuredLevels = allPersistedLevels; + this.levelManager = new ClassificationLevelManager(allPersistedLevels); } } @@ -99,7 +109,7 @@ public class ClassificationServiceImpl extends ServiceBaseImpl throw new MissingConfiguration("Classification reason configuration is missing."); } attributeService.setAttribute((Serializable) classpathReasons, REASONS_KEY); - this.configuredReasons = classpathReasons; + this.reasonManager = new ClassificationReasonManager(classpathReasons); } else { @@ -109,7 +119,7 @@ public class ClassificationServiceImpl extends ServiceBaseImpl + "Alfresco will use the unchanged values stored in the database."); // RM-2073 says that we should log a warning and proceed normally. } - this.configuredReasons = persistedReasons; + this.reasonManager = new ClassificationReasonManager(persistedReasons); } } @@ -188,25 +198,41 @@ public class ClassificationServiceImpl extends ServiceBaseImpl @Override public List getClassificationLevels() { - if (configuredLevels == null) + if (levelManager == null) { return Collections.emptyList(); } // FIXME Currently assume user has highest security clearance, this should be fixed as part of RM-2112. - ClassificationLevel usersLevel = configuredLevels.get(0); - return restrictList(configuredLevels, usersLevel); + ClassificationLevel usersLevel = levelManager.getMostSecureLevel(); + return restrictList(levelManager.getClassificationLevels(), usersLevel); } @Override public List getClassificationReasons() { - return configuredReasons == null ? Collections.emptyList() : - Collections.unmodifiableList(configuredReasons); + return reasonManager == null ? Collections.emptyList() : + Collections.unmodifiableList(reasonManager.getClassificationReasons()); } @Override - public void addClassificationToDocument(ClassificationLevel classificationLevel, String classificationAuthority, - Set classificationReasons, NodeRef document) + public void addClassificationToDocument(String classificationLevelId, String classificationAuthority, + Set classificationReasonIds, NodeRef document) throws LevelIdNotFound, ReasonIdNotFound { - // TODO + Map properties = new HashMap(); + + ClassificationLevel classificationLevel = levelManager.findLevelById(classificationLevelId); + properties.put(PROP_INITIAL_CLASSIFICATION, classificationLevel); + properties.put(PROP_CURRENT_CLASSIFICATION, classificationLevel); + + properties.put(PROP_CLASSIFICATION_AUTHORITY, classificationAuthority); + + HashSet classificationReasons = new HashSet<>(); + for (String classificationReasonId : classificationReasonIds) + { + ClassificationReason classificationReason = reasonManager.findReasonById(classificationReasonId); + classificationReasons.add(classificationReason); + } + properties.put(PROP_CLASSIFICATION_REASONS, classificationReasons); + + nodeService.addAspect(document, ASPECT_CLASSIFIED, properties); } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManagerUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManagerUnitTest.java new file mode 100644 index 0000000000..ed526f4ca6 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationLevelManagerUnitTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.LevelIdNotFound; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for the {@link ClassificationLevelManager}. + * + * @author tpage + */ +public class ClassificationLevelManagerUnitTest +{ + private static final ClassificationLevel LEVEL_1 = new ClassificationLevel("id1", "displayLabelKey1"); + private static final ClassificationLevel LEVEL_2 = new ClassificationLevel("id2", "displayLabelKey2"); + private static final ClassificationLevel LEVEL_3 = new ClassificationLevel("id3", "displayLabelKey3"); + private static final List LEVELS = Arrays.asList(LEVEL_1, LEVEL_2, LEVEL_3); + + private ClassificationLevelManager classificationLevelManager; + + @Before public void setup() + { + classificationLevelManager = new ClassificationLevelManager(LEVELS); + } + + @Test public void findClassificationById_found() + { + ClassificationLevel actual = classificationLevelManager.findLevelById("id2"); + assertEquals(LEVEL_2, actual); + } + + @Test(expected=LevelIdNotFound.class) public void findClassificationById_notFound() + { + classificationLevelManager.findLevelById("id_unknown"); + } + + @Test public void getMostSecureLevel() + { + ClassificationLevel actual = classificationLevelManager.getMostSecureLevel(); + assertEquals(LEVEL_1, actual); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManagerUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManagerUnitTest.java new file mode 100644 index 0000000000..682e4a8843 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationReasonManagerUnitTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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 Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.classification; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.ReasonIdNotFound; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for the {@link ClassificationReasonManager}. + * + * @author tpage + */ +public class ClassificationReasonManagerUnitTest +{ + private static final ClassificationReason REASON_1 = new ClassificationReason("id1", "displayLabelKey1"); + private static final ClassificationReason REASON_2 = new ClassificationReason("id2", "displayLabelKey2"); + private static final ClassificationReason REASON_3 = new ClassificationReason("id3", "displayLabelKey3"); + private static final List REASONS = Arrays.asList(REASON_1, REASON_2, REASON_3); + + private ClassificationReasonManager classificationReasonManager; + + @Before public void setup() + { + classificationReasonManager = new ClassificationReasonManager(REASONS); + } + + @Test public void findClassificationById_found() + { + ClassificationReason actual = classificationReasonManager.findReasonById("id2"); + assertEquals(REASON_2, actual); + } + + @Test(expected = ReasonIdNotFound.class) public void findClassificationById_notFound() + { + classificationReasonManager.findReasonById("id_unknown"); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImplUnitTest.java index bb4c09cbcb..82fd21a085 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationServiceImplUnitTest.java @@ -24,26 +24,36 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Stream; +import com.google.common.collect.Sets; import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationServiceException.MissingConfiguration; +import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel; import org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils; import org.alfresco.module.org_alfresco_module_rm.test.util.MockAuthenticationUtilHelper; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; import org.alfresco.service.cmr.attributes.AttributeService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; import org.apache.log4j.Appender; import org.apache.log4j.Level; import org.apache.log4j.spi.LoggingEvent; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -95,11 +105,16 @@ public class ClassificationServiceImplUnitTest @InjectMocks private ClassificationServiceImpl classificationServiceImpl; - @Mock private AttributeService mockedAttributeService; - @Mock private AuthenticationUtil mockedAuthenticationUtil; - @Mock private ClassificationServiceDAO mockClassificationServiceDAO; + @Mock private AttributeService mockedAttributeService; + @Mock private AuthenticationUtil mockedAuthenticationUtil; + @Mock private ClassificationServiceDAO mockClassificationServiceDAO; + @Mock private NodeService mockNodeService; /** Using a mock appender in the class logger so that we can verify some of the logging requirements. */ - @Mock private Appender mockAppender; + @Mock private Appender mockAppender; + @Mock private ClassificationLevelManager mockLevelManager; + @Mock private ClassificationReasonManager mockReasonManager; + @Captor private ArgumentCaptor loggingEventCaptor; + @Captor private ArgumentCaptor> propertiesCaptor; @Before public void setUp() { @@ -196,9 +211,8 @@ public class ClassificationServiceImplUnitTest anyString(), anyString(), anyString()); // Check that the warning message was logged. - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(LoggingEvent.class); - verify(mockAppender).doAppend(argumentCaptor.capture()); - List loggingEvents = argumentCaptor.getAllValues(); + verify(mockAppender).doAppend(loggingEventCaptor.capture()); + List loggingEvents = loggingEventCaptor.getAllValues(); Stream messages = loggingEvents.stream().map(event -> event.getRenderedMessage()); String expectedMessage = "Classification reasons configured in classpath do not match those stored in Alfresco. Alfresco will use the unchanged values stored in the database."; assertTrue("Warning message not found in log.", messages.anyMatch(message -> message == expectedMessage)); @@ -243,4 +257,37 @@ public class ClassificationServiceImplUnitTest assertEquals("Expected an empty list when the target level is not found.", 0, actual.size()); } + + /** Classify a document with a couple of reasons and check the NodeService is called correctly. */ + @Test public void addClassificationToDocument() + { + // Create a level and two reasons. + ClassificationLevel level = new ClassificationLevel("levelId1", "displayLabelKey"); + ClassificationReason reason1 = new ClassificationReason("reasonId1", "displayLabelKey1"); + ClassificationReason reason2 = new ClassificationReason("reasonId2", "displayLabelKey2"); + Set reasons = Sets.newHashSet(reason1, reason2); + NodeRef document = new NodeRef("fake://document/"); + // Set up the managers to return these objects when the ids are provided. + doReturn(level).when(mockLevelManager).findLevelById("levelId1"); + doReturn(reason1).when(mockReasonManager).findReasonById("reasonId1"); + doReturn(reason2).when(mockReasonManager).findReasonById("reasonId2"); + + // Call the method under test. + classificationServiceImpl.addClassificationToDocument("levelId1", "classificationAuthority", + Sets.newHashSet("reasonId1", "reasonId2"), document); + + verify(mockNodeService).addAspect(eq(document), eq(ClassifiedContentModel.ASPECT_CLASSIFIED), + propertiesCaptor.capture()); + // Check the properties that were received. + Map properties = propertiesCaptor.getValue(); + HashSet expectedPropertyKeys = Sets.newHashSet(ClassifiedContentModel.PROP_INITIAL_CLASSIFICATION, + ClassifiedContentModel.PROP_CURRENT_CLASSIFICATION, + ClassifiedContentModel.PROP_CLASSIFICATION_AUTHORITY, + ClassifiedContentModel.PROP_CLASSIFICATION_REASONS); + assertEquals("Aspect created with unexpected set of keys.", expectedPropertyKeys, properties.keySet()); + assertEquals("Unexpected initial classification.", level, properties.get(ClassifiedContentModel.PROP_INITIAL_CLASSIFICATION)); + assertEquals("Unexpected current classification.", level, properties.get(ClassifiedContentModel.PROP_CURRENT_CLASSIFICATION)); + assertEquals("Unexpected authority.", "classificationAuthority", properties.get(ClassifiedContentModel.PROP_CLASSIFICATION_AUTHORITY)); + assertEquals("Unexpected set of reasons.", reasons, properties.get(ClassifiedContentModel.PROP_CLASSIFICATION_REASONS)); + } } diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationSuite.java index 6275c0c220..12ff51e206 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationSuite.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/classification/ClassificationSuite.java @@ -29,6 +29,8 @@ import org.junit.runners.Suite; @Suite.SuiteClasses( { ClassificationLevelConstraintUnitTest.class, + ClassificationLevelManagerUnitTest.class, + ClassificationReasonManagerUnitTest.class, ClassificationServiceDAOUnitTest.class, ClassificationServiceImplUnitTest.class })