diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/LinksAPI.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/LinksAPI.java new file mode 100644 index 0000000000..0eb10ff546 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/LinksAPI.java @@ -0,0 +1,73 @@ +/*- + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ + +package org.alfresco.rest.v0; + +import org.alfresco.rest.core.v0.BaseAPI; +import org.apache.http.HttpResponse; +import org.json.JSONArray; +import org.json.JSONObject; +import org.springframework.stereotype.Component; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.MessageFormat; +import java.util.List; + +/** + * Methods to make API requests using v0 API for Linking Records + * + * @author Kavit Shah + * @since 3.2 + */ +@Component +public class LinksAPI extends BaseAPI { + + private static final String LINK_API = "{0}doclib/action/rm-link/site/rm/documentLibrary/{1}"; + + /** + * Creates the Link + * + * @param user The username of the user to use. + * @param password The password of the user. + * @param expectedStatusCode The expected return status code. + * @param sourcePath The Source of link the record. This should be in the format + * "{site}/{container}/{path}", "{site}/{container}", "{store_type}/{store_id}/{id}/{path}", + * "{store_type}/{store_id}/{id}" or "{store_type}/{store_id}". + * @param nodeRefs The Node that needs to be linked. + * @return The HTTP Response. + * @throws AssertionError If the API didn't return the expected status code. + */ + public HttpResponse linkRecord(String user, String password, int expectedStatusCode, String sourcePath, List nodeRefs) throws UnsupportedEncodingException { + JSONObject requestParams = new JSONObject(); + requestParams.put("nodeRefs", new JSONArray(nodeRefs)); + + return doSlingshotPostJsonRequest(user, password, expectedStatusCode, requestParams, + MessageFormat.format(LINK_API, "{0}", sourcePath)); + } + +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RecordCategoriesAPI.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RecordCategoriesAPI.java index 0233e99781..17fee78f10 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RecordCategoriesAPI.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/v0/RecordCategoriesAPI.java @@ -52,7 +52,7 @@ public class RecordCategoriesAPI extends BaseAPI private static final String RM_ACTIONS_API = "{0}rma/actions/ExecutionQueue"; private static final String DISPOSITION_ACTIONS_API = "{0}node/{1}/dispositionschedule/dispositionactiondefinitions"; private static final String DISPOSITION_SCHEDULE_API = "{0}node/{1}/dispositionschedule"; - + private static final String NEXT_DISPOSITION_ACTIONS_API = "{0}node/{1}/nextdispositionaction"; /** * Creates a retention schedule for the category given as parameter @@ -191,4 +191,19 @@ public class RecordCategoriesAPI extends BaseAPI retentionProperties.put(RETENTION_SCHEDULE.RETENTION_INSTRUCTIONS, instructions); return retentionProperties; } + + /** + * Get the Next Disposition Action + * + * @param user + * @param password + * @param recordId + * @return the next disposition schedule action + */ + public JSONObject getNextDispositionAction(String user, String password, String recordId) + { + String nodeRef = NODE_PREFIX + recordId; + JSONObject nextDispositionAction = doGetRequest(user, password, MessageFormat.format(NEXT_DISPOSITION_ACTIONS_API, "{0}", nodeRef)); + return nextDispositionAction; + } } diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeclareInPlaceRecordsTestLevel2.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeclareInPlaceRecordsTestLevel2.java new file mode 100644 index 0000000000..c871abd17c --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeclareInPlaceRecordsTestLevel2.java @@ -0,0 +1,311 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ + +package org.alfresco.rest.rm.community.records; + +import org.alfresco.dataprep.CMISUtil; +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.record.Record; +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.rules.ActionsOnRule; +import org.alfresco.rest.rm.community.model.rules.RuleDefinition; +import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer; +import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordsAPI; +import org.alfresco.rest.v0.RulesAPI; +import org.alfresco.rest.v0.service.DispositionScheduleService; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.model.FileModel; +import org.alfresco.utility.model.FolderModel; +import org.alfresco.utility.model.SiteModel; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import static java.util.Arrays.asList; +import static org.alfresco.rest.core.v0.BaseAPI.NODE_PREFIX; +import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID; +import static org.alfresco.rest.rm.community.base.TestData.DEFAULT_PASSWORD; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; +import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CREATED_DATE; +import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS; +import static org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI.PARENT_ID_PARAM; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.junit.Assert.assertTrue; +import static org.springframework.http.HttpStatus.CREATED; + +public class DeclareInPlaceRecordsTestLevel2 extends BaseRMRestTest { + private final String TEST_PREFIX = generateTestPrefix(DeclareInPlaceRecordsTestLevel2.class); + private final String RM_ADMIN = TEST_PREFIX + "rm_admin"; + private final String RECORDS_CATEGORY_ONE = TEST_PREFIX + "category"; + public static final String RECORD_FOLDER_ONE = "record-folder-one"; + public static final String RECORD_CATEGORY_TWO = "record-category-two" + System.currentTimeMillis(); + public static final String RECORD_FOLDER_TWO = "record-folder-two"; + private final String RULE_NAME = TEST_PREFIX + "rule unfiled"; + private String unfiledRecordsNodeRef; + private RecordCategory RecordCategoryOne, RecordCategoryTwo; + private RecordCategoryChild recordFolder; + private UnfiledContainer unfiledContainer; + private FolderModel testFolder; + private SiteModel testSite; + private SiteModel privateSite; + private UserModel testUser; + @Autowired + private DispositionScheduleService dispositionScheduleService; + @Autowired + private RulesAPI rulesAPI; + /** + * data prep services + */ + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + @Autowired + private RecordsAPI recordsAPI; + + @BeforeClass(alwaysRun = true) + public void preConditions() { + STEP("Create RM Site"); + createRMSiteIfNotExists(); + privateSite = dataSite.usingAdmin().createPrivateRandomSite(); + } + + /** + * Given that a user is the owner of a document + * And that user has been deleted + * When admin tries to declare the document as a record + * Then the document becomes an inplace record + */ + @Test + @AlfrescoTest(jira="RM-2584") + public void DeclareRecordOwnerDeleted() throws Exception { + + createTestPrecondition(); + + // Upload document in a folder in a collaboration site + FileModel uploadedDoc = dataContent.usingSite(testSite) + .usingUser(testUser) + .usingResource(testFolder) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + + // delete the test user + dataUser.deleteUser(testUser); + + // declare uploadedDocument as record + getRestAPIFactory().getFilesAPI(getDataUser().getAdminUser()).declareAsRecord(uploadedDoc.getNodeRefWithoutVersion()); + assertStatusCode(CREATED); + + // assert that the document is now a record + assertTrue(hasRecordAspect(uploadedDoc)); + } + /** + * Given that a user is the owner of a document + * And that user declare the document as a record + * When admin files the record to a category that has a disposition schedule applied on records and a cut off step + * And admin completes the record so the pending record action is now Cut off + * Then user is still able to see the in place record in original share site location + */ + @Test + @AlfrescoTest(jira="MNT-18558") + public void inPlaceRecordVisibilityAfterFilingToCategoryWithCutOffStep() throws Exception { + + // create test precondition + createTestPrecondition(RECORDS_CATEGORY_ONE); + + //create a disposition schedule on Records level with a cut off step + dispositionScheduleService.createCategoryRetentionSchedule(RECORDS_CATEGORY_ONE, true); + dispositionScheduleService.addCutOffAfterPeriodStep(RECORDS_CATEGORY_ONE, "day|2", CREATED_DATE); + + //create a folder in category + recordFolder = createFolder(getAdminUser(),RecordCategoryOne.getId(),RECORD_FOLDER_ONE); + + // create a File to record folder rule applied on Unfiled Records container + fileToRuleAppliedOnUnfiledRecords(); + + //create a new test user + UserModel testUser = createSiteManager(); + + // upload a new document as the user and declare the document as record + FileModel uploadedDoc = dataContent.usingSite(privateSite) + .usingUser(testUser) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + + Record uploadedRecord = getRestAPIFactory().getFilesAPI(getDataUser().getAdminUser()).declareAsRecord(uploadedDoc.getNodeRefWithoutVersion()); + assertStatusCode(CREATED); + + //Complete the record as admin to be sure that pending action is now Cut off + recordsAPI.completeRecord(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), uploadedRecord.getName()); + + // As test user navigate to collaboration site documents library and check that the record is still visible + dataContent.usingAdmin().usingSite(privateSite).assertContentExist(); + } + /** + * Create a user called test + * Create a collaboration site + * Add the user to the collaboration site as consumer + * Create an RM site + * In RM, create a new categories under file plan with a cut off step set after an event happens + * Under the previously created category create a folder + * Set READ-ONLY permission for test user for the folder previously created (the user does not have Read + * permissions to the category containing the folder) + * In the collaboration site create two files + * File as record the first file + * Log in with test user and check if he can still see the two files in the collaboration site + */ + @Test + @AlfrescoTest (jira = "MNT-22138") + public void filesVisibilityAfterFilingToCategoryWithCutOffAfterEventStep() throws Exception { + + //create a category + RecordCategoryTwo = createRootCategory(RECORD_CATEGORY_TWO); + + //create a disposition schedule on Records level with a cut off step + dispositionScheduleService.createCategoryRetentionSchedule(RECORD_CATEGORY_TWO, true); + dispositionScheduleService.addCutOffAfterPeriodStep(RECORD_CATEGORY_TWO, "day|2", CREATED_DATE); + + //create a folder in category + recordFolder = createFolder(getAdminUser(),RecordCategoryTwo.getId(),RECORD_FOLDER_TWO); + + //create a new test user + UserModel siteConsumer = getDataUser().createRandomTestUser(); + getDataUser().addUserToSite(siteConsumer,privateSite,UserRole.SiteConsumer); + + // give read permissions to test user + getRestAPIFactory().getRMUserAPI().addUserPermission(recordFolder.getId(), siteConsumer, PERMISSION_READ_RECORDS); + + // create two documents + FileModel testFile = dataContent.usingSite(new SiteModel(privateSite.getTitle())) + .usingAdmin() + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + + FileModel testFileNotFiled = dataContent.usingSite(new SiteModel(privateSite.getTitle())) + .usingAdmin() + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + + // file one of the documents as record + getRestAPIFactory().getFilesAPI() + .usingParams(String.format("%s=%s", PARENT_ID_PARAM, recordFolder.getId())) + .declareAsRecord(testFile.getNodeRefWithoutVersion()); + getRestAPIFactory().getRmRestWrapper().assertStatusCodeIs(CREATED); + + // As test user navigate to collaboration site documents library and check that both of the documents are + // visible + STEP("Verify the document in collaboration site is now a record"); + Assert.assertTrue(hasRecordAspect(testFile), "File should have record aspect"); + Assert.assertFalse(hasRecordAspect(testFileNotFiled), "File should not have record aspect"); + } + + private void createTestPrecondition(String categoryName) { + + // create "rm admin" user if it does not exist and assign it to RM Administrator role + rmRolesAndActionsAPI.createUserAndAssignToRole( + getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), + RM_ADMIN, DEFAULT_PASSWORD, "Administrator"); + + // create category + STEP("Create category"); + RecordCategoryOne = createRootCategory(categoryName,"Title"); + + unfiledContainer = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS); + + unfiledRecordsNodeRef = NODE_PREFIX + unfiledContainer.getId(); + } + private void createTestPrecondition() { + STEP("Create collab_user user"); + testUser = getDataUser().createRandomTestUser(); + testSite = dataSite.usingAdmin().createPublicRandomSite(); + + // invite collab_user to Collaboration site with Contributor role + getDataUser().addUserToSite(testUser, testSite, UserRole.SiteContributor); + + testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder(); + } + private void fileToRuleAppliedOnUnfiledRecords() { + unfiledRecordsRuleTeardown(); + + // create a rule + RuleDefinition ruleDefinition = RuleDefinition.createNewRule().title(RULE_NAME) + .description(RULE_NAME) + .createRecordPath(false) + .path("/" + RECORDS_CATEGORY_ONE + "/" + RECORD_FOLDER_ONE) + .runInBackground(true) + .actions(asList(ActionsOnRule.FILE_TO.getActionValue())); + + // create a rule on unfiledRecords + rulesAPI.createRule(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), unfiledRecordsNodeRef, ruleDefinition); + } + private void unfiledRecordsRuleTeardown() { + rulesAPI.deleteAllRulesOnContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), unfiledRecordsNodeRef); + } + public UserModel createSiteManager() { + UserModel siteManager = getDataUser().createRandomTestUser(); + getDataUser().addUserToSite(siteManager, privateSite, UserRole.SiteManager); + return siteManager; + } + @AfterClass + public void cleanupCategory() { + unfiledRecordsRuleTeardown(); + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, RECORD_FOLDER_ONE); + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, RecordCategoryOne.getName()); + deleteRecordCategory(RecordCategoryOne.getId()); + + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, RECORD_FOLDER_TWO); + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, RecordCategoryTwo.getName()); + deleteRecordCategory(RecordCategoryTwo.getId()); + + dataSite.usingAdmin().deleteSite(privateSite); + dataSite.usingAdmin().deleteSite(testSite); + + UnfiledContainerChildCollection unfiledContainerChildCollection = getRestAPIFactory() + .getUnfiledContainersAPI().getUnfiledContainerChildren(unfiledContainer.getId()); + + unfiledContainerChildCollection.getEntries().forEach(unfiledChild -> + { + if (unfiledChild.getEntry().getIsRecord()) + { + getRestAPIFactory().getRecordsAPI().deleteRecord(unfiledChild.getEntry().getId()); + } + else + { + getRestAPIFactory().getUnfiledRecordFoldersAPI().deleteUnfiledRecordFolder(unfiledChild.getEntry().getId()); + } + }); + } +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java index 8a6a500e30..0968ba155b 100644 --- a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/DeleteRecordTests.java @@ -102,7 +102,7 @@ public class DeleteRecordTests extends BaseRMRestTest testSite = dataSite.usingAdmin().createPublicRandomSite(); recordFolder = createCategoryFolderInFilePlan(); unfiledRecordFolder = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, getRandomName("Unfiled Folder "), - UNFILED_RECORD_FOLDER_TYPE); + UNFILED_RECORD_FOLDER_TYPE); } /** Data provider with electronic and non-electronic records to be deleted */ @@ -133,10 +133,10 @@ public class DeleteRecordTests extends BaseRMRestTest * */ @Test - ( - dataProvider = "recordsToBeDeleted", - description = "Admin user can delete records" - ) + ( + dataProvider = "recordsToBeDeleted", + description = "Admin user can delete records" + ) @AlfrescoTest(jira="RM-4363") public void adminCanDeleteRecords(String recordId) { @@ -154,17 +154,17 @@ public class DeleteRecordTests extends BaseRMRestTest * */ @Test - ( - description = "User without write permissions can't delete a record" - ) + ( + description = "User without write permissions can't delete a record" + ) @AlfrescoTest(jira="RM-4363") public void userWithoutWritePermissionsCantDeleteRecord() { // Create a non-electronic record in unfiled records UnfiledContainerChild nonElectronicRecord = UnfiledContainerChild.builder() - .name("Record " + RandomData.getRandomAlphanumeric()) - .nodeType(NON_ELECTRONIC_RECORD_TYPE) - .build(); + .name("Record " + RandomData.getRandomAlphanumeric()) + .nodeType(NON_ELECTRONIC_RECORD_TYPE) + .build(); UnfiledContainerChild newRecord = getRestAPIFactory().getUnfiledContainersAPI().createUnfiledContainerChild(nonElectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS); assertStatusCode(CREATED); @@ -187,9 +187,9 @@ public class DeleteRecordTests extends BaseRMRestTest * */ @Test - ( - description = "User without delete records capability can't delete a record" - ) + ( + description = "User without delete records capability can't delete a record" + ) @AlfrescoTest(jira="RM-4363") public void userWithoutDeleteRecordsCapabilityCantDeleteRecord() { @@ -234,7 +234,7 @@ public class DeleteRecordTests extends BaseRMRestTest STEP("Create a record in first folder and copy it into second folder."); String recordId = getRestAPIFactory().getRecordFolderAPI() - .createRecord(createElectronicRecordModel(), recordFolder.getId(), getFile(IMAGE_FILE)).getId(); + .createRecord(createElectronicRecordModel(), recordFolder.getId(), getFile(IMAGE_FILE)).getId(); String copyId = copyNode(recordId, recordFolderB.getId()).getId(); assertStatusCode(CREATED); @@ -323,9 +323,9 @@ public class DeleteRecordTests extends BaseRMRestTest STEP("Execute the disposition schedule steps."); rmRolesAndActionsAPI.executeAction(getAdminUser().getUsername(), getAdminUser().getUsername(), recordFiled.getName(), - RM_ACTIONS.CUT_OFF); + RM_ACTIONS.CUT_OFF); rmRolesAndActionsAPI.executeAction(getAdminUser().getUsername(), getAdminUser().getUsername(), recordFiled.getName(), - RM_ACTIONS.DESTROY); + RM_ACTIONS.DESTROY); STEP("Check that it's possible to load the copy content."); getNodeContent(copy.getId()); @@ -348,14 +348,14 @@ public class DeleteRecordTests extends BaseRMRestTest STEP("Declare file version as record."); recordsAPI.declareDocumentVersionAsRecord(getAdminUser().getUsername(), getAdminUser().getPassword(), testSite.getId(), - testFile.getName()); + 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(); + .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()); diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/ShareRecordsTest.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/ShareRecordsTest.java new file mode 100644 index 0000000000..12495f12b4 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/records/ShareRecordsTest.java @@ -0,0 +1,128 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ + +package org.alfresco.rest.rm.community.records; + +import org.alfresco.dataprep.ContentService; +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.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordsAPI; +import org.alfresco.test.AlfrescoTest; +import org.apache.commons.httpclient.HttpStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import static org.alfresco.rest.core.v0.BaseAPI.RM_SITE_ID; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; + +/** + * Tests to cover share action for records + * @author Kavit Shah + */ +public class ShareRecordsTest extends BaseRMRestTest { + + /** data prep services*/ + @Autowired + private RecordsAPI service; + @Autowired + private ContentService contentService; + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + /** Constants*/ + private final String TEST_PREFIX = generateTestPrefix(ShareRecordsTest.class); + private final String CATEGORY = "CategoryWithSharedRecords" + TEST_PREFIX; + private final String FOLDER = "FolderWithSharedRecords" + TEST_PREFIX; + private final String ELECTRONIC_RECORD = "ELECTRONIC_RECORD" + TEST_PREFIX; + private final String NONELECTRONIC_REC = "NON_ELECTRONIC_RECORD" + TEST_PREFIX; + private RecordCategory category; + private RecordCategoryChild recordCategoryChild; + /** + * Given a record + * When admin tries to share it via API + * Then the record can't be shared + */ + @Test + @AlfrescoTest(jira = "RM-5308") + public void shareRecordViaApi() + { + //create RM Site + createRMSiteIfNotExists(); + + //create a category + category = createRootCategory(CATEGORY); + + //create folder + recordCategoryChild = createFolder(category.getId(),FOLDER); + + createNonElectronicRecord(recordCategoryChild.getId(),NONELECTRONIC_REC); + + // create record to be shared + createElectronicRecord(recordCategoryChild.getId(),ELECTRONIC_RECORD); + + //get the node id for the ELECTRONIC_RECORD created + String nodeRefRec1= contentService.getNodeRefByPath(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), + "/Sites/" + RM_SITE_ID + "/documentLibrary/" + CATEGORY + "/" + FOLDER + "/" + service.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, ELECTRONIC_RECORD)); + //check record can't be shared + assertFalse("The record has been succesfully shared", + service.shareDocument(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(),nodeRefRec1 ).getKey()); + //check the error code when trying to share a record + assertEquals("The API response code is not " + HttpStatus.SC_INTERNAL_SERVER_ERROR, service.shareDocument(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nodeRefRec1).getValue(), + String.valueOf( HttpStatus.SC_INTERNAL_SERVER_ERROR)); + + //get the node id for NONELECTRONIC_REC created + String nodeRefRec2 = contentService.getNodeRefByPath(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), + "/Sites/" + RM_SITE_ID + "/documentLibrary/" + CATEGORY + "/" + FOLDER + "/" + service.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), FOLDER, NONELECTRONIC_REC)); + //check record can't be shared + assertFalse("The record has been succesfully shared", + service.shareDocument(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nodeRefRec2).getKey()); + //check the error code when trying to share a record + assertEquals("The API response code is not " + HttpStatus.SC_INTERNAL_SERVER_ERROR, service.shareDocument(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nodeRefRec2).getValue(), + String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + } + + @AfterClass + public void cleanupCategory() { + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, recordCategoryChild.getName()); + rmRolesAndActionsAPI.deleteAllItemsInContainer(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), RM_SITE_ID, category.getName()); + deleteRecordCategory(category.getId()); + } +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DestroyRecordFolderActionsTest.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DestroyRecordFolderActionsTest.java new file mode 100644 index 0000000000..a3f35e5423 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DestroyRecordFolderActionsTest.java @@ -0,0 +1,121 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ +package org.alfresco.rest.rm.community.smoke; + +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.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordFoldersAPI; +import org.alfresco.rest.v0.service.DispositionScheduleService; +import org.alfresco.test.AlfrescoTest; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CREATED_DATE; +import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.CUT_OFF_DATE; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy; +import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.springframework.http.HttpStatus.OK; +import static org.testng.AssertJUnit.assertNotNull; + + +public class DestroyRecordFolderActionsTest extends BaseRMRestTest { + + private RecordCategory Category1,CATEGORY_TO_MOVE; + @Autowired + private DispositionScheduleService dispositionScheduleService; + @Autowired + private RecordFoldersAPI recordFoldersAPI; + private final String TEST_PREFIX = generateTestPrefix(DestroyRecordFolderActionsTest.class); + private final String folderDisposition = TEST_PREFIX + "RM-2937 folder ghosting"; + + + @BeforeClass(alwaysRun = true) + private void setUp(){ + + STEP("Create the RM site if doesn't exist"); + createRMSiteIfNotExists(); + + STEP("Create two record category"); + Category1 = createRootCategory(getRandomName("Category1")); + CATEGORY_TO_MOVE = createRootCategory(getRandomName("CATEGORY_TO_MOVE")); + + //create retention schedule + dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false); + + // add cut off step + dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE); + + // add destroy step with ghosting + dispositionScheduleService.addDestroyWithGhostingImmediatelyAfterCutOff(Category1.getName()); + + } + + @Test + @AlfrescoTest (jira = "RM-1621") + public void moveOnCutOffDestroyFolders() throws Exception { + + //create folders + RecordCategoryChild FOLDER_DESTROY = createFolder(getAdminUser(),Category1.getId(),folderDisposition); + + // edit disposition date + recordFoldersAPI.postFolderAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),FOLDER_DESTROY.getName()); + + // cut off the FOLDER_DESTROY + recordFoldersAPI.postFolderAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),FOLDER_DESTROY.getName()); + + + // Destroy the FOLDER_DESTROY + recordFoldersAPI.postFolderAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","destroy"),FOLDER_DESTROY.getName()); + + + //Move the FOLDER_DESTROY within the CATEGORY_TO_MOVE."); + getRestAPIFactory().getNodeAPI(toContentModel(FOLDER_DESTROY.getId())).move(createBodyForMoveCopy(CATEGORY_TO_MOVE.getId())); + assertStatusCode(OK); + + } + + @AfterMethod(alwaysRun = true) + private void deletePreconditions() { + + deleteRecordCategory(Category1.getId()); + deleteRecordCategory(CATEGORY_TO_MOVE.getId()); + + } + + } diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DispositionScheduleLinkedRecordsTest.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DispositionScheduleLinkedRecordsTest.java new file mode 100644 index 0000000000..7269bf0929 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/DispositionScheduleLinkedRecordsTest.java @@ -0,0 +1,425 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ +package org.alfresco.rest.rm.community.smoke; + +import org.alfresco.rest.core.v0.RMEvents; +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.fileplan.FilePlan; +import org.alfresco.rest.rm.community.model.record.Record; +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.user.UserRoles; +import org.alfresco.rest.v0.LinksAPI; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordFoldersAPI; +import org.alfresco.rest.v0.RecordsAPI; +import org.alfresco.rest.v0.service.DispositionScheduleService; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.model.RepoTestModel; +import org.alfresco.utility.model.UserModel; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.util.EntityUtils; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.alfresco.rest.core.v0.BaseAPI.NODE_REF_WORKSPACE_SPACES_STORE; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.CUT_OFF_ASPECT; +import static org.alfresco.rest.rm.community.model.recordcategory.RetentionPeriodProperty.*; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.springframework.http.HttpStatus.NO_CONTENT; + +public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest { + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + @Autowired + private DispositionScheduleService dispositionScheduleService; + @Autowired + private LinksAPI linksAPI; + @Autowired + private RecordsAPI recordsAPI; + @Autowired + private RecordFoldersAPI recordFoldersAPI; + private final static String TEST_PREFIX = generateTestPrefix(DispositionScheduleLinkedRecordsTest.class); + private RecordCategory Category1,catsameLevel1,catsameLevel2; + private RecordCategoryChild CopyCatFolder,folder1,CatFolder,folder2; + private static final String categoryRM3077 = TEST_PREFIX + "RM-3077_manager_sees_me"; + private static final String copyCategoryRM3077 = "Copy_of_" + categoryRM3077; + private static final String folderRM3077 = "RM-3077_folder_"+ categoryRM3077; + private static final String copyFolderRM3077 = "Copy_of_" + folderRM3077; + private final String electronicRecord = "RM-2937 electronic 2 record"; + private final String folder = TEST_PREFIX + "RM-2937 folder ghosting"; + private static final String categoryRecordsRM2526 = TEST_PREFIX + "RM-2526_category_records_immediately"; + private static final String category2RecordsRM2526 = TEST_PREFIX + "RM-2526_category_2_records_1_day"; + private static final String firstCategoryRM3060 = TEST_PREFIX + "RM-3060_category_record"; + private static final String secondCategoryRM3060 = "Copy_of_" + firstCategoryRM3060; + private static final String firstFolderRM3060 = TEST_PREFIX + "RM-3060_folder"; + private static final String secondFolderRM3060 = TEST_PREFIX + "RM-3060_disposition_on_Record_Level"; + private static final String electronicRecordRM3060 = TEST_PREFIX + "RM-3060_electronic_1_record"; + private static final String nonElectronicRecordRM3060 = TEST_PREFIX + "RM-3060_non-electronic_record"; + private static final String TRANSFER_LOCATION = TEST_PREFIX + "RM-3060_transferred_records"; + public static final String TRANSFER_TYPE = "rma:transferred"; + private FilePlan filePlanModel; + private UserModel rmAdmin, rmManager; + @BeforeClass(alwaysRun = true) + public void setupDispositionScheduleLinkedRecordsTest() { + createRMSiteIfNotExists(); + //get file plan + filePlanModel = getRestAPIFactory().getFilePlansAPI().getFilePlan(FILE_PLAN_ALIAS); + + // create "rm admin" user if it does not exist and assign it to RM Administrator role + rmAdmin = getDataUser().createRandomTestUser(); + rmRolesAndActionsAPI.assignRoleToUser(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(),rmAdmin.getUsername(), + UserRoles.ROLE_RM_ADMIN.roleId); + + // create "rm Manager" user if it does not exist and assign it to RM Administrator role + rmManager = getDataUser().createRandomTestUser(); + rmRolesAndActionsAPI.assignRoleToUser(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(),rmManager.getUsername(), + UserRoles.ROLE_RM_MANAGER.roleId); + } + /** + * Disposition Schedule on Record Folder with linked records test + *

+ * Precondition: + *

+ * Create rm_manager user that would have RM Managers role, rm_admin that would have RM Administrator role. + * Log in with admin user, create a category "manager sees me", give rm_manager read&file permission over it. + * Create a disposition schedule for it that would cut off folders after 1 day from created date. Copy the category. + *

+ *

TestRail Test C775

+ **/ + @Test + @AlfrescoTest(jira = "RM-1622") + public void dispositionScheduleLinkedRecords() throws UnsupportedEncodingException { + STEP("Create record category"); + Category1 = createRootCategory(categoryRM3077); + + //create retention schedule + dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false); + + // add cut off step + dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE); + + //create a copy of the category recordsCategory + String CopyCategoryId = copyCategory(getAdminUser(),Category1.getId(), copyCategoryRM3077); + + // create folders in both categories + CatFolder = createRecordFolder(Category1.getId(), folderRM3077); + CopyCatFolder = createRecordFolder(CopyCategoryId, copyFolderRM3077); + + // create record files + String electronicRecord = "RM-2801 electronic record"; + Record elRecord = createElectronicRecord(CatFolder.getId(), electronicRecord); + String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), electronicRecord); + + String nonElectronicRecord = "RM-2801 non-electronic record"; + Record nonElRecord = createNonElectronicRecord(CatFolder.getId(), nonElectronicRecord); + String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), nonElectronicRecord); + + // link the records to copy folder, then complete them + List recordLists = new ArrayList<>(); + recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + elRecord.getId()); + recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + nonElRecord.getId()); + + linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,copyCategoryRM3077 + "/" + + copyFolderRM3077, recordLists); + recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), elRecordFullName); + recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), nonElRecordFullName); + + // edit disposition date + recordFoldersAPI.postFolderAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),CatFolder.getName()); + + // cut off the Folder + recordFoldersAPI.postFolderAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),CatFolder.getName()); + + // Verify the Content + Node electronicNode = getNode(elRecord.getId()); + assertTrue("The content of " + electronicRecord + " is available", + StringUtils.isEmpty(electronicNode.getNodeContent().getResponse().getBody().asString())); + + // verify the Properties + AssertJUnit.assertNull("The properties are present even after cutting off the record.", elRecord.getProperties().getTitle()); + + // delete precondition + deleteRecordCategory(Category1.getId()); + deleteRecordCategory(CopyCategoryId); + } + /** + * Test covering RM-3060 + * Check the disposition steps for a record can be executed + * When the record is linked to a folder with the same disposition schedule + * */ + @Test + @AlfrescoTest (jira = "RM-3060") + public void sameDispositionScheduleLinkedRecords() throws UnsupportedEncodingException { + + // create a category with retention applied on records level + RecordCategory recordCategory = getRestAPIFactory().getFilePlansAPI(rmAdmin) + .createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(), + RecordCategory.DEFAULT_FILE_PLAN_ALIAS); + dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true); + dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "week|1", DATE_FILED); + dispositionScheduleService.addTransferAfterEventStep(firstCategoryRM3060, TRANSFER_LOCATION, RMEvents.CASE_CLOSED.getEventName()); + dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(firstCategoryRM3060, "week|1", CUT_OFF_DATE); + + // make a copy of the category created + String categorySecondId = copyCategory(getAdminUser(), recordCategory.getId(), secondCategoryRM3060); + + // create a folder on the category firstCategoryRM3060 with a complete electronic record + RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(recordCategory.getId(),firstFolderRM3060); + Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060); + + String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060); + String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060); + + recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), elRecordFullName); + + // create a folder on the category secondCategoryRM3060 with a non electronic record + RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(categorySecondId,secondFolderRM3060); + Record secondNonElectronicRecord = createNonElectronicRecord(secondFolderRecordCategoryChild.getId(),nonElectronicRecordRM3060); + + // link the nonElectronicRecordRM3060 to firstFolderRM3060 + List recordLists = new ArrayList<>(); + recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId()); + + linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" + + secondFolderRM3060, recordLists); + String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), secondFolderRM3060, secondNonElectronicRecord.getName()); + String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060); + + // complete records and cut them off + recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), nonElRecordFullName); + + // edit the disposition date + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef); + + // cut off the record + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef); + + //check the record is cut off + AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT)); + + // link the electronic record to secondFolderRM3060 + recordLists.clear(); + recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId()); + linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" + + secondFolderRM3060, recordLists); + + // edit the disposition date and cut off the record + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef); + + AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT)); + + // open the record and complete the disposition schedule event + rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(), + getAdminUser().getPassword(), elRecordFullName, RMEvents.CASE_CLOSED, Instant.now()); + rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(), + getAdminUser().getPassword(), nonElRecordFullName, RMEvents.CASE_CLOSED, Instant.now()); + + // transfer the files & complete transfers + HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060)); + + String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId); + + HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060)); + + String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId); + + AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully transferred", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE)); + AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully transferred.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE)); + + // edit the disposition date for nonElectronicRecordRM3060 & electronicRecordRM3060 + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef); + + // destroy nonElectronicRecordRM3060 & electronicRecordRM3060 records + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef); + + // check the file is not displayed + assertNull("The file " + nonElectronicRecordRM3060 + " has not been successfully destroyed.", secondNonElectronicRecord.getContent()); + assertNull("The file " + electronicRecordRM3060 + " has not been successfully destroyed.", firstElectronicRecord.getContent()); + + // delete precondition + deleteRecordCategory(recordCategory.getId()); + deleteRecordCategory(categorySecondId); + } + private String copyCategory(UserModel user, String categoryId, String copyName) { + RepoTestModel repoTestModel = new RepoTestModel() {}; + repoTestModel.setNodeRef(categoryId); + RestNodeModel restNodeModel; + + RestNodeBodyMoveCopyModel copyDestinationInfo = new RestNodeBodyMoveCopyModel(); + copyDestinationInfo.setTargetParentId(filePlanModel.getId()); + copyDestinationInfo.setName(copyName); + + try + { + restNodeModel = getRestAPIFactory().getNodeAPI(user, repoTestModel).copy(copyDestinationInfo); + } + catch (Exception e) + { + throw new RuntimeException("Problem copying category.", e); + } + return restNodeModel.getId(); + } + + private Node getNode(String recordId) + { + RepoTestModel repoTestModel = new RepoTestModel() {}; + repoTestModel.setNodeRef(recordId); + return getRestAPIFactory().getNodeAPI(repoTestModel); + } + + private String getTransferId(HttpResponse httpResponse,String nodeRef) { + HttpEntity entity = httpResponse.getEntity(); + String responseString = null; + try { + responseString = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + throw new RuntimeException(e); + } + JSONObject result = new JSONObject(responseString); + return result + .getJSONObject("results") + .get(nodeRef) + .toString(); + + } + + @Test + @AlfrescoTest(jira = "RM-1622") + public void sameLevelDispositionScheduleStepsPeriodsCalculation() throws Exception { + + // create a category with retention applied on records level + RecordCategory catsameLevel1 = getRestAPIFactory().getFilePlansAPI(rmAdmin) + .createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(), + RecordCategory.DEFAULT_FILE_PLAN_ALIAS); + RecordCategory catsameLevel2 = getRestAPIFactory().getFilePlansAPI(rmAdmin) + .createRootRecordCategory(RecordCategory.builder().name(secondCategoryRM3060).build(), + RecordCategory.DEFAULT_FILE_PLAN_ALIAS); + + // create retention schedule applied on records for category 1 + dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true); + + // with retain immediately after record creation date and cut 1 day after record creation date + dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "day|1", DATE_FILED); + + + // create a folder on the category firstCategoryRM3060 with a complete electronic record + RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(catsameLevel1.getId(),firstFolderRM3060); + Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060); + + String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060); + String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060); + + recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), elRecordFullName); + + // create a folder on the category secondCategoryRM3060 with a non electronic record + RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(catsameLevel2.getId(),secondFolderRM3060); + String elRecordNameNodeRefs = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060); + + + // link it to the folder in second category through the details page + List recordLists = new ArrayList<>(); + recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + firstElectronicRecord.getId()); + + linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(), + getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" + + secondFolderRM3060, recordLists); + + // edit disposition date + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRefs); + + + } + + @Test (dependsOnMethods = {"sameLevelDispositionScheduleStepsPeriodsCalculation" }) + public void deleteLongestPeriodTestPrecondition() { + // Delete the RM site + getRestAPIFactory().getRMSiteAPI().deleteRMSite(); + + // Verify the status code + assertStatusCode(NO_CONTENT); + } + } \ No newline at end of file diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/FileVersionAsRecordTests.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/FileVersionAsRecordTests.java new file mode 100644 index 0000000000..09600f9545 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/FileVersionAsRecordTests.java @@ -0,0 +1,138 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ + +package org.alfresco.rest.rm.community.smoke; + +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.recordfolder.RecordFolderCollection; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.rm.community.records.FileUnfiledRecordsTests; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordCategoriesAPI; +import org.alfresco.rest.v0.RecordsAPI; +import org.alfresco.rest.v0.service.RoleService; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.Utility; +import org.alfresco.utility.data.DataContent; +import org.alfresco.utility.data.DataSite; +import org.alfresco.utility.model.FileModel; +import org.alfresco.utility.model.FileType; +import org.alfresco.utility.model.SiteModel; +import org.alfresco.utility.model.UserModel; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.util.concurrent.atomic.AtomicReference; + +import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.data.RandomData.getRandomName; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.springframework.test.util.AssertionErrors.assertTrue; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; + +public class FileVersionAsRecordTests extends BaseRMRestTest { + + private UserModel nonRMuser,rmManager; + private SiteModel testSite; + private FileModel document, documentDeclared; + private RecordCategory category_manager, category_admin; + private RecordCategoryChild folder_admin, folder_manager ; + private static final String CATEGORY_MANAGER = "catManager" + generateTestPrefix(FileAsRecordTests.class); + private static final String CATEGORY_ADMIN = "catAdmin" + generateTestPrefix(FileAsRecordTests.class); + private static final String FOLDER_MANAGER = "recordFolder" + generateTestPrefix(FileAsRecordTests.class); + private static final String FOLDER_ADMIN = "recordFolder" + generateTestPrefix(FileAsRecordTests.class); + + @Autowired + private DataSite dataSite; + @Autowired + private DataContent dataContent; + @Autowired + private RoleService roleService; + + @BeforeClass(alwaysRun = true) + public void preconditionForFileVersionAsRecordTests() + { + STEP("Create the RM site if doesn't exist"); + createRMSiteIfNotExists(); + + STEP("Create a user"); + nonRMuser = dataUser.createRandomTestUser("testUser"); + + STEP("Create a collaboration site"); + testSite = dataSite.usingUser(nonRMuser).createPublicRandomSite(); + + STEP("Create a document with the user without RM role"); + document = dataContent.usingSite(testSite) + .usingUser(nonRMuser) + .createContent(CMISUtil.DocumentType.TEXT_PLAIN); + + STEP("Create two categories with two folders"); + category_manager = createRootCategory(CATEGORY_MANAGER); + category_admin = createRootCategory(CATEGORY_ADMIN); + folder_admin = createFolder(category_admin.getId(),FOLDER_ADMIN); + folder_manager = createFolder(category_manager.getId(),FOLDER_MANAGER); + + STEP("Create an rm user and give filling permission over CATEGORY_MANAGER record category"); + RecordCategory recordCategory = new RecordCategory().builder() + .id(category_manager.getId()) + .build(); + rmManager = roleService.createCollaboratorWithRMRoleAndPermission(testSite, recordCategory, + UserRoles.ROLE_RM_MANAGER, PERMISSION_FILING); + + } + + @Test + @AlfrescoTest (jira = "APPS-1625") + public void fileVersionAsRecordToUnfiledRecordContainer() throws Exception + { + + AtomicReference apiChildren = new AtomicReference<>(); + + STEP("Create a document with the user without RM role"); + FileModel inplaceRecord = dataContent.usingSite(testSite).usingUser(rmManager) + .createContent(new FileModel("declareAndFileToIntoUnfiledRecordFolder", + FileType.TEXT_PLAIN)); + + STEP("Click on Declare and file without selecting a record folder"); + getRestAPIFactory().getActionsAPI(rmManager).declareAndFile(inplaceRecord,""); + + STEP("Check the file is declared in unfiled record folder"); + Assert.assertTrue(isMatchingRecordInUnfiledRecords(inplaceRecord), "Record should be filed to Unfiled Records folder"); + + + } + + +} diff --git a/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/RecordRetentionAsOfDateTest.java b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/RecordRetentionAsOfDateTest.java new file mode 100644 index 0000000000..5427019983 --- /dev/null +++ b/amps/ags/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/smoke/RecordRetentionAsOfDateTest.java @@ -0,0 +1,156 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2022 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 . + * #L% + */ + +package org.alfresco.rest.rm.community.smoke; + +import org.alfresco.rest.core.v0.BaseAPI; +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.record.Record; +import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory; +import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild; +import org.alfresco.rest.v0.RMRolesAndActionsAPI; +import org.alfresco.rest.v0.RecordCategoriesAPI; +import org.alfresco.rest.v0.RecordFoldersAPI; +import org.alfresco.rest.v0.RecordsAPI; +import org.alfresco.rest.v0.service.DispositionScheduleService; +import org.alfresco.test.AlfrescoTest; +import org.apache.commons.lang3.time.DateUtils; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import static org.alfresco.rest.rm.community.base.TestData.DEFAULT_PASSWORD; +import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix; +import static org.alfresco.utility.report.log.Step.STEP; +import static org.testng.Assert.assertTrue; + +public class RecordRetentionAsOfDateTest extends BaseRMRestTest { + + /** data prep 6services */ + @Autowired + private RMRolesAndActionsAPI rmRolesAndActionsAPI; + @Autowired + private RecordsAPI recordsAPI; + @Autowired + private RecordFoldersAPI recordFoldersAPI; + @Autowired + private RecordCategoriesAPI recordCategoriesAPI; + @Autowired + private DispositionScheduleService dispositionScheduleService; + private RecordCategory Category1; + private final String TEST_PREFIX = generateTestPrefix(RecordRetentionAsOfDateTest.class); + private final String RM_ADMIN = TEST_PREFIX + "rm_admin"; + private final String recordsCategory = TEST_PREFIX + "RM-5733 category"; + private final String folderDisposition = TEST_PREFIX + "RM-5733 folder"; + + private static final String YEAR_MONTH_DAY = "yyyy-MM-dd"; + + @Test + @AlfrescoTest (jira = "RM-5733,RM-5799") + public void checkRetentionAsOfDateForTransferStepWithRetentionAction() { + + // create test precondition + createTestPrecondition(recordsCategory); + + // create disposition schedule + dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), true); + + // add cut off step + dispositionScheduleService.addCutOffImmediatelyStep(Category1.getName()); + + // add transfer step + HashMap transferStep = new HashMap<>(); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.RETENTION_PERIOD, "day|1"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.NAME, "transfer"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.RETENTION_PERIOD_PROPERTY, "rma:cutOffDate"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.COMBINE_DISPOSITION_STEP_CONDITIONS, "false"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.RETENTION_ELIGIBLE_FIRST_EVENT, "true"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.RETENTION_GHOST, "on"); + transferStep.put(BaseAPI.RETENTION_SCHEDULE.DESCRIPTION, "Transfer after 1 day"); + recordCategoriesAPI.addDispositionScheduleSteps(getAdminUser().getUsername(), + getAdminUser().getPassword(), Category1.getName(), transferStep); + + // create a folder and an electronic and a non-electronic record in it + RecordCategoryChild FOLDER = createFolder(getAdminUser(),Category1.getId(),folderDisposition); + + String nonElectronicRecord = TEST_PREFIX + "RM-5733 non-electronic record"; + Record nonElRecord = createNonElectronicRecord(FOLDER.getId(), nonElectronicRecord); + + // complete records and cut them off + String nonElRecordName = recordsAPI.getRecordFullName(getAdminUser().getUsername(), + getAdminUser().getPassword(), folderDisposition, nonElectronicRecord); + + // complete records and cut them off + completeRecord(nonElRecord.getId()); + + String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordName, "/" + Category1.getName() + "/" + folderDisposition); + recordFoldersAPI.postRecordAction(getAdminUser().getUsername(), + getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef); + + JSONObject nextDispositionActionJson = recordCategoriesAPI.getNextDispositionAction(getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(),nonElRecord.getId()); + + assertTrue(getAsOfDate(nextDispositionActionJson).startsWith(getTomorrow()), + "The retention as of date is not set to tomorrow."); + } + + @AfterClass(alwaysRun = true) + public void cleanUp() { + // delete category + deleteRecordCategory(Category1.getId()); + } + + private void createTestPrecondition(String categoryName) { + createRMSiteIfNotExists(); + + // create "rm admin" user if it does not exist and assign it to RM Administrator role + rmRolesAndActionsAPI.createUserAndAssignToRole( + getDataUser().usingAdmin().getAdminUser().getUsername(), + getDataUser().usingAdmin().getAdminUser().getPassword(), + RM_ADMIN, DEFAULT_PASSWORD, "Administrator"); + + // create category + STEP("Create category"); + Category1 = createRootCategory(categoryName,"Title"); + } + + private String getAsOfDate(JSONObject nextDispositionActionJson) { + return nextDispositionActionJson.getJSONObject("data").get("asOf").toString(); + } + + private static String getTomorrow() { + Date today = new Date(); + Date tomorrow = DateUtils.addDays(today, 1); + SimpleDateFormat dateFormat = new SimpleDateFormat(YEAR_MONTH_DAY); + return dateFormat.format(tomorrow); + } + +} \ No newline at end of file