mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-6869 removing linked record during rejection
This commit is contained in:
@@ -75,4 +75,30 @@ public class ActionsExecutionAPI extends RMModelRequest
|
|||||||
return getRmRestWrapper().withCoreAPI().usingActions()
|
return getRmRestWrapper().withCoreAPI().usingActions()
|
||||||
.executeAction(ActionsOnRule.DECLARE_AS_RECORD.getActionValue(), targetNode);
|
.executeAction(ActionsOnRule.DECLARE_AS_RECORD.getActionValue(), targetNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links a record to a new record folder using v1 actions api
|
||||||
|
*
|
||||||
|
* @param targetNode the node on which the action is executed
|
||||||
|
* @param destination the path of the category/folder to create and place the link
|
||||||
|
*/
|
||||||
|
public JSONObject linkRecord(RepoTestModel targetNode, String destination) throws Exception
|
||||||
|
{
|
||||||
|
return getRmRestWrapper().withCoreAPI().usingActions()
|
||||||
|
.executeAction(ActionsOnRule.LINK_TO.getActionValue(), targetNode,
|
||||||
|
ImmutableMap.of("path", destination, "createRecordPath", "true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rejects a record using v1 actions api
|
||||||
|
*
|
||||||
|
* @param targetNode record to reject
|
||||||
|
* @param reason reason for rejection
|
||||||
|
*/
|
||||||
|
public JSONObject rejectRecord(RepoTestModel targetNode, String reason) throws Exception
|
||||||
|
{
|
||||||
|
return getRmRestWrapper().withCoreAPI().usingActions()
|
||||||
|
.executeAction(ActionsOnRule.REJECT.getActionValue(), targetNode,
|
||||||
|
ImmutableMap.of("reason", reason));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* #%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.rest.rm.community.records;
|
||||||
|
|
||||||
|
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||||
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.alfresco.dataprep.CMISUtil;
|
||||||
|
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
|
||||||
|
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||||
|
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
|
||||||
|
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildCollection;
|
||||||
|
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildEntry;
|
||||||
|
import org.alfresco.test.AlfrescoTest;
|
||||||
|
import org.alfresco.utility.Utility;
|
||||||
|
import org.alfresco.utility.model.FileModel;
|
||||||
|
import org.alfresco.utility.model.SiteModel;
|
||||||
|
import org.testng.annotations.AfterClass;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API tests for rejecting records
|
||||||
|
* @author Ross Gale
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class RejectRecordTests extends BaseRMRestTest
|
||||||
|
{
|
||||||
|
private SiteModel publicSite;
|
||||||
|
private RecordCategory recordCategory;
|
||||||
|
private RecordCategoryChild recordFolder;
|
||||||
|
|
||||||
|
@BeforeClass (alwaysRun = true)
|
||||||
|
public void setUp() throws Exception
|
||||||
|
{
|
||||||
|
createRMSiteIfNotExists();
|
||||||
|
publicSite = dataSite.usingAdmin().createPublicRandomSite();
|
||||||
|
recordCategory = createRootCategory(getRandomName("recordCategory"));
|
||||||
|
recordFolder = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that when rejecting a linked record that the link is also removed
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@AlfrescoTest(jira = "RM-6869")
|
||||||
|
public void declareAndFileToValidLocationUsingActionsAPI() throws Exception
|
||||||
|
{
|
||||||
|
STEP("Create a document in the collaboration site");
|
||||||
|
FileModel testFile = dataContent.usingSite(publicSite)
|
||||||
|
.usingAdmin()
|
||||||
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
|
STEP("Declare document as record with a location parameter value");
|
||||||
|
getRestAPIFactory().getActionsAPI(getAdminUser()).declareAndFile(testFile,
|
||||||
|
Utility.buildPath(recordCategory.getName(), recordFolder.getName()));
|
||||||
|
|
||||||
|
STEP("Link record to new folder");
|
||||||
|
getRestAPIFactory().getActionsAPI().linkRecord(testFile, recordCategory.getName() + "/" + recordFolder.getName() + "_2");
|
||||||
|
RecordCategoryChildCollection recordFolders = getRestAPIFactory().getRecordCategoryAPI().getRecordCategoryChildren(recordCategory.getId());
|
||||||
|
Optional<RecordCategoryChildEntry> linkedFolder = recordFolders.getEntries().stream().filter(child -> child.getEntry().getName().equals(recordFolder.getName() + "_2"))
|
||||||
|
.findFirst();
|
||||||
|
if (linkedFolder.isPresent())
|
||||||
|
{
|
||||||
|
STEP("Verify the linked record has been added");
|
||||||
|
assertFalse(getRestAPIFactory().getRecordFolderAPI().getRecordFolderChildren(linkedFolder.get().getEntry().getId()).isEmpty());
|
||||||
|
|
||||||
|
STEP("Reject record");
|
||||||
|
getRestAPIFactory().getActionsAPI().rejectRecord(testFile, "Just because");
|
||||||
|
|
||||||
|
STEP("Check record has been rejected");
|
||||||
|
assertFalse(isMatchingRecordInRecordFolder(testFile, recordFolder));
|
||||||
|
|
||||||
|
STEP("Verify the linked record has been removed");
|
||||||
|
assertTrue(getRestAPIFactory().getRecordFolderAPI().getRecordFolderChildren(linkedFolder.get().getEntry().getId()).isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass (alwaysRun = true)
|
||||||
|
public void cleanUp()
|
||||||
|
{
|
||||||
|
deleteRecordCategory(recordCategory.getId());
|
||||||
|
dataSite.deleteSite(publicSite);
|
||||||
|
}
|
||||||
|
}
|
@@ -1497,10 +1497,11 @@ public class RecordServiceImpl extends BaseBehaviourBean
|
|||||||
final List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
final List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||||
for (ChildAssociationRef childAssociationRef : parentAssocs)
|
for (ChildAssociationRef childAssociationRef : parentAssocs)
|
||||||
{
|
{
|
||||||
if (!childAssociationRef.isPrimary() && childAssociationRef.getParentRef().equals(originatingLocation))
|
if (!childAssociationRef.isPrimary() &&
|
||||||
|
(childAssociationRef.getParentRef().equals(originatingLocation) ||
|
||||||
|
nodeService.getType(childAssociationRef.getParentRef()).equals(TYPE_RECORD_FOLDER)))
|
||||||
{
|
{
|
||||||
nodeService.removeChildAssociation(childAssociationRef);
|
nodeService.removeChildAssociation(childAssociationRef);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,7 +41,10 @@ import static org.mockito.Mockito.times;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -49,10 +52,12 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
|||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
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.DispositionSchedule;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.notification.RecordsManagementNotificationHelper;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||||
import org.alfresco.repo.policy.Behaviour;
|
import org.alfresco.repo.policy.Behaviour;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
|
import org.alfresco.service.cmr.rendition.RenditionService;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
@@ -63,6 +68,7 @@ import org.apache.commons.collections.CollectionUtils;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,6 +87,24 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
private NodeRef closedRecordFolder;
|
private NodeRef closedRecordFolder;
|
||||||
private ChildAssociationRef parentAssoc;
|
private ChildAssociationRef parentAssoc;
|
||||||
|
|
||||||
|
private final String recordId = "recordId";
|
||||||
|
private final String documentOwner = "Bob";
|
||||||
|
private final String originalName = "originalName";
|
||||||
|
private final NodeRef originatingLocation = new NodeRef("workspace://SpacesStore/originalLocation");
|
||||||
|
private final NodeRef link = new NodeRef("workspace://SpacesStore/linkLocation");
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RenditionService mockedRenditionService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RecordsManagementNotificationHelper mockedNotificationHelper;
|
||||||
|
@Mock
|
||||||
|
private ChildAssociationRef mockedChildAssoc;
|
||||||
|
@Mock
|
||||||
|
private ChildAssociationRef mockedLinkAssoc;
|
||||||
|
@Mock
|
||||||
|
private ChildAssociationRef mockedParentAssoc;
|
||||||
|
|
||||||
private static QName TYPE_MY_FILE_PLAN = generateQName();
|
private static QName TYPE_MY_FILE_PLAN = generateQName();
|
||||||
private static QName ASPECT_FOR_FILE_PLAN = generateQName();
|
private static QName ASPECT_FOR_FILE_PLAN = generateQName();
|
||||||
|
|
||||||
@@ -639,4 +663,54 @@ public class RecordServiceImplUnitTest extends BaseUnitTest
|
|||||||
|
|
||||||
when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null);
|
when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the mocks for the reject record scenarios
|
||||||
|
* @param mockProperties the mock for the node properties
|
||||||
|
*/
|
||||||
|
private void setUpReject(Map mockProperties)
|
||||||
|
{
|
||||||
|
when(mockedNodeService.getProperties(dmNodeRef)).thenReturn(mockProperties);
|
||||||
|
when(mockedVersionService.getVersionHistory(dmNodeRef)).thenReturn(null);
|
||||||
|
when(mockProperties.get(PROP_IDENTIFIER)).thenReturn(recordId);
|
||||||
|
when(mockProperties.get(PROP_ORIGIONAL_NAME)).thenReturn(originalName);
|
||||||
|
when(mockProperties.get(PROP_RECORD_ORIGINATING_LOCATION)).thenReturn(originatingLocation);
|
||||||
|
List<ChildAssociationRef> assocs = new ArrayList<>();
|
||||||
|
assocs.add(mockedChildAssoc);
|
||||||
|
assocs.add(mockedLinkAssoc);
|
||||||
|
when(mockedNodeService.getParentAssocs(dmNodeRef)).thenReturn(assocs);
|
||||||
|
when(mockedChildAssoc.getParentRef()).thenReturn(originatingLocation);
|
||||||
|
when(mockedLinkAssoc.getParentRef()).thenReturn(dmNodeRef);
|
||||||
|
when(mockedLinkAssoc.getParentRef()).thenReturn(link);
|
||||||
|
when(mockedNodeService.getType(link)).thenReturn(TYPE_RECORD_FOLDER);
|
||||||
|
when(mockedNodeService.getPrimaryParent(dmNodeRef)).thenReturn(mockedParentAssoc);
|
||||||
|
when(mockedParentAssoc.getQName()).thenReturn(ContentModel.TYPE_CATEGORY);
|
||||||
|
doNothing().when(recordService).invokeBeforeRecordRejection(dmNodeRef);
|
||||||
|
doNothing().when(recordService).invokeOnRecordRejection(dmNodeRef);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Test for the reject record method
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRejectRecord()
|
||||||
|
{
|
||||||
|
Map mockProperties = mock(HashMap.class);
|
||||||
|
setUpReject(mockProperties);
|
||||||
|
when(mockProperties.get(PROP_RECORD_ORIGINATING_USER_ID)).thenReturn(documentOwner);
|
||||||
|
recordService.rejectRecord(dmNodeRef, "Just because..");
|
||||||
|
verify(mockedNodeService, times(1)).removeChildAssociation(mockedChildAssoc);
|
||||||
|
verify(mockedNodeService, times(1)).removeChildAssociation(mockedLinkAssoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the reject record method throws an error without document owner
|
||||||
|
*/
|
||||||
|
@Test (expected = AlfrescoRuntimeException.class)
|
||||||
|
public void testRejectRecordThrowsErrorWithoutDocumentOwner()
|
||||||
|
{
|
||||||
|
Map mockProperties = mock(HashMap.class);
|
||||||
|
setUpReject(mockProperties);
|
||||||
|
when(mockProperties.get(PROP_RECORD_ORIGINATING_USER_ID)).thenReturn(null);
|
||||||
|
recordService.rejectRecord(dmNodeRef, "Just because..");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user