diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java index 8342ce9661..c74034ed5a 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponent.java @@ -85,6 +85,9 @@ public class FilePlanComponent @JsonProperty (value = ALLOWABLE_OPERATIONS) private List allowableOperations; + @JsonProperty (required = false) + private FilePlanComponentContent content; + private FilePlanComponentPath path; @JsonProperty (required = true) diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java new file mode 100644 index 0000000000..eb2f102266 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentContent.java @@ -0,0 +1,113 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 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; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * POJO for FilePlanComponent content field + * @author Kristijan Conkas + * @since 2.6 + */ +public class FilePlanComponentContent +{ + @JsonProperty (required = true) + private String encoding; + + @JsonProperty (required = true) + private String mimeType; + + @JsonProperty (required = true) + private String mimeTypeName; + + @JsonProperty (required = true) + private Integer sizeInBytes; + + /** + * @return the encoding + */ + public String getEncoding() + { + return this.encoding; + } + + /** + * @param encoding the encoding to set + */ + public void setEncoding(String encoding) + { + this.encoding = encoding; + } + + /** + * @return the mimeType + */ + public String getMimeType() + { + return this.mimeType; + } + + /** + * @param mimeType the mimeType to set + */ + public void setMimeType(String mimeType) + { + this.mimeType = mimeType; + } + + /** + * @return the mimeTypeName + */ + public String getMimeTypeName() + { + return this.mimeTypeName; + } + + /** + * @param mimeTypeName the mimeTypeName to set + */ + public void setMimeTypeName(String mimeTypeName) + { + this.mimeTypeName = mimeTypeName; + } + + /** + * @return the sizeInBytes + */ + public Integer getSizeInBytes() + { + return this.sizeInBytes; + } + + /** + * @param sizeInBytes the sizeInBytes to set + */ + public void setSizeInBytes(Integer sizeInBytes) + { + this.sizeInBytes = sizeInBytes; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java index 98f38afd36..11b14c1906 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentFields.java @@ -45,7 +45,17 @@ public class FilePlanComponentFields public static final String PROPERTIES_DESCRIPTION = "cm:description"; public static final String PROPERTIES_SUPPLEMENTAL_MARKING_LIST = "rmc:supplementalMarkingList"; public static final String ALLOWABLE_OPERATIONS = "allowableOperations"; - public static final String IS_CLOSED="isClosed"; - public static final String PROPERTIES_REVIEW_PERIOD="rma:reviewPeriod"; - public static final String PROPERTIES_LOCATION="rma:location"; + public static final String IS_CLOSED = "isClosed"; + public static final String PROPERTIES_REVIEW_PERIOD = "rma:reviewPeriod"; + public static final String PROPERTIES_LOCATION = "rma:location"; + public static final String PROPERTIES_IS_CLOSED = "rma:isClosed"; // not to be confused with IS_CLOSED! + + // for non-electronic records + public static final String PROPERTIES_BOX = "rma:box"; + public static final String PROPERTIES_FILE = "rma:file"; + public static final String PROPERTIES_NUMBER_OF_COPIES = "rma:numberOfCopies"; + public static final String PROPERTIES_PHYSICAL_SIZE = "rma:physicalSize"; + public static final String PROPERTIES_SHELF = "rma:shelf"; + public static final String PROPERTIES_STORAGE_LOCATION = "rma:storageLocation"; + } diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java index ab8fbcd253..9c17419680 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/model/fileplancomponents/FilePlanComponentProperties.java @@ -26,10 +26,16 @@ */ package org.alfresco.rest.rm.community.model.fileplancomponents; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_BOX; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FILE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HOLD_REASON; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IS_CLOSED; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_LOCATION; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_NUMBER_OF_COPIES; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PHYSICAL_SIZE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SHELF; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SUPPLEMENTAL_MARKING_LIST; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE; import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR; @@ -74,6 +80,25 @@ public class FilePlanComponentProperties @JsonProperty(PROPERTIES_LOCATION) private String location; + + @JsonProperty(value = PROPERTIES_IS_CLOSED, required = false) + private Boolean isClosed; + + @JsonProperty(value = PROPERTIES_BOX, required = false) + private String box; + + @JsonProperty(value = PROPERTIES_FILE, required = false) + private String file; + + @JsonProperty(value = PROPERTIES_SHELF, required = false) + private String shelf; + + @JsonProperty(value = PROPERTIES_NUMBER_OF_COPIES, required = false) + private Integer numberOfCopies; + + @JsonProperty(value = PROPERTIES_PHYSICAL_SIZE, required = false) + private Integer physicalSize; + public FilePlanComponentProperties(String title, String description) { @@ -203,4 +228,99 @@ public class FilePlanComponentProperties this.location = location; } + /** + * @return the box + */ + public String getBox() + { + return this.box; + } + + /** + * @param box the box to set + */ + public void setBox(String box) + { + this.box = box; + } + + /** + * @return the file + */ + public String getFile() + { + return this.file; + } + + /** + * @param file the file to set + */ + public void setFile(String file) + { + this.file = file; + } + + /** + * @return the shelf + */ + public String getShelf() + { + return this.shelf; + } + + /** + * @param shelf the shelf to set + */ + public void setShelf(String shelf) + { + this.shelf = shelf; + } + + /** + * @return the numberOfCopies + */ + public Integer getNumberOfCopies() + { + return this.numberOfCopies; + } + + /** + * @param numberOfCopies the numberOfCopies to set + */ + public void setNumberOfCopies(Integer numberOfCopies) + { + this.numberOfCopies = numberOfCopies; + } + + /** + * @return the physicalSize + */ + public Integer getPhysicalSize() + { + return this.physicalSize; + } + + /** + * @param physicalSize the physicalSize to set + */ + public void setPhysicalSize(Integer physicalSize) + { + this.physicalSize = physicalSize; + } + + /** + * @return the isClosed + */ + public Boolean getIsClosed() + { + return this.isClosed; + } + + /** + * @param isClosed the isClosed to set + */ + public void setIsClosed(Boolean isClosed) + { + this.isClosed = isClosed; + } } 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 1308a68295..4398087e56 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 @@ -46,7 +46,8 @@ public enum FilePlanComponentType TRANSFER_CONTAINER_TYPE("rma:transferContainer"), UNFILED_CONTAINER_TYPE("rma:unfiledRecordContainer"), FOLDER_TYPE("cm:folder"), - CONTENT_TYPE("cm:content"); + CONTENT_TYPE("cm:content"), + NON_ELECTRONIC_RECORD_TYPE("rma:nonElectronicDocument"); private String type; diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java index 0ba49263ab..f90d9e767c 100644 --- a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/rm/community/requests/FilePlanComponentAPI.java @@ -123,8 +123,9 @@ public class FilePlanComponentAPI extends RestAPI return usingRestWrapper().processModel(FilePlanComponent.class, requestWithBody( POST, toJson(filePlanComponentModel), - "fileplan-components/{fileplanComponentId}/children", - parentId + "fileplan-components/{fileplanComponentId}/children?{parameters}", + parentId, + getParameters() )); } @@ -152,8 +153,9 @@ public class FilePlanComponentAPI extends RestAPI return usingRestWrapper().processModel(FilePlanComponent.class, requestWithBody( PUT, toJson(filePlanComponent), - "fileplan-components/{fileplanComponentId}", - filePlanComponentId + "fileplan-components/{fileplanComponentId}?{parameters}", + filePlanComponentId, + getParameters() )); } diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java index 7eade80baa..3fa9973b24 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/base/BaseRestTest.java @@ -35,6 +35,7 @@ import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanCo import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE; import static org.alfresco.rest.rm.community.model.site.RMSiteCompliance.STANDARD; import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; import com.jayway.restassured.RestAssured; @@ -83,7 +84,7 @@ public class BaseRestTest extends RestTest @Autowired private RMSiteAPI rmSiteAPI; - + @Autowired private DataUser dataUser; @@ -190,4 +191,25 @@ public class BaseRestTest extends RestTest return fpc; } + /** + * Helper method to close folder + * @param folderToClose + * @return + * @throws Exception + */ + public FilePlanComponent closeFolder(String folderId) throws Exception + { + RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // build fileplan component + properties for update request + FilePlanComponentProperties properties = new FilePlanComponentProperties(); + properties.setIsClosed(true); + FilePlanComponent filePlanComponent = new FilePlanComponent(); + filePlanComponent.setProperties(properties); + + FilePlanComponent updatedComponent = filePlanComponentAPI.updateFilePlanComponent(filePlanComponent, folderId); + restWrapper.assertStatusCodeIs(OK); + return updatedComponent; + } + } \ 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/NonElectronicRecordTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java new file mode 100644 index 0000000000..69c197ea90 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/NonElectronicRecordTests.java @@ -0,0 +1,415 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 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 java.util.Arrays.asList; + +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; +import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE; +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.util.PojoUtility.toJson; +import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; + +import java.util.Random; + +import org.alfresco.rest.rm.community.base.BaseRestTest; +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.FilePlanComponentAPI; +import org.alfresco.rest.rm.community.requests.RMSiteAPI; +import org.alfresco.utility.constants.UserRole; +import org.alfresco.utility.data.DataUser; +import org.alfresco.utility.model.SiteModel; +import org.alfresco.utility.model.UserModel; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Create/File Non-Electronic Record into Unfiled Record Container/Record Folder ReST API tests + * + * @author Kristijan Conkas + * @since 2.6 + */ +public class NonElectronicRecordTests extends BaseRestTest +{ + @Autowired + private FilePlanComponentAPI filePlanComponentAPI; + + @Autowired + private DataUser dataUser; + + @Autowired + private RMSiteAPI rmSiteAPI; + + /** Valid root containers where non-electronic records can be created */ + @DataProvider(name = "validContainers") + public Object[][] rootContainers() throws Exception { + return new Object[][] { + // an arbitrary record folder + { createFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()) }, + // unfiled records root + { filePlanComponentAPI.getFilePlanComponent(UNFILED_RECORDS_CONTAINER_ALIAS.toString()) }, + // an arbitrary unfiled records folder + { createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS.toString(), "Unfiled Folder " + getRandomAlphanumeric()) } + }; + } + + /** + *
+     * Given a parent container that is NOT a record folder or an unfiled record folder
+     * When I try to create a non-electronic record within the parent container
+     * Then nothing happens
+     * And an error is reported
+     * 
+ * @throws Exception if prerequisites can't be created + */ + @Test(description = "Non-electronic record can't be created as a child of invalid parent Id") + public void cantCreateForInvalidParentIds() throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // non-electronic record object to be used for create tests + FilePlanComponent nonElectronicRecord = new FilePlanComponent( + "Record " + getRandomAlphanumeric(), + NON_ELECTRONIC_RECORD_TYPE.toString(), + new FilePlanComponentProperties()); + + // create record category, non-electronic records can't be its children + FilePlanComponent recordCategory = filePlanComponentAPI.createFilePlanComponent( + new FilePlanComponent("Category " + getRandomAlphanumeric(), + RECORD_CATEGORY_TYPE.toString(), + new FilePlanComponentProperties()), + FILE_PLAN_ALIAS.toString()); + + // iterate through all invalid parent containers and try to create/file an electronic record + asList(FILE_PLAN_ALIAS.toString(), TRANSFERS_ALIAS.toString(), HOLDS_ALIAS.toString(), recordCategory.getId()) + .stream() + .forEach(id -> + { + try + { + filePlanComponentAPI.createFilePlanComponent(nonElectronicRecord, id); + } + catch (Exception error) + { + } + + // Verify the status code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY); + }); + } + + /** + *
+     * Given a parent container that is a record folder
+     * And the record folder is open
+     * When I try to create a non-electronic record within the parent container
+     * Then the non-electronic record is created
+     * And the details of the new record are returned
+     * 
+     * and
+     * 
+     * Given a parent container that is an unfiled record folder or the root unfiled record container
+     * When I try to create a non-electronic record within the parent container
+     * Then the non-electronic record is created
+     * And the details of the new record are returned
+     * 
+ * @throws Exception if record can't be created + */ + @Test + ( + dataProvider = "validContainers", + description = "Non-electronic records can be created in valid containers" + ) + public void canCreateInValidContainers(FilePlanComponent container) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + logger.info("Root container:\n" + toJson(container)); + if (container.getNodeType().equals(RECORD_FOLDER_TYPE.toString())) + { + // only record folders can be open or closed + assertFalse(container.getProperties().getIsClosed()); + } + + // use these properties for non-electronic record to be created + String title = "Title " + getRandomAlphanumeric(); + String description = "Description " + getRandomAlphanumeric(); + String box = "Box "+ getRandomAlphanumeric(); + String file = "File " + getRandomAlphanumeric(); + String shelf = "Shelf " + getRandomAlphanumeric(); + String location = "Location " + getRandomAlphanumeric(); + + Random random = new Random(); + Integer copies = random.nextInt(Integer.MAX_VALUE); + Integer size = random.nextInt(Integer.MAX_VALUE); + + // set values of all available properties + FilePlanComponentProperties properties = new FilePlanComponentProperties(title, description); + properties.setBox(box); + properties.setFile(file); + properties.setShelf(shelf); + properties.setLocation(location); + properties.setNumberOfCopies(copies); + properties.setPhysicalSize(size); + + // create non-electronic record + String nonElectronicId = filePlanComponentAPI.createFilePlanComponent( + new FilePlanComponent("Record " + getRandomAlphanumeric(), + NON_ELECTRONIC_RECORD_TYPE.toString(), + properties), + container.getId()).getId(); + + // verify the create request status code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + + // get newly created non-electonic record and verify its properties + FilePlanComponent nonElectronicRecord = filePlanComponentAPI.getFilePlanComponent(nonElectronicId); + + assertEquals(title, nonElectronicRecord.getProperties().getTitle()); + assertEquals(description, nonElectronicRecord.getProperties().getDescription()); + assertEquals(box, nonElectronicRecord.getProperties().getBox()); + assertEquals(file, nonElectronicRecord.getProperties().getFile()); + assertEquals(shelf, nonElectronicRecord.getProperties().getShelf()); + assertEquals(location, nonElectronicRecord.getProperties().getLocation()); + assertEquals(copies, nonElectronicRecord.getProperties().getNumberOfCopies()); + assertEquals(size, nonElectronicRecord.getProperties().getPhysicalSize()); + } + + /** + *
+     * Given a parent container that is a record folder
+     * And the record folder is closed 
+     * When I try to create a non-electronic record within the parent container
+     * Then nothing happens
+     * And an error is reported
+     * 
+ * @throws Exception if prerequisites can't be created + */ + @Test(description = "Non-electronic record can't be created in closed record folder") + public void cantCreateInClosedFolder() throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + FilePlanComponent recordFolder = createFolderInFilePlan(dataUser.getAdminUser(), FILE_PLAN_ALIAS.toString()); + + // the folder should be open + assertFalse(recordFolder.getProperties().getIsClosed()); + + // close the folder + closeFolder(recordFolder.getId()); + + // try to create it, this should fail and throw an exception + + filePlanComponentAPI.createFilePlanComponent( + new FilePlanComponent("Record " + getRandomAlphanumeric(), + NON_ELECTRONIC_RECORD_TYPE.toString(), + new FilePlanComponentProperties()), + recordFolder.getId()).getId(); + + // verify the status code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(UNPROCESSABLE_ENTITY); + } + + /** + *
+     * Given a parent container that is a record folder
+     * And the record folder is open
+     * When I try to create a non-electronic record within the parent container
+     * And I do not provide all the required mandatory property values
+     * Then nothing happens
+     * And an error is reported
+     * 
+ * and + *
+     * Given a parent container that is an unfiled record folder or the root unfiled record container
+     * When I try to create a non-electronic record within the parent container
+     * And I do not provide all the required mandatory property values
+     * Then nothing happens
+     * And an error is reported
+     * 
+ * @throws Exception if prerequisites can't be created + */ + @Test + ( + dataProvider = "validContainers", + description = "Non-electronic record can only be created if all mandatory properties are given" + ) + public void allMandatoryPropertiesRequired(FilePlanComponent container) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + logger.info("Root container:\n" + toJson(container)); + if (container.getNodeType().equals(RECORD_FOLDER_TYPE.toString())) + { + // only record folders can be open or closed + assertFalse(container.getProperties().getIsClosed()); + } + + // component without name and title + FilePlanComponent noNameOrTitle = getDummyNonElectronicRecord(); + + // component with title only + FilePlanComponent titleOnly = getDummyNonElectronicRecord(); + FilePlanComponentProperties properties = new FilePlanComponentProperties(); + properties.setTitle("Title " + getRandomAlphanumeric()); + titleOnly.setProperties(properties); + + // try to create invalid components + asList(noNameOrTitle, titleOnly).stream().forEach(c -> + { + try + { + logger.info("Creating non-electronic record with body:\n" + toJson(c)); + } + catch (Exception error) + { + } + + // this should fail and throw an exception + try + { + filePlanComponentAPI.createFilePlanComponent(c, container.getId()); + } + catch (Exception e) + { + } + + // verify the status code is BAD_REQUEST + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(BAD_REQUEST); + }); + } + + /** + *
+     * Given that I am a user without RM privileges
+     * When I try to create a non-electronic record
+     * Then nothing happens
+     * And an error is reported
+     * 
+ * @throws Exception + */ + @Test + ( + dataProvider = "validContainers", + description = "Non-electronic record can't be created if user doesn't have RM privileges" + ) + public void cantCreateIfNoRmPrivileges(FilePlanComponent container) throws Exception + { + String username = "zzzuser"; + UserModel user = createUserWithRole(username, UserRole.SiteManager); + + filePlanComponentAPI.usingRestWrapper().authenticateUser(user); + + // try to create a fileplan component + FilePlanComponent record = new FilePlanComponent("Record Name", NON_ELECTRONIC_RECORD_TYPE.toString(), + new FilePlanComponentProperties("Name", "Title")); + + // this should fail and throw an exception + try + { + filePlanComponentAPI.createFilePlanComponent(record, container.getId()); + } + catch (Exception e) + { + } + + // user who isn't an RM site member can't access the container path + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + + /** + * Helper function to return an empty FilePlanComponent for non-electronic record + * @return + */ + private FilePlanComponent getDummyNonElectronicRecord() + { + FilePlanComponent component = new FilePlanComponent(); + component.setNodeType(NON_ELECTRONIC_RECORD_TYPE.toString()); + return component; + } + + /** + * Helper method to create a randomly-named / structure in fileplan + * @return record folder + * @throws Exception on failed creation + */ + private FilePlanComponent createFolderInFilePlan(UserModel user, String parentId) throws Exception + { + filePlanComponentAPI.usingRestWrapper().authenticateUser(user); + + // create root category + FilePlanComponent recordCategory = createCategory(parentId, "Category " + getRandomAlphanumeric()); + + // and return a folder underneath + return createFolder(recordCategory.getId(), "Folder " + getRandomAlphanumeric()); + } + + /** + * Create user with given role and add it to RM site + *
+ * Checks whether the user exists in RM site and creates it if required, with password identical + * to username. Note the role is a Core API role, not an RM role. + *
+ * For already existing users, no site membership or role verification is performed. + *

+ * @param userName username to add + * @param userRole user's role + * @throws Exception + */ + private UserModel createUserWithRole(String userName, UserRole userRole) throws Exception + { + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + String siteId = rmSiteAPI.getSite().getId(); + + // check if user exists + UserModel user = new UserModel(); + user.setUsername(userName); + user.setPassword(userName); + + if (!dataUser.isUserInRepo(userName)) + { + // user doesn't exist, create it + user = dataUser.createUser(userName, userName); + user.setUserRole(userRole); + + dataUser.addUserToSite(user, new SiteModel(siteId), userRole); + } + + return user; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java index d074f1c8e8..74e669d8ce 100644 --- a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/rm/community/fileplancomponents/UnfiledRecordsFolderTests.java @@ -100,7 +100,7 @@ public class UnfiledRecordsFolderTests extends BaseRestTest public void createRootUnfiledRecordsFolder() throws Exception { // Authenticate with admin user - RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); String folderName = "Folder " + getRandomAlphanumeric(); String folderTitle = folderName + " Title"; @@ -142,7 +142,7 @@ public class UnfiledRecordsFolderTests extends BaseRestTest ) public void onlyRecordFoldersCanBeCreatedAtUnfiledRecordsRoot(FilePlanComponentType componentType) { - RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); String folderName = "Folder " + getRandomAlphanumeric(); String folderTitle = folderName + " Title";