assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef assoc : assocs)
{
NodeRef child = assoc.getChildRef();
- if (filePlanService.isFilePlanContainer(child) ||
- recordFolderService.isRecordFolder(child) ||
- recordService.isRecord(child)||
- instanceOf(child, TYPE_HOLD) ||
+ if (isFilePlanContainer(child) ||
+ isRecordFolder(child) ||
+ isRecord(child)||
+ isHold(child) ||
instanceOf(child, TYPE_TRANSFER))
{
deletePermission(child, authority, permission);
@@ -587,6 +541,6 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
return null;
}
- }, AuthenticationUtil.getSystemUserName());
+ });
}
}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java
index ddd5eeb0e6..cca1d1f49f 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java
@@ -31,6 +31,9 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.PropertyMap;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
/**
* Helper base class for service implementations.
@@ -38,13 +41,25 @@ import org.alfresco.util.PropertyMap;
* @author Roy Wetherall
* @since 2.1
*/
-public class ServiceBaseImpl implements RecordsManagementModel
+public class ServiceBaseImpl implements RecordsManagementModel, ApplicationContextAware
{
/** Node service */
protected NodeService nodeService;
/** Dictionary service */
protected DictionaryService dictionaryService;
+
+ /** Application context */
+ protected ApplicationContext applicationContext;
+
+ /**
+ * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
+ */
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
+ {
+ this.applicationContext = applicationContext;
+ }
/**
* @param nodeService node service
@@ -61,6 +76,60 @@ public class ServiceBaseImpl implements RecordsManagementModel
{
this.dictionaryService = dictionaryService;
}
+
+ /**
+ * Indicates whether the given node is a file plan component or not.
+ *
+ * Exposed in the FilePlan service.
+ *
+ * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlanComponent(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ public boolean isFilePlanComponent(NodeRef nodeRef)
+ {
+ boolean result = false;
+
+ // use the internal node service to prevent redirection of security checking.
+ NodeService myNodeService = (NodeService)applicationContext.getBean("nodeService");
+
+ if (myNodeService.exists(nodeRef) &&
+ myNodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT))
+ {
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Indicates whether the given node is a file plan or not.
+ *
+ * Exposed in the FilePlan service.
+ *
+ * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlan(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ public boolean isFilePlan(NodeRef nodeRef)
+ {
+ return instanceOf(nodeRef, TYPE_FILE_PLAN);
+ }
+
+ /**
+ * Indicates whether the given node is a file plan container or not.
+ *
+ * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isFilePlanContainer(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ public boolean isFilePlanContainer(NodeRef nodeRef)
+ {
+ return instanceOf(nodeRef, TYPE_RECORDS_MANAGEMENT_CONTAINER);
+ }
+
+ /**
+ * Indicates whether the given node is a record category or not.
+ *
+ * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#isRecordCategory(org.alfresco.service.cmr.repository.NodeRef)
+ */
+ public boolean isRecordCategory(NodeRef nodeRef)
+ {
+ return instanceOf(nodeRef, TYPE_RECORD_CATEGORY);
+ }
/**
* Indicates whether the given node is a record folder or not.
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImplUnitTest.java
new file mode 100644
index 0000000000..66f4adea3f
--- /dev/null
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImplUnitTest.java
@@ -0,0 +1,263 @@
+/*
+ * 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.security;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.namespace.QName;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Spy;
+
+/**
+ * File plan permission service implementation unit test.
+ *
+ * Primarily tests the file plan permission service interaction with the
+ * permission service.
+ *
+ * @author Roy Wetherall
+ * @since 2.2
+ */
+public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
+{
+ /** test authority */
+ protected static final String AUTHORITY = "anAuthority";
+
+ /** unfiled nodes */
+ protected NodeRef unfiledRecordContainer;
+ protected NodeRef unfiledRecordFolder;
+ protected NodeRef unfiledRecordFolderChild;
+ protected NodeRef unfiledRecord;
+
+ /** held nodes */
+ protected NodeRef holdContainer;
+ protected NodeRef hold;
+ protected NodeRef heldRecord;
+
+ /** file plan permission service implementation */
+ @Spy @InjectMocks FilePlanPermissionServiceImpl filePlanPermissionService;
+
+ /**
+ * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before()
+ */
+ @Override
+ public void before()
+ {
+ super.before();
+
+ // mock up run as methods
+ mockRunAsMethods(filePlanPermissionService);
+
+ // initialize node's
+ unfiledRecordContainer = generateContainerNodeRef(TYPE_UNFILED_RECORD_CONTAINER);
+ unfiledRecordFolder = generateContainerNodeRef(TYPE_UNFILED_RECORD_FOLDER);
+ unfiledRecordFolderChild = generateContainerNodeRef(TYPE_UNFILED_RECORD_FOLDER);
+ unfiledRecord = generateRecord();
+ holdContainer = generateContainerNodeRef(TYPE_HOLD_CONTAINER);
+ hold = generateHoldNodeRef("my test hold");
+ heldRecord = generateRecord();
+
+ // setup parent hierarchy
+ makePrimaryParentOf(filePlan, generateNodeRef(ContentModel.TYPE_FOLDER));
+
+ makePrimaryParentOf(unfiledRecordFolder, unfiledRecordContainer);
+ makePrimaryParentOf(unfiledRecordContainer, filePlan);
+
+ makePrimaryParentOf(hold, holdContainer);
+ makePrimaryParentOf(holdContainer, filePlan);
+
+ // setup child hierarchy
+ makeChildrenOf(unfiledRecordFolder, unfiledRecordFolderChild);
+ makeChildrenOf(unfiledRecordFolderChild, unfiledRecord);
+
+ makeChildrenOf(hold, heldRecord);
+ }
+
+ /**
+ * Helper method to generate a container node ref of a perticular type.
+ *
+ * @param type type of node reference
+ * @return {@link NodeRef} node reference that behaves like a container of the type given.
+ */
+ private NodeRef generateContainerNodeRef(QName type)
+ {
+ NodeRef nodeRef = generateNodeRef(type);
+ setupAsFilePlanComponent(nodeRef);
+ doReturn(true).when(filePlanPermissionService).isFilePlanContainer(nodeRef);
+ return nodeRef;
+ }
+
+ /**
+ * Set read permission on unfiled record folder.
+ */
+ @Test
+ public void setReadPermissionOnUnfiledRecordFolder()
+ {
+ // set read permission on unfiled record folder
+ filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify READ permission set down hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecord, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ }
+
+ /**
+ * Set filling permission on unfiled record folder
+ */
+ @Test
+ public void setReadAndFilePermissionOnUnfileRecordFolder()
+ {
+ // set read permission on unfiled record folder
+ filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify FILING permission set down hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.FILING, true);
+ verify(mockedPermissionService, times(1)).setPermission(unfiledRecord, AUTHORITY, RMPermissionModel.FILING, true);
+ }
+
+ /**
+ * Remove permission from unfiled record folders.
+ */
+ @Test
+ public void deletePermissionFromUnfiledRecordFolder()
+ {
+ // delete read permission from unfiled record folder
+ filePlanPermissionService.deletePermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS);
+
+ // verify permission deleted on target node
+ verify(mockedPermissionService, times(1)).deletePermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS);
+
+ // verify no permissions deleted up the hierarchy
+ verify(mockedPermissionService, never()).deletePermission(eq(unfiledRecordContainer), eq(AUTHORITY), anyString());
+ verify(mockedPermissionService, never()).deletePermission(eq(filePlan), eq(AUTHORITY), anyString());
+
+ // verify READ permission removed down hierarchy
+ verify(mockedPermissionService, times(1)).deletePermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.READ_RECORDS);
+ verify(mockedPermissionService, times(1)).deletePermission(unfiledRecord, AUTHORITY, RMPermissionModel.READ_RECORDS);
+ }
+
+ /**
+ * Set read permission on hold container
+ */
+ public void setReadPermissionOnHoldContainer()
+ {
+ // set read permission on hold
+ filePlanPermissionService.setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify READ permission set on hold
+ verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify permission not set on child of hold
+ verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
+
+ }
+
+ /**
+ * Set filing permission on hold container
+ */
+ public void setFilingPermissionOnHoldContainer()
+ {
+ // set read permission on hold
+ filePlanPermissionService.setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify FILING permission set on hold
+ verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true);
+
+ // verify permission not set on child of hold
+ verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
+
+ }
+
+ /**
+ * Set read permission on hold.
+ */
+ @Test
+ public void setReadPermissionOnHold()
+ {
+ // set read permission on hold
+ filePlanPermissionService.setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify permission not set on child of hold
+ verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
+ }
+
+ /**
+ * Set filing permission on hold.
+ */
+ @Test
+ public void setFilingPermissionOnHold()
+ {
+ // set filing permission on hold
+ filePlanPermissionService.setPermission(hold, AUTHORITY, RMPermissionModel.FILING);
+
+ // verify permission set on target node
+ verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true);
+
+ // verify READ permission set up hierarchy
+ verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+ verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
+
+ // verify permission not set on child of hold
+ verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
+ }
+
+}
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
index ca1eb72d62..43b9af7306 100644
--- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java
@@ -26,6 +26,7 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordServiceImplUnitTe
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPostUnitTest;
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldPutUnitTest;
import org.alfresco.module.org_alfresco_module_rm.script.hold.HoldsGetUnitTest;
+import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionServiceImplUnitTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@@ -46,7 +47,8 @@ import org.junit.runners.Suite.SuiteClasses;
TransferEvaluatorUnitTest.class,
HoldsGetUnitTest.class,
HoldPostUnitTest.class,
- HoldPutUnitTest.class
+ HoldPutUnitTest.class,
+ FilePlanPermissionServiceImplUnitTest.class
})
public class AllUnitTestSuite
{
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 43d52c48a0..6325c296a1 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
@@ -19,7 +19,9 @@
package org.alfresco.module.org_alfresco_module_rm.test.util;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
@@ -34,14 +36,18 @@ import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
+import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl;
+import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNamePattern;
+import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.GUID;
import org.alfresco.util.collections.CollectionUtils;
import org.junit.Before;
@@ -49,6 +55,9 @@ import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.springframework.context.ApplicationContext;
/**
* Base unit test.
@@ -72,12 +81,17 @@ public class BaseUnitTest implements RecordsManagementModel
@Mock(name="dictionaryService") protected DictionaryService mockedDictionaryService;
@Mock(name="namespaceService") protected NamespaceService mockedNamespaceService;
@Mock(name="identifierService") protected IdentifierService mockedIdentifierService;
+ @Mock(name="permissionService") protected PermissionService mockedPermissionService;
+ /** rm service mocks */
@Mock(name="filePlanService") protected FilePlanService mockedFilePlanService;
@Mock(name="recordFolderService") protected RecordFolderService mockedRecordFolderService;
@Mock(name="recordService") protected RecordService mockedRecordService;
@Mock(name="holdService") protected HoldService mockedHoldService;
+ /** application context mock */
+ @Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;
+
/** expected exception rule */
@Rule
public ExpectedException exception = ExpectedException.none();
@@ -89,9 +103,13 @@ public class BaseUnitTest implements RecordsManagementModel
public void before()
{
MockitoAnnotations.initMocks(this);
+
+ // setup application context
+ doReturn(mockedNodeService).when(mockedApplicationContext).getBean("nodeService");
// setup file plan
filePlan = generateNodeRef(TYPE_FILE_PLAN);
+ setupAsFilePlanComponent(filePlan);
doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan);
// setup basic file plan component
@@ -112,8 +130,7 @@ public class BaseUnitTest implements RecordsManagementModel
doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
doReturn(result).when(mockedNodeService).getParentAssocs(record);
doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
- doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
-
+ doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
}
/**
@@ -179,7 +196,7 @@ public class BaseUnitTest implements RecordsManagementModel
doReturn(filePlan).when(mockedFilePlanService).getFilePlan(nodeRef);
doReturn(filePlan).when(mockedNodeService).getProperty(nodeRef, PROP_ROOT_NODEREF);
}
-
+
/**
* Helper method to generate a node reference.
*
@@ -207,4 +224,72 @@ public class BaseUnitTest implements RecordsManagementModel
}
return nodeRef;
}
+
+ /**
+ * Helper method to make one node the primary parent of the other.
+ *
+ * Assumes the cm:contains assoc type.
+ *
+ * @param child
+ * @param parent
+ */
+ protected void makePrimaryParentOf(NodeRef child, NodeRef parent)
+ {
+ doReturn(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, parent, generateQName(), child))
+ .when(mockedNodeService)
+ .getPrimaryParent(child);
+ }
+
+ /**
+ * Helper method to make a number of nodes children of another.
+ *
+ * Assumes the cm:contains assoc type.
+ *
+ * @param parent
+ * @param children
+ */
+ protected void makeChildrenOf(NodeRef parent, NodeRef ... children)
+ {
+ List assocs = new ArrayList(children.length);
+ for (NodeRef child : children)
+ {
+ assocs.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, parent, generateQName(), child));
+ }
+
+ doReturn(assocs).when(mockedNodeService).getChildAssocs(parent, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
+ }
+
+ /**
+ * Helper method to mock up calls to 'run as' methods
+ * on base service implementation.
+ *
+ * @param service
+ */
+ @SuppressWarnings("unchecked")
+ protected void mockRunAsMethods(ServiceBaseImpl service)
+ {
+ doAnswer(new Answer