diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java index 866c550dff..f3cecae507 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/service/DispositionScheduleService.java @@ -30,7 +30,6 @@ package org.alfresco.rest.v0.service; import java.util.HashMap; import org.alfresco.rest.core.v0.BaseAPI; -import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; import org.alfresco.rest.v0.RecordCategoriesAPI; import org.alfresco.utility.data.DataUser; import org.springframework.beans.factory.annotation.Autowired; @@ -85,6 +84,24 @@ public class DispositionScheduleService extends BaseAPI dataUser.getAdminUser().getPassword(), categoryName, cutOffStep); } + /** + * Helper method for adding a destroy with ghosting after period + * + * @param categoryName the category in whose schedule the step will be added + * @param period + * @return + */ + public void addDestroyWithGhostingAfterPeriodStep(String categoryName, String period) + { + HashMap destroyStep = new HashMap<>(); + destroyStep.put(RETENTION_SCHEDULE.NAME, "destroy"); + destroyStep.put(RETENTION_SCHEDULE.RETENTION_PERIOD, "immediately|"); + destroyStep.put(RETENTION_SCHEDULE.DESCRIPTION, "Destroy immediately"); + destroyStep.put(RETENTION_SCHEDULE.RETENTION_GHOST, "on"); + recordCategoriesAPI.addDispositionScheduleSteps(dataUser.getAdminUser().getUsername(), + dataUser.getAdminUser().getPassword(), categoryName, destroyStep); + } + /** * Helper method for adding a cut off after an event occurs step * diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java index 79e30ea0d4..1267f371a2 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java @@ -40,6 +40,8 @@ import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.create import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicUnfiledContainerChildModel; import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile; import static org.alfresco.utility.constants.UserRole.SiteCollaborator; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.HttpStatus.NOT_FOUND; @@ -49,23 +51,29 @@ import static org.springframework.http.HttpStatus.OK; import org.alfresco.dataprep.CMISUtil; import org.alfresco.rest.core.JsonBodyGenerator; import org.alfresco.rest.core.RestResponse; +import org.alfresco.rest.core.v0.BaseAPI.RM_ACTIONS; import org.alfresco.rest.model.RestNodeBodyMoveCopyModel; import org.alfresco.rest.model.RestNodeModel; import org.alfresco.rest.requests.Node; import org.alfresco.rest.rm.community.base.BaseRMRestTest; import org.alfresco.rest.rm.community.model.record.Record; +import org.alfresco.rest.rm.community.model.record.RecordBodyFile; +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.unfiledcontainer.UnfiledContainerChild; import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI; import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI; import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.service.DispositionScheduleService; import org.alfresco.test.AlfrescoTest; import org.alfresco.utility.data.RandomData; import org.alfresco.utility.model.FileModel; +import org.alfresco.utility.model.FolderModel; import org.alfresco.utility.model.RepoTestModel; import org.alfresco.utility.model.SiteModel; import org.alfresco.utility.model.UserModel; -import org.alfresco.utility.report.log.Step; +import org.springframework.beans.factory.annotation.Autowired; import org.testng.annotations.Test; /** @@ -76,6 +84,13 @@ import org.testng.annotations.Test; */ public class DeleteRecordTests extends BaseRMRestTest { + @Autowired + private DispositionScheduleService dispositionScheduleService; + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + @Autowired + private org.alfresco.rest.v0.RecordsAPI recordsAPI; + /** *
      * Given an electronic record
@@ -266,24 +281,24 @@ public class DeleteRecordTests extends BaseRMRestTest
     @AlfrescoTest(jira="MNT-18806")
     public void deleteCopyOfRecord()
     {
-        Step.STEP("Create two record categories and folders.");
+        STEP("Create two record categories and folders.");
         RecordCategoryChild recordFolderA = createCategoryFolderInFilePlan();
         RecordCategoryChild recordFolderB = createCategoryFolderInFilePlan();
 
-        Step.STEP("Create a record in folder A and copy it into folder B.");
+        STEP("Create a record in folder A and copy it into folder B.");
         String recordId = getRestAPIFactory().getRecordFolderAPI()
                     .createRecord(createElectronicRecordModel(), recordFolderA.getId(), getFile(IMAGE_FILE)).getId();
         String copyId = copyRecord(recordId, recordFolderB.getId()).getId();
         assertStatusCode(CREATED);
 
-        Step.STEP("Check that it's possible to load the original content.");
+        STEP("Check that it's possible to load the original content.");
         getNodeContent(recordId);
         assertStatusCode(OK);
 
-        Step.STEP("Delete the copy.");
+        STEP("Delete the copy.");
         deleteAndVerify(copyId);
 
-        Step.STEP("Check that the original record node and content still exist.");
+        STEP("Check that the original record node and content still exist.");
         checkNodeExists(recordId);
         getNodeContent(recordId);
     }
@@ -301,30 +316,126 @@ public class DeleteRecordTests extends BaseRMRestTest
     @AlfrescoTest (jira = "MNT-20145")
     public void deleteOriginOfRecord() throws Exception
     {
-        Step.STEP("Create a file.");
+        STEP("Create a file.");
         testSite = dataSite.usingAdmin().createPublicRandomSite();
         FileModel testFile = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
 
-        Step.STEP("Create a copy for the file created.");
+        STEP("Create a copy for the file created.");
         String postBody = JsonBodyGenerator.keyValueJson("targetParentId", testSite.getGuid());
         RestNodeModel copyOfTestFile = getRestAPIFactory().getNodeAPI(testFile).copyNode(postBody);
 
-        Step.STEP("Declare original file as record");
+        STEP("Declare original file as record");
         getRestAPIFactory().getFilesAPI().declareAsRecord(testFile.getNodeRefWithoutVersion());
         assertStatusCode(CREATED);
 
-        Step.STEP("Delete the record.");
-        getRestAPIFactory().getRecordsAPI().deleteRecord(testFile.getNodeRefWithoutVersion());
-        assertStatusCode(NO_CONTENT);
+        STEP("Delete the record.");
+        deleteAndVerify(testFile.getNodeRefWithoutVersion());
 
-        Step.STEP("Check that it's possible to load the copy content.");
+        STEP("Check that it's possible to load the copy content.");
         getNodeContent(copyOfTestFile.getId());
         assertStatusCode(OK);
 
-        Step.STEP("Clean up.");
+        STEP("Clean up.");
         dataSite.deleteSite(testSite);
     }
 
+    /**
+     * 
+     * Given a file that has  copy
+     * And the original file is declared as record
+     * And the file becomes part of a disposition schedule with a destroy step
+     * When the record is destroyed
+     * Then it is still possible to view the content of the copy
+     * 
+ */ + @Test (description = "Destroying record doesn't delete the content for the associated copy") + @AlfrescoTest (jira = "MNT-20145") + public void destroyOfRecord() throws Exception + { + STEP("Create a file."); + testSite = dataSite.usingAdmin().createPublicRandomSite(); + FileModel testFile = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN); + FolderModel folderModel =dataContent.usingSite(testSite).createFolder(); + + STEP("Create a copy for the file created."); + RestNodeModel copy = copyRecord(testFile.getNodeRefWithoutVersion(), folderModel.getNodeRefWithoutVersion()); + assertStatusCode(CREATED); + + STEP("Declare the file as record."); + getRestAPIFactory().getFilesAPI().declareAsRecord(testFile.getNodeRefWithoutVersion()); + assertStatusCode(CREATED); + + STEP("Create a record category with a disposition schedule."); + RecordCategory recordCategory = createRootCategory(getRandomName("Category with disposition")); + dispositionScheduleService.createCategoryRetentionSchedule(recordCategory.getName(), true); + + STEP("Add retention schedule cut off and destroy step with immediate period."); + dispositionScheduleService.addCutOffAfterPeriodStep(recordCategory.getName(), "immediately"); + dispositionScheduleService.addDestroyWithGhostingAfterPeriodStep(recordCategory.getName(), "immediately"); + + STEP("Create a record folder and file the record"); + RecordCategoryChild recFolder = createFolder(recordCategory.getId(), getRandomName("recFolder")); + RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(recFolder.getId()).build(); + Record recordFiled = getRestAPIFactory().getRecordsAPI().fileRecord(recordBodyFile, testFile.getNodeRefWithoutVersion()); + getRestAPIFactory().getRecordsAPI().completeRecord(recordFiled.getId()); + assertStatusCode(CREATED); + + STEP("Execute the disposition schedule steps ."); + rmRolesAndActionsAPI.executeAction(getAdminUser().getUsername(), getAdminUser().getUsername(), recordFiled.getName(), + RM_ACTIONS.CUT_OFF); + rmRolesAndActionsAPI.executeAction(getAdminUser().getUsername(), getAdminUser().getUsername(), recordFiled.getName(), + RM_ACTIONS.DESTROY); + + STEP("Check that it's possible to load the copy content."); + getNodeContent(copy.getId()); + assertStatusCode(OK); + + STEP("Clean up."); + dataSite.deleteSite(testSite); + + } + + /** + *
+     * Given a file that is declared version as record
+     * When the record is deleted
+     * Then it is still possible to view the content of the file
+     * 
+ */ + @Test (description = "Destroying record doesn't delete the content for the associated copy") + @AlfrescoTest (jira = "MNT-20145") + public void deleteVersionDeclaredAsRecord() throws Exception + { + STEP("Create a file."); + testSite = dataSite.usingAdmin().createPublicRandomSite(); + FileModel testFile = dataContent.usingSite(testSite).createContent(CMISUtil.DocumentType.TEXT_PLAIN); + FolderModel folderModel = dataContent.usingSite(testSite).createFolder(); + + STEP("Declare the file as record."); + // declare documents as records + recordsAPI.declareDocumentVersionAsRecord(getAdminUser().getUsername(), getAdminUser().getPassword(), testSite.getId(), + testFile.getName()); + UnfiledContainerChild unfiledContainerChild = getRestAPIFactory().getUnfiledContainersAPI() + .getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS) + .getEntries().stream() + .filter(child -> child.getEntry().getName() + .startsWith(testFile.getName().substring(0, testFile.getName().indexOf(".")))) + .findFirst() + .get().getEntry(); + + STEP("Delete the record."); + deleteAndVerify(unfiledContainerChild.getId()); + + STEP("Check that it's possible to load the file declared version as record."); + getNodeContent(testFile.getNodeRefWithoutVersion()); + assertStatusCode(OK); + + STEP("Clean up."); + dataSite.deleteSite(testSite); + + } + + /** * Utility method to delete a record and verify successful deletion *