From af6f894ed067ed3fa4176bdda409d066ddb03610 Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Wed, 25 Feb 2015 00:25:33 +0000 Subject: [PATCH] Prevent incompatiable disposition schedules from being linked together * the unpredicatable behaviour was caused by this incompatibility and the resulting uncertaintity over which level of dispostion would 'win' * RM-1963: It is not possible to cut off record scheduled for cut off if it's linked to a folder with disposition schedule with cut off step set on folder. * RM-1962: The disposition schedule steps are not working as expected on a record linked to a folder with disposition schedule on it's own. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.3@97948 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../rm-service-context.xml | 1 + .../record/RecordLinkRuntimeException.java | 53 ++++++ .../record/RecordServiceImpl.java | 86 ++++++++-- .../integration/record/LinkRecordTest.java | 156 +++++++++++++++++ .../integration/record/RecordTestSuite.java | 3 +- .../record/RecordServiceImplUnitTest.java | 160 +++++++++++++++++- .../test/util/BaseUnitTest.java | 2 + 7 files changed, 439 insertions(+), 22 deletions(-) create mode 100644 rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordLinkRuntimeException.java create mode 100644 rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/LinkRecordTest.java diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index daf9aea80d..ce80a91dfb 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -1054,6 +1054,7 @@ + diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordLinkRuntimeException.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordLinkRuntimeException.java new file mode 100644 index 0000000000..b114543715 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordLinkRuntimeException.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2014 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.record; + +import org.alfresco.error.AlfrescoRuntimeException; + + +/** + * Record link exception class + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RecordLinkRuntimeException extends AlfrescoRuntimeException +{ + private static final long serialVersionUID = 5202539484220535897L; + + public RecordLinkRuntimeException(String msgId, Throwable cause) + { + super(msgId, cause); + } + + public RecordLinkRuntimeException(String msgId, Object[] msgParams, Throwable cause) + { + super(msgId, msgParams, cause); + } + + public RecordLinkRuntimeException(String msgId, Object[] msgParams) + { + super(msgId, msgParams); + } + + public RecordLinkRuntimeException(String msgId) + { + super(msgId); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index a6e54acba8..536403da9b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -43,6 +43,8 @@ import org.alfresco.module.org_alfresco_module_rm.RecordsManagementPolicies.OnFi 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.capability.RMPermissionModel; +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.dod5015.DOD5015Model; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; @@ -221,6 +223,9 @@ public class RecordServiceImpl extends BaseBehaviourBean /** Relationship service */ private RelationshipService relationshipService; + + /** Disposition service */ + private DispositionService dispositionService; /** records management container type */ private RecordsManagementContainerType recordsManagementContainerType; @@ -362,6 +367,17 @@ public class RecordServiceImpl extends BaseBehaviourBean this.relationshipService = relationshipService; } + /** + * @param dispositionService disposition service + */ + public void setDispositionService(DispositionService dispositionService) + { + this.dispositionService = dispositionService; + } + + /** + * @param recordsManagementContainerType records management container type + */ public void setRecordsManagementContainerType(RecordsManagementContainerType recordsManagementContainerType) { this.recordsManagementContainerType = recordsManagementContainerType; @@ -518,18 +534,33 @@ public class RecordServiceImpl extends BaseBehaviourBean Set newRecords = transactionalResourceHelper.getSet(KEY_NEW_RECORDS); newRecords.add(nodeRef); } + else + { + // if we are linking a record + NodeRef parentNodeRef = childAssocRef.getParentRef(); + if (isRecord(nodeRef) && isRecordFolder(parentNodeRef)) + { + // validate the link conditions + validateLinkConditions(nodeRef, parentNodeRef); + } + } // create and file the content as a record file(nodeRef); } } } + catch (RecordLinkRuntimeException e) + { + // rethrow exception + throw e; + } catch (AlfrescoRuntimeException e) { // do nothing but log error - if (logger.isDebugEnabled()) + if (logger.isWarnEnabled()) { - logger.debug("Unable to file pending record.", e); + logger.warn("Unable to file pending record.", e); } } finally @@ -1685,7 +1716,7 @@ public class RecordServiceImpl extends BaseBehaviourBean { ParameterCheck.mandatory("record", record); ParameterCheck.mandatory("recordFolder", recordFolder); - + // ensure we are linking a record to a record folder if(isRecord(record) && isRecordFolder(recordFolder)) { @@ -1696,24 +1727,51 @@ public class RecordServiceImpl extends BaseBehaviourBean if (parent.getParentRef().equals(recordFolder)) { // we can not link a record to the same location more than once - throw new AlfrescoRuntimeException("Can not link a record to the same record folder more than once"); + throw new RecordLinkRuntimeException("Can not link a record to the same record folder more than once"); } - } - + } + + // validate link conditions + validateLinkConditions(record, recordFolder); + // get the current name of the record String name = nodeService.getProperty(record, ContentModel.PROP_NAME).toString(); - + // create a secondary link to the record folder nodeService.addChild( - recordFolder, - record, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); } else { // can only link a record to a record folder - throw new AlfrescoRuntimeException("Can only link a record to a record folder."); + throw new RecordLinkRuntimeException("Can only link a record to a record folder."); + } + } + + /** + * + * @param record + * @param recordFolder + */ + private void validateLinkConditions(NodeRef record, NodeRef recordFolder) + { + // ensure that the linking record folders have compatible disposition schedules + DispositionSchedule recordDispositionSchedule = dispositionService.getDispositionSchedule(record); + if (recordDispositionSchedule != null) + { + DispositionSchedule recordFolderDispositionSchedule = dispositionService.getDispositionSchedule(recordFolder); + if (recordFolderDispositionSchedule != null) + { + if (recordDispositionSchedule.isRecordLevelDisposition() != recordFolderDispositionSchedule.isRecordLevelDisposition()) + { + // we can't link a record to an incompatible disposition schedule + throw new RecordLinkRuntimeException("Can not link a record to a record folder with an incompatible disposition schedule. " + + "They must either both be record level or record folder level dispositions."); + } + } } } @@ -1733,7 +1791,7 @@ public class RecordServiceImpl extends BaseBehaviourBean NodeRef primaryParent = nodeService.getPrimaryParent(record).getParentRef(); if (primaryParent.equals(recordFolder)) { - throw new AlfrescoRuntimeException("Can't unlink a record from it's owning record folder."); + throw new RecordLinkRuntimeException("Can't unlink a record from it's owning record folder."); } // remove the link @@ -1742,7 +1800,7 @@ public class RecordServiceImpl extends BaseBehaviourBean else { // can only unlink a record from a record folder - throw new AlfrescoRuntimeException("Can only unlink a record from a record folder."); + throw new RecordLinkRuntimeException("Can only unlink a record from a record folder."); } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/LinkRecordTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/LinkRecordTest.java new file mode 100644 index 0000000000..df22b25f2b --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/LinkRecordTest.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2005-2014 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.test.integration.record; + +import java.util.List; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.springframework.extensions.webscripts.GUID; + +/** + * Link/Unlink Record Tests + * + * @author Roy Wetherall + * @since 2.3 + */ +public class LinkRecordTest extends BaseRMTestCase +{ + @Override + protected boolean isUserTest() + { + return true; + } + + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + + @Override + protected void initServices() + { + super.initServices(); + } + + /** + * Given source and destination disposition schedules are compatible + * When I link a record to the record folder + * Then it is successful + */ + public void testLinkWithCompatibleDispositionSchedules() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + private NodeRef sourceRecordCategory; + private NodeRef targetRecordCategory; + private NodeRef sourceRecordFolder; + private NodeRef targetRecordFolder; + private NodeRef myRecord; + + public void given() throws Exception + { + // test entities + sourceRecordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + sourceRecordFolder = recordFolderService.createRecordFolder(sourceRecordCategory, GUID.generate()); + myRecord = utils.createRecord(sourceRecordFolder, GUID.generate()); + targetRecordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + targetRecordFolder = recordFolderService.createRecordFolder(targetRecordCategory, GUID.generate()); + + // create disposition schedules on record folders + utils.createBasicDispositionSchedule( + sourceRecordCategory, + "disposition instructions", + "disposition authority", + false, + true); + utils.createBasicDispositionSchedule( + targetRecordCategory, + "disposition instructions", + "disposition authority", + false, + true); + } + + public void when() throws Exception + { + // link the record into the record folder + recordService.link(myRecord, targetRecordFolder); + } + + public void then() throws Exception + { + // assert that the record now has two parents + List assocs = nodeService.getParentAssocs(myRecord); + assertNotNull(assocs); + assertEquals(2, assocs.size()); + } + }); + } + + /** + * Given source and destination disposition schedules are incompatible + * When I link a record to the record folder + * Then it is fails + */ + public void testLinkWithIncompatibleDispositionSchedules() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest(AlfrescoRuntimeException.class) + { + private NodeRef sourceRecordCategory; + private NodeRef targetRecordCategory; + private NodeRef sourceRecordFolder; + private NodeRef targetRecordFolder; + private NodeRef myRecord; + + public void given() throws Exception + { + // test entities + sourceRecordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + sourceRecordFolder = recordFolderService.createRecordFolder(sourceRecordCategory, GUID.generate()); + myRecord = utils.createRecord(sourceRecordFolder, GUID.generate()); + targetRecordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + targetRecordFolder = recordFolderService.createRecordFolder(targetRecordCategory, GUID.generate()); + + // create disposition schedules on record folders + utils.createBasicDispositionSchedule( + sourceRecordCategory, + "disposition instructions", + "disposition authority", + false, + true); + utils.createBasicDispositionSchedule( + targetRecordCategory, + "disposition instructions", + "disposition authority", + true, + true); + } + + public void when() throws Exception + { + // link the record into the record folder + recordService.link(myRecord, targetRecordFolder); + } + }); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java index b134320645..d2b3b8e498 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java @@ -36,7 +36,8 @@ import org.junit.runners.Suite.SuiteClasses; MoveRecordTest.class, HideInplaceRecordTest.class, MoveInplaceRecordTest.class, - ViewRecordTest.class + ViewRecordTest.class, + LinkRecordTest.class }) public class RecordTestSuite { diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index 3a77194016..0f2ac51bfe 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.record; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -33,9 +34,10 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.repo.policy.Behaviour; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.NamespaceService; @@ -77,6 +79,9 @@ public class RecordServiceImplUnitTest extends BaseUnitTest // set-up dictionary service when(mockedDictionaryService.getAllAspects()).thenReturn(CollectionUtils.EMPTY_COLLECTION); + + // mock up getting behaviours + when(recordService.getBehaviour(any(String.class))).thenReturn(mock(Behaviour.class)); } @Test @@ -106,7 +111,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest NodeRef recordFolder = generateRecordFolder(); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // link recordService.link(nonRecord, recordFolder); @@ -118,7 +123,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest NodeRef nonRecordFolder = generateNodeRef(TYPE_FOLDER); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // link recordService.link(record, nonRecordFolder); @@ -139,7 +144,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest makeChildrenOf(recordFolder, record); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // link recordService.link(record, recordFolder); @@ -174,6 +179,147 @@ public class RecordServiceImplUnitTest extends BaseUnitTest QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); } + /** + * Given that the source record has no disposition schedule + * When I link + * Then it is successful + */ + @Test public void linkNoSourceDisposition() + { + // create record and record folder + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + makeChildrenOf(generateRecordFolder(), record); + + // set the name of the record + String name = generateText(); + doReturn(name).when(mockedNodeService).getProperty(record, PROP_NAME); + + // set dispositions + when(mockedDispositionService.getDispositionSchedule(record)) + .thenReturn(null); + + // link + recordService.link(record, recordFolder); + + // verify link was created + verify(mockedNodeService, times(1)).addChild( + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + } + + /** + * Given that the target record folder has no disposition schedule + * When I link + * Then it is successful + */ + @Test public void linkNoTargetDisposition() + { + // create record and record folder + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + makeChildrenOf(generateRecordFolder(), record); + + // set the name of the record + String name = generateText(); + doReturn(name).when(mockedNodeService).getProperty(record, PROP_NAME); + + // set dispositions + when(mockedDispositionService.getDispositionSchedule(record)) + .thenReturn(mock(DispositionSchedule.class)); + when(mockedDispositionService.getDispositionSchedule(record)) + .thenReturn(null); + + // link + recordService.link(record, recordFolder); + + // verify link was created + verify(mockedNodeService, times(1)).addChild( + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + } + + /** + * Given that the source record and target record folder have incompatible disposition schedules + * When I link + * Then I expect a failure + */ + @Test public void linkIncompatibleDispositions() + { + // create record and record folder + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + makeChildrenOf(generateRecordFolder(), record); + + // set the name of the record + String name = generateText(); + doReturn(name).when(mockedNodeService).getProperty(record, PROP_NAME); + + // set dispositions + DispositionSchedule recordDispositionSchedule = mock(DispositionSchedule.class); + when(recordDispositionSchedule.isRecordLevelDisposition()) + .thenReturn(true); + when(mockedDispositionService.getDispositionSchedule(record)) + .thenReturn(recordDispositionSchedule); + + DispositionSchedule recordFolderDispositionSchedule = mock(DispositionSchedule.class); + when(recordFolderDispositionSchedule.isRecordLevelDisposition()) + .thenReturn(false); + when(mockedDispositionService.getDispositionSchedule(recordFolder)) + .thenReturn(recordFolderDispositionSchedule); + + // expect exception + exception.expect(RecordLinkRuntimeException.class); + exception.expectMessage("incompatible disposition schedule"); + + // link + recordService.link(record, recordFolder); + } + + /** + * Given that the source record and target record folder have compatible disposition schedules + * When I link + * Then it is successful + */ + @Test public void linkCompatibleDispositions() + { + // create record and record folder + NodeRef record = generateRecord(); + NodeRef recordFolder = generateRecordFolder(); + makeChildrenOf(generateRecordFolder(), record); + + // set the name of the record + String name = generateText(); + doReturn(name).when(mockedNodeService).getProperty(record, PROP_NAME); + + // set dispositions + DispositionSchedule recordDispositionSchedule = mock(DispositionSchedule.class); + when(recordDispositionSchedule.isRecordLevelDisposition()) + .thenReturn(true); + when(mockedDispositionService.getDispositionSchedule(record)) + .thenReturn(recordDispositionSchedule); + + DispositionSchedule recordFolderDispositionSchedule = mock(DispositionSchedule.class); + when(recordFolderDispositionSchedule.isRecordLevelDisposition()) + .thenReturn(true); + when(mockedDispositionService.getDispositionSchedule(recordFolder)) + .thenReturn(recordFolderDispositionSchedule); + + // link + recordService.link(record, recordFolder); + + // verify link was created + verify(mockedNodeService, times(1)).addChild( + recordFolder, + record, + ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name)); + } + /** * Given invalid types * When unlinking @@ -186,7 +332,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest NodeRef recordFolder = generateRecordFolder(); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // unlink recordService.unlink(nonRecord, recordFolder); @@ -198,7 +344,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest NodeRef nonRecordFolder = generateNodeRef(TYPE_FOLDER); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // unlink recordService.unlink(record, nonRecordFolder); @@ -219,7 +365,7 @@ public class RecordServiceImplUnitTest extends BaseUnitTest makePrimaryParentOf(record, recordFolder); // set expected exception - exception.expect(AlfrescoRuntimeException.class); + exception.expect(RecordLinkRuntimeException.class); // link recordService.unlink(record, recordFolder); diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java index 01394d66de..ab726af049 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java @@ -34,6 +34,7 @@ import java.util.UUID; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; @@ -134,6 +135,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel @Mock(name="transactionalResourceHelper") protected TransactionalResourceHelper mockedTransactionalResourceHelper; @Mock(name="alfrescoTransactionSupport") protected AlfrescoTransactionSupport mockedAlfrescoTransactionSupport; @Mock(name="freezeService") protected FreezeService mockedFreezeService; + @Mock(name="dispositionService") protected DispositionService mockedDispositionService; /** application context mock */ @Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;