diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/audit-service.properties b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/audit-service.properties index e2ce5dc332..da0adf2b30 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/audit-service.properties +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/messages/audit-service.properties @@ -15,6 +15,7 @@ rm.audit.copyTo=Copy to rm.audit.fileTo=File to rm.audit.createHold=Create Hold rm.audit.deleteHold=Delete Hold +rm.audit.addToHold=Add To Hold rm.audit.audit-start=Audit Start rm.audit.audit-stop=Audit Stop rm.audit.audit-clear=Audit Clear diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml index 364feeb76e..be43164702 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-audit-context.xml @@ -14,11 +14,13 @@ - + + + @@ -138,4 +140,11 @@ + + + + + + + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java new file mode 100644 index 0000000000..6cac5e2cf6 --- /dev/null +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEvent.java @@ -0,0 +1,85 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.EVERY_EVENT; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies; +import org.alfresco.repo.policy.annotation.Behaviour; +import org.alfresco.repo.policy.annotation.BehaviourBean; +import org.alfresco.repo.policy.annotation.BehaviourKind; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.namespace.QName; + +/** + * Add to hold audit event. + * + * @author Sara Aspery + * @since 3.3 + */ +@BehaviourBean +public class AddToHoldAuditEvent extends AuditEvent implements HoldServicePolicies.OnAddToHoldPolicy +{ + /** + * Node Service + */ + private NodeService nodeService; + + /** + * Sets the node service + * + * @param nodeService nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.hold.HoldServicePolicies.OnAddToHoldPolicy#onAddToHold(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:hold", + notificationFrequency = EVERY_EVENT + ) + public void onAddToHold(NodeRef holdNodeRef, NodeRef contentNodeRef) + { + Map auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService); + auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(contentNodeRef, ContentModel.PROP_NAME)); + + recordsManagementAuditService.auditEvent(contentNodeRef, getName(), null, auditProperties, true, false); + } +} diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/FilePlanNamePathDataExtractor.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/NamePathDataExtractor.java similarity index 67% rename from rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/FilePlanNamePathDataExtractor.java rename to rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/NamePathDataExtractor.java index 67e6bd68fc..2aba0a894f 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/FilePlanNamePathDataExtractor.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/audit/extractor/NamePathDataExtractor.java @@ -35,25 +35,33 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.audit.extractor.AbstractDataExtractor; +import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.security.PermissionService; /** * An extractor that extracts the cm:name path from the RM root down to * - and including - the node's own name. This will only extract data if the - * node is a {@link RecordsManagementModel#ASPECT_FILE_PLAN_COMPONENT fileplan component}. + * node is a {@link RecordsManagementModel#ASPECT_FILE_PLAN_COMPONENT fileplan component} + * or is a subtype of content. * * @see FilePlanService#getNodeRefPath(NodeRef) * * @author Derek Hulley * @since 3.2 + * @author Sara Aspery + * @since AGS 3.3 */ -public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor +public final class NamePathDataExtractor extends AbstractDataExtractor { private NodeService nodeService; private FilePlanService filePlanService; private RuleService ruleService; + private PermissionService permissionService; + private DictionaryService dictionaryService; /** * Used to check that the node in the context is a fileplan component @@ -68,8 +76,8 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor */ public void setFilePlanService(FilePlanService filePlanService) { - this.filePlanService = filePlanService; - } + this.filePlanService = filePlanService; + } /** * @param ruleService the ruleService to set @@ -80,8 +88,24 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor } /** - * @return Returns true if the data is a NodeRef and it represents - * a fileplan component + * @param permissionService permission service + */ + public void setPermissionService(PermissionService permissionService) + { + this.permissionService = permissionService; + } + + /** + * @param dictionaryService dictionary service + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @return Returns true if the data is a NodeRef and it either represents + * a fileplan component or is frozen */ public boolean isSupported(Serializable data) { @@ -89,7 +113,9 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor { return false; } - return nodeService.hasAspect((NodeRef)data, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT); + NodeRef nodeRef = (NodeRef) data; + return nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) || + dictionaryService.isSubClass(nodeService.getType(nodeRef), ContentModel.TYPE_CONTENT); } /** @@ -97,25 +123,34 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor */ public Serializable extractData(Serializable value) { - String extractedData = null; + String extractedData; ruleService.disableRules(); try { NodeRef nodeRef = (NodeRef) value; StringBuilder sb = new StringBuilder(128); - + if (nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT)) { // Get path from the RM root List nodeRefPath = filePlanService.getNodeRefPath(nodeRef); - + for (NodeRef pathNodeRef : nodeRefPath) { - String name = (String)nodeService.getProperty(pathNodeRef, ContentModel.PROP_NAME); + String name = (String) nodeService.getProperty(pathNodeRef, ContentModel.PROP_NAME); sb.append("/").append(name); } } + else if (dictionaryService.isSubClass(nodeService.getType(nodeRef), ContentModel.TYPE_CONTENT)) + { + // Get path from the DM root + Path nodeRefPath = nodeService.getPath(nodeRef); + sb.append(nodeRefPath.toDisplayPath(nodeService, permissionService)); + // Get node name + String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + sb.append("/").append(name); + } // Done extractedData = sb.toString(); @@ -143,9 +178,9 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor { return false; } - FilePlanNamePathDataExtractor that = (FilePlanNamePathDataExtractor) o; + NamePathDataExtractor that = (NamePathDataExtractor) o; return Objects.equals(nodeService, that.nodeService) && Objects.equals(filePlanService, that.filePlanService) - && Objects.equals(ruleService, that.ruleService); + && Objects.equals(ruleService, that.ruleService); } @Override @@ -154,3 +189,4 @@ public final class FilePlanNamePathDataExtractor extends AbstractDataExtractor return Objects.hash(nodeService, filePlanService, ruleService); } } + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java index d286a70d63..32400091e0 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImpl.java @@ -100,7 +100,6 @@ public class HoldServiceImpl extends ServiceBaseImpl private static Log logger = LogFactory.getLog(HoldServiceImpl.class); /** Audit event keys */ - private static final String AUDIT_ADD_TO_HOLD = "addToHold"; private static final String AUDIT_REMOVE_FROM_HOLD = "removeFromHold"; /** I18N */ @@ -225,7 +224,6 @@ public class HoldServiceImpl extends ServiceBaseImpl @Override public Void doWork() throws Exception { - recordsManagementAuditService.registerAuditEvent(new AuditEvent(AUDIT_ADD_TO_HOLD, "capability.AddToHold.title")); recordsManagementAuditService.registerAuditEvent(new AuditEvent(AUDIT_REMOVE_FROM_HOLD, "capability.RemoveFromHold.title")); return null; } @@ -667,9 +665,6 @@ public class HoldServiceImpl extends ServiceBaseImpl transactionalResourceHelper.getSet("frozen").add(nodeRef); nodeService.addChild(hold, nodeRef, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); - // audit item being added to the hold - recordsManagementAuditService.auditEvent(nodeRef, AUDIT_ADD_TO_HOLD); - // Mark all the folders contents as frozen if (isRecordFolder(nodeRef)) { diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java index fdf3c0367e..671aa3d239 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/DeleteHoldTest.java @@ -109,7 +109,11 @@ public class DeleteHoldTest extends BaseRMTestCase implements BeforeDeleteHoldPo public NodeRef run() throws Exception { // create test holds - return createAndCheckHold(); + NodeRef newHold = createAndCheckHold(); + // add the record folder to hold1 + holdService.addToHold(newHold, rmFolder); + + return newHold; } }); //Splitting transaction to fix onCreateNodePolicy issue where there was a node not found exception @@ -118,9 +122,6 @@ public class DeleteHoldTest extends BaseRMTestCase implements BeforeDeleteHoldPo @Override public Void run() throws Exception { - // add the record folder to hold1 - holdService.addToHold(hold1, rmFolder); - // assert that the folder and records are frozen assertTrue(freezeService.isFrozen(rmFolder)); assertTrue(freezeService.isFrozen(recordOne)); @@ -162,33 +163,44 @@ public class DeleteHoldTest extends BaseRMTestCase implements BeforeDeleteHoldPo //Splitting transaction to fix onCreateNodePolicy issue where there was a node not found exception doTestInTransaction(new Test() { - @Override - public Void run() throws Exception - { - NodeRef hold1 = holds.get(0); - NodeRef hold2 = holds.get(1); + @Override + public Void run() throws Exception + { + NodeRef hold1 = holds.get(0); + NodeRef hold2 = holds.get(1); - // add the record folder to hold1 - holdService.addToHold(hold1, rmFolder); + // add the record folder to hold1 + holdService.addToHold(hold1, rmFolder); - // assert that the folder and records are frozen - assertTrue(freezeService.isFrozen(rmFolder)); - assertTrue(freezeService.isFrozen(recordOne)); - assertTrue(freezeService.isFrozen(recordDeclaredOne)); + // assert that the folder and records are frozen + assertTrue(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertTrue(freezeService.isFrozen(recordDeclaredOne)); - // check the contents of the hold - List frozenNodes = holdService.getHeld(hold1); - assertNotNull(frozenNodes); - assertEquals(1, frozenNodes.size()); - assertEquals(rmFolder, frozenNodes.get(0)); + // check the contents of the hold + List frozenNodes = holdService.getHeld(hold1); + assertNotNull(frozenNodes); + assertEquals(1, frozenNodes.size()); + assertEquals(rmFolder, frozenNodes.get(0)); - holdService.addToHold(hold2, recordOne); + holdService.addToHold(hold2, recordOne); - // assert that the folder and records are frozen - assertTrue(freezeService.isFrozen(rmFolder)); - assertTrue(freezeService.isFrozen(recordOne)); - assertTrue(freezeService.isFrozen(recordDeclaredOne)); + // assert that the folder and records are frozen + assertTrue(freezeService.isFrozen(rmFolder)); + assertTrue(freezeService.isFrozen(recordOne)); + assertTrue(freezeService.isFrozen(recordDeclaredOne)); + return null; + } + }); + + doTestInTransaction(new Test() + { + @Override + public Void run() throws Exception + { + NodeRef hold1 = holds.get(0); + NodeRef hold2 = holds.get(1); // delete the hold holdService.deleteHold(hold1); diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java index 95e03ca779..532d3f6d98 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementAuditServiceImplTest.java @@ -62,7 +62,7 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase implements RMPermissionModel { /** A QName to display for the hold name. */ - public static final QName HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name"); + private static final QName HOLD_NAME = QName.createQName(RecordsManagementModel.RM_URI, "Hold Name"); /** Test record */ private NodeRef record; @@ -108,6 +108,15 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase return true; } + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#isCollaborationSiteTest() + */ + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase#setupTestDataImpl() */ @@ -574,61 +583,11 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase }); } - /** - * Given I have created a hold - * When I delete the hold and get the RM audit filter by delete hold event - * Then there will be an entry for the deleted hold, including the hold name - */ - @org.junit.Test - public void testAuditForDeleteHold() - { - doBehaviourDrivenTest(new BehaviourDrivenTest() - { - final static String DELETE_HOLD_AUDIT_EVENT = "Delete Hold"; - - String holdName = "Hold " + GUID.generate(); - - NodeRef hold; - Map auditEventProperties; - - @Override - public void given() - { - rmAuditService.clearAuditLog(filePlan); - hold = createHold(holdName, "Reason " + GUID.generate()); - } - - @Override - public void when() - { - deleteHold(hold); - auditEventProperties = getAuditEntry(DELETE_HOLD_AUDIT_EVENT).getBeforeProperties(); - } - - @Override - public void then() - { - // check delete hold audit event includes the hold name - assertEquals("Delete Hold event does not include hold name.", holdName, - auditEventProperties.get(HOLD_NAME)); - } - - @Override - public void after() - { - // Stop and delete all entries - rmAuditService.stopAuditLog(filePlan); - rmAuditService.clearAuditLog(filePlan); - } - }); - } - /** * Given I have created a hold * When I will get the RM audit filter by create hold event * Then there will be an entry for the created hold, including the hold name and reason */ - @org.junit.Test public void testAuditForCreateHold() { doBehaviourDrivenTest(new BehaviourDrivenTest() @@ -638,14 +597,13 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase String holdName = "Hold " + GUID.generate(); String holdReason = "Reason " + GUID.generate(); - NodeRef hold; Map auditEventProperties; @Override public void given() { rmAuditService.clearAuditLog(filePlan); - hold = createHold(holdName, holdReason); + utils.createHold(filePlan, holdName, holdReason); } @Override @@ -676,6 +634,107 @@ public class RecordsManagementAuditServiceImplTest extends BaseRMTestCase }); } + /** + * Given I have created a hold + * When I delete the hold and get the RM audit filter by delete hold event + * Then there will be an entry for the deleted hold, including the hold name + */ + public void testAuditForDeleteHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + final static String DELETE_HOLD_AUDIT_EVENT = "Delete Hold"; + + String holdName = "Hold " + GUID.generate(); + + NodeRef hold; + Map auditEventProperties; + + @Override + public void given() + { + rmAuditService.clearAuditLog(filePlan); + hold = utils.createHold(filePlan, holdName, "Reason " + GUID.generate()); + } + + @Override + public void when() + { + utils.deleteHold(hold); + auditEventProperties = getAuditEntry(DELETE_HOLD_AUDIT_EVENT).getBeforeProperties(); + } + + @Override + public void then() + { + // check delete hold audit event includes the hold name + assertEquals("Delete Hold event does not include hold name.", holdName, + auditEventProperties.get(HOLD_NAME)); + } + + @Override + public void after() + { + // Stop and delete all entries + rmAuditService.stopAuditLog(filePlan); + rmAuditService.clearAuditLog(filePlan); + } + }); + } + + /** + * Given I have added an item of content to a hold + * When I get the RM audit filter by add to hold event + * Then there will be an entry for the item added to the hold, including both the item name and hold name + */ + public void testAuditForAddContentToHold() + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + final static String ADD_TO_HOLD_AUDIT_EVENT = "Add To Hold"; + + String holdName = "Hold " + GUID.generate(); + NodeRef hold; + + Map auditEventProperties; + + @Override + public void given() + { + rmAuditService.clearAuditLog(filePlan); + hold = utils.createHold(filePlan, holdName, "Reason " + GUID.generate()); + utils.addItemToHold(hold, dmDocument); + } + + @Override + public void when() + { + auditEventProperties = getAuditEntry(ADD_TO_HOLD_AUDIT_EVENT).getAfterProperties(); + } + + @Override + public void then() + { + // check add to hold audit event includes the hold name + assertEquals("Add To Hold event does not include hold name.", holdName, + auditEventProperties.get(HOLD_NAME)); + + // check add to hold audit event includes the content name + String contentName = (String) nodeService.getProperty(dmDocument, PROP_NAME); + assertEquals("Add To Hold event does not include content name.", contentName, + auditEventProperties.get(PROP_NAME)); + } + + @Override + public void after() + { + // Stop and delete all entries + rmAuditService.stopAuditLog(filePlan); + rmAuditService.clearAuditLog(filePlan); + } + }); + } + /** === Helper methods === */ private List getAuditTrail(String asUser) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index b6a1eb03f3..21cb4ce5d8 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -92,8 +92,6 @@ import org.alfresco.util.GUID; import org.alfresco.util.RetryingTransactionHelperTestCase; import org.springframework.context.ApplicationContext; -import static org.alfresco.util.GUID.generate; - /** * Base test case class to use for RM unit tests. * @@ -709,26 +707,6 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase return createPerson(userName, true); } - /** - * Util method to create a hold. - * @param holdName hold name - * @param holdReason hold reason - * @return NodeRef hold node reference - */ - protected NodeRef createHold(String holdName, String holdReason) - { - return holdService.createHold(filePlan, holdName, holdReason, generate()); - } - - /** - * Util method to delete a hold. - * @param nodeRef hold node reference - */ - protected void deleteHold(NodeRef nodeRef) - { - holdService.deleteHold(nodeRef); - } - /** * Setup multi hierarchy test data */ diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java index 9991c9bafd..cf7e449f24 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/CommonRMTestUtils.java @@ -27,6 +27,8 @@ package org.alfresco.module.org_alfresco_module_rm.test.util; +import static org.alfresco.util.GUID.generate; + import java.io.InputStream; import java.io.Serializable; import java.util.ArrayList; @@ -48,6 +50,7 @@ import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.security.ModelSecurityService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; @@ -72,16 +75,9 @@ import org.springframework.context.ApplicationContext; */ public class CommonRMTestUtils implements RecordsManagementModel { - private DispositionService dispositionService; - private NodeService nodeService; - private ContentService contentService; - private RecordsManagementActionService actionService; - private ModelSecurityService modelSecurityService; - private FilePlanRoleService filePlanRoleService; - private CapabilityService capabilityService; - private RecordService recordService; - - /** test values */ + /** + * test values + */ public static final String DEFAULT_DISPOSITION_AUTHORITY = "disposition authority"; public static final String DEFAULT_DISPOSITION_INSTRUCTIONS = "disposition instructions"; public static final String DEFAULT_DISPOSITION_DESCRIPTION = "disposition action description"; @@ -91,22 +87,32 @@ public class CommonRMTestUtils implements RecordsManagementModel public static final String PERIOD_ONE_WEEK = "week|1"; public static final String PERIOD_ONE_YEAR = "year|1"; public static final String PERIOD_THREE_YEARS = "year|3"; + private DispositionService dispositionService; + private NodeService nodeService; + private ContentService contentService; + private RecordsManagementActionService actionService; + private ModelSecurityService modelSecurityService; + private FilePlanRoleService filePlanRoleService; + private CapabilityService capabilityService; + private RecordService recordService; + private HoldService holdService; /** * Constructor * - * @param applicationContext application context + * @param applicationContext application context */ public CommonRMTestUtils(ApplicationContext applicationContext) { - dispositionService = (DispositionService)applicationContext.getBean("DispositionService"); - nodeService = (NodeService)applicationContext.getBean("NodeService"); - contentService = (ContentService)applicationContext.getBean("ContentService"); - actionService = (RecordsManagementActionService)applicationContext.getBean("RecordsManagementActionService"); - modelSecurityService = (ModelSecurityService)applicationContext.getBean("ModelSecurityService"); - filePlanRoleService = (FilePlanRoleService)applicationContext.getBean("FilePlanRoleService"); - capabilityService = (CapabilityService)applicationContext.getBean("CapabilityService"); - recordService = (RecordService)applicationContext.getBean("RecordService"); + dispositionService = (DispositionService) applicationContext.getBean("DispositionService"); + nodeService = (NodeService) applicationContext.getBean("NodeService"); + contentService = (ContentService) applicationContext.getBean("ContentService"); + actionService = (RecordsManagementActionService) applicationContext.getBean("RecordsManagementActionService"); + modelSecurityService = (ModelSecurityService) applicationContext.getBean("ModelSecurityService"); + filePlanRoleService = (FilePlanRoleService) applicationContext.getBean("FilePlanRoleService"); + capabilityService = (CapabilityService) applicationContext.getBean("CapabilityService"); + recordService = (RecordService) applicationContext.getBean("RecordService"); + holdService = (HoldService) applicationContext.getBean("HoldService"); } /** @@ -123,26 +129,26 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Create test disposition schedule */ - public DispositionSchedule createBasicDispositionSchedule( - NodeRef container, - String dispositionInstructions, - String dispositionAuthority, - boolean isRecordLevel, - boolean defaultDispositionActions) - { - return createDispositionSchedule(container, dispositionInstructions, dispositionAuthority, isRecordLevel, defaultDispositionActions, false); - } + public DispositionSchedule createBasicDispositionSchedule( + NodeRef container, + String dispositionInstructions, + String dispositionAuthority, + boolean isRecordLevel, + boolean defaultDispositionActions) + { + return createDispositionSchedule(container, dispositionInstructions, dispositionAuthority, isRecordLevel, defaultDispositionActions, false); + } /** * Create test disposition schedule */ public DispositionSchedule createDispositionSchedule( - NodeRef container, - String dispositionInstructions, - String dispositionAuthority, - boolean isRecordLevel, - boolean defaultDispositionActions, - boolean extendedDispositionSchedule) + NodeRef container, + String dispositionInstructions, + String dispositionAuthority, + boolean isRecordLevel, + boolean defaultDispositionActions, + boolean extendedDispositionSchedule) { return createDispositionSchedule( container, @@ -158,13 +164,13 @@ public class CommonRMTestUtils implements RecordsManagementModel * Create test disposition schedule */ public DispositionSchedule createDispositionSchedule( - NodeRef container, - String dispositionInstructions, - String dispositionAuthority, - boolean isRecordLevel, - boolean defaultDispositionActions, - boolean extendedDispositionSchedule, - String defaultEvent) + NodeRef container, + String dispositionInstructions, + String dispositionAuthority, + boolean isRecordLevel, + boolean defaultDispositionActions, + boolean extendedDispositionSchedule, + String defaultEvent) { Map dsProps = new HashMap<>(3); dsProps.put(PROP_DISPOSITION_AUTHORITY, dispositionAuthority); @@ -180,7 +186,7 @@ public class CommonRMTestUtils implements RecordsManagementModel List events = new ArrayList<>(1); events.add(defaultEvent); - adParams.put(PROP_DISPOSITION_EVENT, (Serializable)events); + adParams.put(PROP_DISPOSITION_EVENT, (Serializable) events); dispositionService.addDispositionActionDefinition(dispositionSchedule, adParams); @@ -209,8 +215,8 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Helper method to create a record in a record folder. * - * @param recordFolder record folder - * @param name name of record + * @param recordFolder record folder + * @param name name of record * @return {@link NodeRef} record node reference */ public NodeRef createRecord(NodeRef recordFolder, String name) @@ -221,9 +227,9 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Helper method to create a record in a record folder. * - * @param recordFolder record folder - * @param name name of the record - * @param title title of the record + * @param recordFolder record folder + * @param name name of the record + * @param title title of the record * @return {@link NodeRef} record node reference */ public NodeRef createRecord(NodeRef recordFolder, String name, String title) @@ -236,10 +242,10 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Helper method to create a record in a record folder. * - * @param recordFolder record folder - * @param name name of record - * @param properties properties of the record - * @param content content of the record + * @param recordFolder record folder + * @param name name of record + * @param properties properties of the record + * @param content content of the record * @return {@link NodeRef} record node reference */ public NodeRef createRecord(NodeRef recordFolder, String name, Map properties, String content) @@ -259,10 +265,10 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Helper method to create a record in a record folder. * - * @param recordFolder record folder - * @param name name of record - * @param properties properties of the record - * @param content content of the record + * @param recordFolder record folder + * @param name name of record + * @param properties properties of the record + * @param content content of the record * @return {@link NodeRef} record node reference */ public NodeRef createRecord(NodeRef recordFolder, String name, Map properties, String mimetype, InputStream content) @@ -373,7 +379,7 @@ public class CommonRMTestUtils implements RecordsManagementModel }, AuthenticationUtil.getAdminUserName()); } - public Role createRole(NodeRef filePlan, String roleName, String ... capabilityNames) + public Role createRole(NodeRef filePlan, String roleName, String... capabilityNames) { Set capabilities = new HashSet<>(capabilityNames.length); for (String name : capabilityNames) @@ -392,8 +398,8 @@ public class CommonRMTestUtils implements RecordsManagementModel /** * Helper method to complete event on disposable item * - * @param disposableItem disposable item (record or record folder) - * @param eventName event name + * @param disposableItem disposable item (record or record folder) + * @param eventName event name */ public void completeEvent(NodeRef disposableItem, String eventName) { @@ -404,4 +410,37 @@ public class CommonRMTestUtils implements RecordsManagementModel // complete event actionService.executeRecordsManagementAction(disposableItem, CompleteEventAction.NAME, params); } + + /** + * Helper method to create a hold. + * + * @param holdName hold name + * @param holdReason hold reason + * @return NodeRef hold node reference + */ + public NodeRef createHold(NodeRef filePlan, String holdName, String holdReason) + { + return holdService.createHold(filePlan, holdName, holdReason, generate()); + } + + /** + * Helper method to delete a hold. + * + * @param nodeRef hold node reference + */ + public void deleteHold(NodeRef nodeRef) + { + holdService.deleteHold(nodeRef); + } + + /** + * Util method to add content to a hold. + * + * @param holdNodeRef hold node reference + * @param contentNodeRef content node reference + */ + public void addItemToHold(NodeRef holdNodeRef, NodeRef contentNodeRef) + { + holdService.addToHold(holdNodeRef, contentNodeRef); + } } diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java new file mode 100644 index 0000000000..334cf13fcd --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/audit/event/AddToHoldAuditEventUnitTest.java @@ -0,0 +1,92 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2019 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * 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 . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.audit.event; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.GUID; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.Map; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * Unit tests for {@link AddToHoldAuditEvent}. + * + * @author Sara Aspery + * @since 3.3 + */ +public class AddToHoldAuditEventUnitTest extends BaseUnitTest +{ + @InjectMocks + private AddToHoldAuditEvent addToHoldAuditEvent; + + @Mock + private NodeService mockedNodeService; + + private NodeRef holdNodeRef; + private NodeRef contentNodeRef; + + /** Set up the mocks. */ + @Before + public void setUp() + { + initMocks(this); + + holdNodeRef = generateNodeRef(); + String holdName = "Hold " + GUID.generate(); + + contentNodeRef = generateNodeRef(); + String contentName = "Content " + GUID.generate(); + + when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName); + when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName); + } + + /** + * Check that the add to hold event calls an audit event. + * + */ + @Test + public void testAddToHoldCausesAuditEvent() + { + addToHoldAuditEvent.onAddToHold(holdNodeRef, contentNodeRef); + verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), isNull(Map.class), any(Map.class), eq(true), eq(false)); + } +} diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java index 55de14c20d..fdcede7805 100644 --- a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/hold/HoldServiceImplUnitTest.java @@ -346,18 +346,15 @@ public class HoldServiceImplUnitTest extends BaseUnitTest verify(mockedNodeService).addChild(hold, recordFolder, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class)); verify(mockedNodeService).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService).auditEvent(eq(recordFolder), anyString()); holdService.addToHold(hold, record); verify(mockedNodeService).addChild(hold, record, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class)); verify(mockedNodeService, times(2)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService).auditEvent(eq(record), anyString()); holdService.addToHold(hold, activeContent); verify(mockedNodeService).addChild(hold, activeContent, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService).addAspect(eq(activeContent), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService).auditEvent(eq(activeContent), anyString()); } @SuppressWarnings("unchecked") @@ -371,13 +368,11 @@ public class HoldServiceImplUnitTest extends BaseUnitTest verify(mockedNodeService, never()).addChild(hold, recordFolder, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class)); verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService, never()).auditEvent(eq(recordFolder), anyString()); holdService.addToHold(hold, activeContent); verify(mockedNodeService, never()).addChild(hold, activeContent, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService, never()).addAspect(eq(activeContent), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService, never()).auditEvent(eq(activeContent), anyString()); } @SuppressWarnings("unchecked") @@ -395,12 +390,10 @@ public class HoldServiceImplUnitTest extends BaseUnitTest verify(mockedNodeService).addChild(hold, recordFolder, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService, never()).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class)); verify(mockedNodeService, never()).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService).auditEvent(eq(recordFolder), anyString()); holdService.addToHold(hold, activeContent); verify(mockedNodeService).addChild(hold, activeContent, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService, never()).addAspect(eq(activeContent), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService).auditEvent(eq(activeContent), anyString()); } @Test (expected = AccessDeniedException.class) @@ -466,7 +459,6 @@ public class HoldServiceImplUnitTest extends BaseUnitTest verify(mockedNodeService, times(1)).addChild(hold2, recordFolder, ASSOC_FROZEN_CONTENT, ASSOC_FROZEN_CONTENT); verify(mockedNodeService, times(1)).addAspect(eq(recordFolder), eq(ASPECT_FROZEN), any(Map.class)); verify(mockedNodeService, times(1)).addAspect(eq(record), eq(ASPECT_FROZEN), any(Map.class)); - verify(mockedRecordsManagementAuditService, times(2)).auditEvent(eq(recordFolder), anyString()); } @Test (expected = IntegrityException.class)