Merge branch 'feature/RM-7028_Add_Add_To_Hold_ToAudit' into 'master'

RM-7028 Audit add to hold

Closes RM-7028

See merge request records-management/records-management!1296
This commit is contained in:
Sara Aspery
2019-11-19 18:21:37 +00:00
11 changed files with 483 additions and 185 deletions

View File

@@ -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

View File

@@ -14,11 +14,13 @@
<property name="filePlanRoleService" ref="filePlanRoleService" />
</bean>
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNamePathDataExtractor">
<bean id="org_alfresco_module_rm_namePathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.NamePathDataExtractor">
<property name="registry" ref="auditModel.extractorRegistry" />
<property name="nodeService" ref="nodeService" />
<property name="filePlanService" ref="filePlanService" />
<property name="ruleService" ref="RuleService" />
<property name="permissionService" ref="PermissionService" />
<property name="dictionaryService" ref="DictionaryService" />
</bean>
<bean id="org_alfresco_module_rm_nodeRefPathExtractor" class="org.alfresco.module.org_alfresco_module_rm.audit.extractor.FilePlanNodeRefPathDataExtractor">
@@ -138,4 +140,11 @@
<property name="name" value="Delete Hold"/>
<property name="label" value="rm.audit.deleteHold"/>
</bean>
<bean id="audit-event.addToHold" parent="audit-event" class="org.alfresco.module.org_alfresco_module_rm.audit.event.AddToHoldAuditEvent">
<property name="nodeService" ref="nodeService" />
<property name="name" value="Add To Hold"/>
<property name="label" value="rm.audit.addToHold"/>
</bean>
</beans>

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<QName, Serializable> auditProperties = HoldUtils.makePropertiesMap(holdNodeRef, nodeService);
auditProperties.put(ContentModel.PROP_NAME, nodeService.getProperty(contentNodeRef, ContentModel.PROP_NAME));
recordsManagementAuditService.auditEvent(contentNodeRef, getName(), null, auditProperties, true, false);
}
}

View File

@@ -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 <b>cm:name</b> 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 <tt>true</tt> 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 <tt>true</tt> 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<NodeRef> 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);
}
}

View File

@@ -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))
{

View File

@@ -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<Void>()
{
@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<NodeRef> frozenNodes = holdService.getHeld(hold1);
assertNotNull(frozenNodes);
assertEquals(1, frozenNodes.size());
assertEquals(rmFolder, frozenNodes.get(0));
// check the contents of the hold
List<NodeRef> 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<Void>()
{
@Override
public Void run() throws Exception
{
NodeRef hold1 = holds.get(0);
NodeRef hold2 = holds.get(1);
// delete the hold
holdService.deleteHold(hold1);

View File

@@ -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<QName, Serializable> 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<QName, Serializable> 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<QName, Serializable> 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<QName, Serializable> 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<RecordsManagementAuditEntry> getAuditTrail(String asUser)

View File

@@ -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
*/

View File

@@ -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<QName, Serializable> dsProps = new HashMap<>(3);
dsProps.put(PROP_DISPOSITION_AUTHORITY, dispositionAuthority);
@@ -180,7 +186,7 @@ public class CommonRMTestUtils implements RecordsManagementModel
List<String> 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<QName, Serializable> 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<QName, Serializable> 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<Capability> 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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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));
}
}

View File

@@ -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)