Feature/apps 1613 (#1284)

* Adding test for the stage AGS Smoke UI Tests for actions in RM site

* pushed the createCategoriesTest in APPS-1550 brach

* pushed the createCategoriesTest in APPS-1550 branch

* pushed the CreateFoldersTests in APPS-1550 branch

* [ags]

* ~ /\[ags\]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Revert "~ /\[ags\]"

This reverts commit ed9443e5

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Adding FoldersDispositionScheduleTests

* Added foldersDispositionScheduleWithGhosting

* Added foldersDispositionScheduleWithoutGhosting

* Added RecordsDispositionScheduleTests and other fixes

* Added RecordsDispositionScheduleWithGhostingTests

* [ags api]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* Revert "[ags api]"

This reverts commit 2153eafc0f.

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* DispositionScheduleLinkedRecordsTest class added

* [ags]

* [ags]

* [ags]

* [ags]

* ags

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

* [ags]

Co-authored-by: sbisht <shishuraj.bisht@globallogic.com>
This commit is contained in:
kavitshah-gl
2022-09-15 10:51:52 +05:30
committed by GitHub
parent 2a48160442
commit 033a00075f
9 changed files with 1392 additions and 25 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<String> 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));
}
}

View File

@@ -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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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());
}
});
}
}

View File

@@ -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
* </pre>
*/
@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
* </pre>
*/
@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
* </pre>
*/
@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());

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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());
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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());
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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
* <p>
* Precondition:
* <p>
* 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.
* <p>
* <p/> TestRail Test C775<p/>
**/
@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<String> 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<String> 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<String> 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);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<RecordFolderCollection> 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");
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<BaseAPI.RETENTION_SCHEDULE, String> 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);
}
}