diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentAspects.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentAspects.java new file mode 100644 index 0000000000..7d564ff187 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentAspects.java @@ -0,0 +1,39 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2017 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.model.fileplancomponents; + +/** + * File plan component aspect names constants + * + * @author Kristijan Conkas + * @since 2.6 + */ +public class FilePlanComponentAspects +{ + // aspect present on closed records + public static final String ASPECTS_CLOSED_RECORD = "rma:declaredRecord"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentType.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentType.java index 9af5f106e9..82e89de568 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentType.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentType.java @@ -37,6 +37,7 @@ public class FilePlanComponentType public static final String FILE_PLAN_TYPE = "rma:filePlan"; public static final String RECORD_CATEGORY_TYPE = "rma:recordCategory"; public static final String RECORD_FOLDER_TYPE = "rma:recordFolder"; + public static final String RECORD_TYPE = "rma:record"; // generic record type public static final String HOLD_TYPE = "rma:hold"; public static final String UNFILED_RECORD_FOLDER_TYPE = "rma:unfiledRecordFolder"; public static final String HOLD_CONTAINER_TYPE = "rma:holdContainer"; diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/igCoreAPI/RecordsAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/igCoreAPI/RecordsAPI.java index 8ad7e6a012..1036bc25fb 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/igCoreAPI/RecordsAPI.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/igCoreAPI/RecordsAPI.java @@ -78,6 +78,7 @@ public class RecordsAPI extends RMModelRequest *
  • {@code recordId} does not exist
  • * */ + //FIXME Add a generic method to support retrieving binary content public T getRecordContentText(String recordId) throws Exception { mandatoryString("recordId", recordId); @@ -105,6 +106,8 @@ public class RecordsAPI extends RMModelRequest *
  • {@code recordId} does not exist
  • * */ + //FIXME Add a generic method to support retrieving binary content as we might end up + //FIXME with too many methods for differents content types public RestHtmlResponse getRecordContent(String recordId) throws Exception { mandatoryString("recordId", recordId); diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java index cc1db1e740..2309640651 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRMRestTest.java @@ -30,19 +30,26 @@ import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_TITLE; import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.ASPECTS_CLOSED_RECORD; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_TYPE; import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createFilePlanComponentModel; import static org.alfresco.rest.rm.community.utils.RMSiteUtil.createStandardRMSiteModel; import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; import static org.springframework.http.HttpStatus.CREATED; import static org.springframework.http.HttpStatus.OK; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.util.List; import org.alfresco.rest.RestTest; import org.alfresco.rest.core.RestAPIFactory; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties; +import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI; import org.alfresco.rest.rm.community.requests.igCoreAPI.RMSiteAPI; import org.alfresco.utility.data.DataUser; import org.alfresco.utility.model.UserModel; @@ -272,6 +279,31 @@ public class BaseRMRestTest extends RestTest return updatedComponent; } + /** + * Helper method to close record + * + * @param recordToClose Record to close + * @return The closed record + * @throws Exception + */ + public FilePlanComponent closeRecord(FilePlanComponent recordToClose) throws Exception + { + FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI(); + List aspects = filePlanComponentsAPI.getFilePlanComponent(recordToClose.getId()).getAspectNames(); + // this operation is only valid for records + assertTrue(aspects.contains(RECORD_TYPE)); + // a record mustn't be closed + assertFalse(aspects.contains(ASPECTS_CLOSED_RECORD)); + + // add closed record aspect + aspects.add(ASPECTS_CLOSED_RECORD); + + FilePlanComponent updatedComponent = filePlanComponentsAPI.updateFilePlanComponent(FilePlanComponent.builder().aspectNames(aspects).build(), + recordToClose.getId()); + assertStatusCode(OK); + return updatedComponent; + } + /** * Helper method to create a randomly-named / structure in file plan * @@ -326,4 +358,4 @@ public class BaseRMRestTest extends RestTest return getFilePlanComponentAsUser(getAdminUser(), componentId); } -} \ No newline at end of file +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UpdateRecordsTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UpdateRecordsTests.java new file mode 100644 index 0000000000..e2738c2fca --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UpdateRecordsTests.java @@ -0,0 +1,258 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2017 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.fileplancomponents; + +import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE; +import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel; +import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; +import static org.testng.Assert.assertEquals; + +import java.util.Arrays; + +import org.alfresco.rest.rm.community.base.BaseRMRestTest; +import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties; +import org.alfresco.rest.rm.community.model.user.UserPermissions; +import org.alfresco.rest.rm.community.model.user.UserRoles; +import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI; +import org.alfresco.rest.rm.community.requests.igCoreAPI.RMUserAPI; +import org.alfresco.test.AlfrescoTest; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.model.SiteModel; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.Test; + +/** + * Update records tests + *
    + * These tests only test the update of electronic and non-electronic tests + *

    + * @author Kristijan Conkas + * @since 2.6 + */ +public class UpdateRecordsTests extends BaseRMRestTest +{ + @Autowired + private RMUserAPI rmUserAPI; + + /* to be used to append to modifications */ + private final String MODIFIED_PREFIX = "modified_"; + + /** + *

    +     * Given an incomplete record
    +     * When I try to update the records meta-data
    +     * Then the record is successfully updated
    +     * 
    + * @throws Exception + */ + @Test + ( + dataProvider = "validRootContainers", + description = "Incomplete records can be updated" + ) + @AlfrescoTest(jira="RM-4362") + public void incompleteRecordsCanBeUpdated(FilePlanComponent recordFolder) throws Exception + { + FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI(); + + // create electronic and non-electronic records in a folder + FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, recordFolder.getId()); + assertStatusCode(CREATED); + FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), recordFolder.getId()); + assertStatusCode(CREATED); + + for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) { + // generate update metadata + String newName = getModifiedPropertyValue(record.getName()); + String newTitle = getModifiedPropertyValue(record.getProperties().getTitle()); + String newDescription = getModifiedPropertyValue(record.getProperties().getDescription()); + + FilePlanComponent updateRecord = FilePlanComponent.builder() + .name(newName) + .properties(FilePlanComponentProperties.builder() + .description(newDescription) + .title(newTitle) + .build()) + .build(); + + // update record + filePlanComponentsAPI.updateFilePlanComponent(updateRecord, record.getId()); + assertStatusCode(OK); + + // verify the update got applied + FilePlanComponent updatedRecord = filePlanComponentsAPI.getFilePlanComponent(record.getId()); + assertEquals(updatedRecord.getName(), newName); + assertEquals(updatedRecord.getProperties().getTitle(), newTitle); + assertEquals(updatedRecord.getProperties().getDescription(), newDescription); + } + } + + /** + *
    +     * Given an incomplete record
    +     * And that I am a non-admin user with metadata update capabilities
    +     * When I try to update the records meta-data
    +     * Then the record is successfully updated
    +     * 
    + * @throws Exception + */ + @Test + ( + description = "User with Edit Metadata capabilities can update incomplete record's metadata" + ) + @AlfrescoTest(jira="RM-4362") + public void userWithEditMetadataCapsCanUpdateMetadata() throws Exception + { + // create test user and add it with collab. privileges + UserModel updateUser = getDataUser().createRandomTestUser("updateuser"); + updateUser.setUserRole(UserRole.SiteCollaborator); + getDataUser().addUserToSite(updateUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), UserRole.SiteCollaborator); + + // RM Security Officer is the lowest role with Edit Record Metadata capabilities + rmUserAPI.assignRoleToUser(updateUser.getUsername(), UserRoles.ROLE_RM_SECURITY_OFFICER); + rmUserAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // create random folder + FilePlanComponent randomFolder = createCategoryFolderInFilePlan(); + logger.info("random folder:" + randomFolder.getName()); + + // grant updateUser Filing privileges on randomFolder category, this will be + // inherited to randomFolder + FilePlanComponentAPI filePlanComponentsAPIAsAdmin = getRestAPIFactory().getFilePlanComponentsAPI(); + rmUserAPI.addUserPermission(filePlanComponentsAPIAsAdmin.getFilePlanComponent(randomFolder.getParentId()), + updateUser, UserPermissions.PERMISSION_FILING); + rmUserAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // create electronic and non-electronic records in a folder + FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI(); + FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, randomFolder.getId()); + assertStatusCode(CREATED); + FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), randomFolder.getId()); + assertStatusCode(CREATED); + + // get FilePlanComponentAPI instance initialised to updateUser + FilePlanComponentAPI filePlanComponentsAPIAsUser = getRestAPIFactory().getFilePlanComponentsAPI(updateUser); + + for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) { + filePlanComponentsAPIAsUser.getFilePlanComponent(record.getId()); + assertStatusCode(OK); + + // generate update metadata + String newName = getModifiedPropertyValue(record.getName()); + String newTitle = getModifiedPropertyValue(record.getProperties().getTitle()); + String newDescription = getModifiedPropertyValue(record.getProperties().getDescription()); + + FilePlanComponent updateRecord = FilePlanComponent.builder() + .name(newName) + .properties(FilePlanComponentProperties.builder() + .description(newDescription) + .title(newTitle) + .build()) + .build(); + + // update record + filePlanComponentsAPIAsUser.updateFilePlanComponent(updateRecord, record.getId()); + assertStatusCode(OK); + + // verify the update got applied + FilePlanComponent updatedRecord = filePlanComponentsAPIAsUser.getFilePlanComponent(record.getId()); + assertEquals(updatedRecord.getName(), newName); + assertEquals(updatedRecord.getProperties().getTitle(), newTitle); + assertEquals(updatedRecord.getProperties().getDescription(), newDescription); + assertEquals(updatedRecord.getModifiedByUser().getId(), updateUser.getUsername()); + } + } + + /** + *
    +     * Given a complete record
    +     * When I try to update the records meta-data
    +     * Then it fails
    +     * And and the records meta-data is unchanged
    +     * 
    + * @throws Exception + */ + @Test + ( + dataProvider = "validRootContainers", + description = "Complete records can't be updated" + ) + @AlfrescoTest(jira="RM-4362") + public void completeRecordsCantBeUpdated(FilePlanComponent recordFolder) throws Exception + { + FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI(); + + // create electronic and non-electronic records in a folder + FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, recordFolder.getId()); + assertStatusCode(CREATED); + closeRecord(electronicRecord); + + FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), recordFolder.getId()); + assertStatusCode(CREATED); + closeRecord(nonElectronicRecord); + + for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) { + // generate update metadata + String newName = getModifiedPropertyValue(record.getName()); + String newTitle = getModifiedPropertyValue(record.getProperties().getTitle()); + String newDescription = getModifiedPropertyValue(record.getProperties().getDescription()); + + FilePlanComponent updateRecord = FilePlanComponent.builder() + .name(newName) + .properties(FilePlanComponentProperties.builder() + .description(newDescription) + .title(newTitle) + .build()) + .build(); + + // attempt to update record + filePlanComponentsAPI.updateFilePlanComponent(updateRecord, record.getId()); + assertStatusCode(BAD_REQUEST); + + // verify the original record metatada has been retained + FilePlanComponent updatedRecord = filePlanComponentsAPI.getFilePlanComponent(record.getId()); + assertEquals(updatedRecord.getName(), record.getName()); + assertEquals(updatedRecord.getProperties().getTitle(), record.getProperties().getTitle()); + assertEquals(updatedRecord.getProperties().getDescription(), record.getProperties().getTitle()); + } + } + + /** + * Helper method to generate modified property value based on original value + * @param originalValue original value + * @return modified value + */ + private String getModifiedPropertyValue(String originalValue) + { + return MODIFIED_PREFIX + originalValue; + } +}