diff --git a/rm-automation/pom.xml b/rm-automation/pom.xml index 70f2b10f0e..5b63c34b46 100644 --- a/rm-automation/pom.xml +++ b/rm-automation/pom.xml @@ -1,9 +1,9 @@ - - + 4.0.0 alfresco-rm-automation Alfresco Records Management Automation + pom org.alfresco @@ -11,43 +11,20 @@ 2.6-SNAPSHOT - - 2.45.0 - 4.0.5.RELEASE - 1.8 - testng.xml - true - + + + LGPL 3 + + + + + rm-automation-community-rest-api + rm-automation-enterprise-rest-api + rm-automation-ui + - - org.codehaus.mojo - build-helper-maven-plugin - - - add-test-source - - add-test-source - - - - src/unit-test/java - - - - - - - maven-surefire-plugin - - false - - ${project.build.testOutputDirectory}/${suiteXmlFile} - - ${skip.automationtests} - - maven-antrun-plugin @@ -64,15 +41,6 @@ - - org.codehaus.mojo - license-maven-plugin - - alfresco_enterprise - file:${project.parent.basedir}/license - ${project.parent.basedir}/license/description.ftl - - @@ -104,88 +72,6 @@ - - - org.alfresco.test - dataprep - 1.8 - - - org.alfresco.test - alfresco-testng - 1.1 - - - org.alfresco - selenium-grid - 1.8 - - - org.springframework - spring-beans - ${spring.version} - - - org.springframework - spring-core - ${spring.version} - - - org.springframework - spring-context - ${spring.version} - - - org.springframework - spring-tx - ${spring.version} - test - - - org.springframework - spring-test - ${spring.version} - test - - - org.testng - testng - 6.8.8 - - - ru.yandex.qatools.htmlelements - htmlelements-all - 1.15 - - - ru.yandex.qatools.properties - properties-loader - 1.5 - test - - - com.github.tomakehurst - wiremock - 1.56 - - - org.mockito - mockito-all - test - - - org.slf4j - slf4j-log4j12 - test - - - org.slf4j - jul-to-slf4j - 1.7.21 - test - - - install-alfresco diff --git a/rm-automation/rm-automation-community-rest-api/.gitignore b/rm-automation/rm-automation-community-rest-api/.gitignore new file mode 100644 index 0000000000..d1a4acb433 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/.gitignore @@ -0,0 +1,8 @@ +/target/ +/.settings/ +.classpath +.project +/src/test/resources/local.properties +/.idea/ +*.iml +/test-output/ diff --git a/rm-automation/rm-automation-community-rest-api/README b/rm-automation/rm-automation-community-rest-api/README new file mode 100644 index 0000000000..907f41ab0a --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/README @@ -0,0 +1,3 @@ +FIXME: Add more info to the README file + +In order to change the value of a property in "config.properties" create a file called "local.properties" under src/test/resources and redefine the property with the new value. \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/pom.xml b/rm-automation/rm-automation-community-rest-api/pom.xml new file mode 100644 index 0000000000..7eeb2dd519 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/pom.xml @@ -0,0 +1,37 @@ + + + + 4.0.0 + alfresco-rm-automation-community-rest-api + Alfresco Records Management Automation Community REST API + + + org.alfresco + alfresco-rm-automation + 2.6-SNAPSHOT + + + + 1.8 + 1.8 + + + + + org.alfresco.tas + restapi-test + 1.0-SNAPSHOT + + + org.alfresco.tas + restapi-test + 1.0-SNAPSHOT + test-jar + + + org.jglue.fluent-json + fluent-json + 2.0.0 + + + diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponent.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponent.java new file mode 100644 index 0000000000..2090616ac9 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponent.java @@ -0,0 +1,230 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.ALLOWABLE_OPERATIONS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * POJO for file plan component + * + * @author Tuna Aksoy + * @since 1.0 + */ +//FIXME: Once the fields have been added the JsonIgnoreProperties annotation should be removed +@JsonIgnoreProperties(ignoreUnknown = true) +public class FilePlanComponent +{ + private String id; + private String parentId; + private String name; + private String nodeType; + private boolean isCategory; + private boolean isRecordFolder; + private boolean isFile; + private boolean hasRetentionSchedule; + private List aspectNames; + private FilePlanComponentCreatedByUser createdByUser; + @JsonProperty(PROPERTIES) + private FilePlanComponentProperties properties; + @JsonProperty (ALLOWABLE_OPERATIONS) + private List allowableOperations; + + /** + * @return the id + */ + public String getId() + { + return this.id; + } + + /** + * @param id the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the parentId + */ + public String getParentId() + { + return this.parentId; + } + + /** + * @param parentId the parentId to set + */ + public void setParentId(String parentId) + { + this.parentId = parentId; + } + + /** + * @return the name + */ + public String getName() + { + return this.name; + } + + /** + * @param name the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the nodeType + */ + public String getNodeType() + { + return this.nodeType; + } + + /** + * @param nodeType the nodeType to set + */ + public void setNodeType(String nodeType) + { + this.nodeType = nodeType; + } + + /** + * @return the isCategory + */ + public boolean isIsCategory() + { + return this.isCategory; + } + + /** + * @param isCategory the isCategory to set + */ + public void setCategory(boolean isCategory) + { + this.isCategory = isCategory; + } + + /** + * @return the isRecordFolder + */ + public boolean isIsRecordFolder() + { + return this.isRecordFolder; + } + + /** + * @param isRecordFolder the isRecordFolder to set + */ + public void setRecordFolder(boolean isRecordFolder) + { + this.isRecordFolder = isRecordFolder; + } + + /** + * @return the isFile + */ + public boolean isIsFile() + { + return this.isFile; + } + + /** + * @param isFile the isFile to set + */ + public void setFile(boolean isFile) + { + this.isFile = isFile; + } + + /** + * @return the hasRetentionSchedule + */ + public boolean isHasRetentionSchedule() + { + return this.hasRetentionSchedule; + } + + /** + * @param hasRetentionSchedule the hasRetentionSchedule to set + */ + public void setHasRetentionSchedule(boolean hasRetentionSchedule) + { + this.hasRetentionSchedule = hasRetentionSchedule; + } + + /** + * @return the properties + */ + public FilePlanComponentProperties getProperties() + { + return properties; + } + + /** + * @param properties the properties to set + */ + public void setProperties(FilePlanComponentProperties properties) + { + this.properties = properties; + } + + /** + * @return the aspectNames + */ + public List getAspectNames() + { + return this.aspectNames; + } + + /** + * @param aspectNames the aspectNames to set + */ + public void setAspectNames(List aspectNames) + { + this.aspectNames = aspectNames; + } + + /** + * @return the createdByUser + */ + public FilePlanComponentCreatedByUser getCreatedByUser() + { + return this.createdByUser; + } + + /** + * @param createdByUser the createdByUser to set + */ + public void setCreatedByUser(FilePlanComponentCreatedByUser createdByUser) + { + this.createdByUser = createdByUser; + } + + /** + * @return the allowableOperations + */ + public List getAllowableOperations() + { + return this.allowableOperations; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentAlias.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentAlias.java new file mode 100644 index 0000000000..975324531a --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentAlias.java @@ -0,0 +1,68 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import static org.alfresco.rest.util.ParameterCheck.mandatoryString; + +/** + * File plan component alias enumeration + * + * @author Tuna Aksoy + * @since 1.0 + */ +public enum FilePlanComponentAlias +{ + FILE_PLAN_ALIAS("-filePlan-"), + TRANSFERS_ALIAS("-transfers-"), + UNFILED_RECORDS_CONTAINER_ALIAS("-unfiled-"), + HOLDS_ALIAS("-holds-"); + + private String alias; + + private FilePlanComponentAlias(String alias) + { + this.alias = alias; + } + + public static final FilePlanComponentAlias getFilePlanComponentAlias(String alias) + { + mandatoryString("alias", alias); + + FilePlanComponentAlias result = null; + FilePlanComponentAlias[] values = values(); + + for (FilePlanComponentAlias filePlanComponentAlias : values) + { + if (filePlanComponentAlias.toString().equals(alias)) + { + result = filePlanComponentAlias; + break; + } + } + + if (result == null) + { + throw new IllegalArgumentException("Invalid file plan component alias enum value: '" + alias + "'."); + } + + return result; + } + + /** + * @see java.lang.Enum#toString() + */ + @Override + public String toString() + { + return this.alias; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentCreatedByUser.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentCreatedByUser.java new file mode 100644 index 0000000000..c7abc2f920 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentCreatedByUser.java @@ -0,0 +1,56 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +/** + * POJO for file plan component created by object + * + * @author Kristijan Conkas + * @since 1.0 + */ +public class FilePlanComponentCreatedByUser +{ + private String id; + private String displayName; + + /** + * @return the id + */ + public String getId() + { + return this.id; + } + + /** + * @param id the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the displayName + */ + public String getDisplayName() + { + return this.displayName; + } + + /** + * @param displayName the displayName to set + */ + public void setDisplayName(String displayName) + { + this.displayName = displayName; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentEntry.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentEntry.java new file mode 100644 index 0000000000..134ea684ba --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentEntry.java @@ -0,0 +1,35 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.ENTRY; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.alfresco.rest.core.RestModels; + +/** + * POJO for file plan component entry + * + * @author Tuna Aksoy + * @since 1.0 + */ +public class FilePlanComponentEntry extends RestModels +{ + @JsonProperty(ENTRY) + FilePlanComponent filePlanComponent; + + public FilePlanComponent getFilePlanComponent() + { + return filePlanComponent; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentFields.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentFields.java new file mode 100644 index 0000000000..fe59991f0e --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentFields.java @@ -0,0 +1,32 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +/** + * File plan component field names constants + * + * @author Tuna Aksoy + * @since 1.0 + */ +public class FilePlanComponentFields +{ + public static final String NAME = "name"; + public static final String NODE_TYPE = "nodeType"; + public static final String NODE_PARENT_ID = "parentId"; + public static final String ENTRY = "entry"; + public static final String PROPERTIES = "properties"; + public static final String PROPERTIES_TITLE = "cm:title"; + public static final String PROPERTIES_VITAL_RECORD_INDICATOR = "rma:vitalRecordIndicator"; + public static final String PROPERTIES_HOLD_REASON = "rma:holdReason"; + public static final String PROPERTIES_DESCRIPTION = "cm:description"; + public static final String ALLOWABLE_OPERATIONS = "allowableOperations"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentProperties.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentProperties.java new file mode 100644 index 0000000000..729c444eb5 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentProperties.java @@ -0,0 +1,107 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HOLD_REASON; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * POJO for file plan component properties + * + * @author Kristijan Conkas + * @since 1.0 + */ +//FIXME: Once the fields have been added the JsonIgnoreProperties annotation should be removed +@JsonIgnoreProperties(ignoreUnknown = true) +public class FilePlanComponentProperties +{ + @JsonProperty(PROPERTIES_VITAL_RECORD_INDICATOR) + private boolean vitalRecord; + + @JsonProperty(PROPERTIES_TITLE) + private String title; + + @JsonProperty(PROPERTIES_HOLD_REASON) + private String holdReason; + + @JsonProperty(PROPERTIES_DESCRIPTION) + private String description; + + /** + * @return the vitalRecord + */ + public boolean isVitalRecord() + { + return this.vitalRecord; + } + + /** + * @param vitalRecord the vitalRecord to set + */ + public void setVitalRecord(boolean vitalRecord) + { + this.vitalRecord = vitalRecord; + } + + /** + * @return the title + */ + public String getTitle() + { + return this.title; + } + + /** + * @param title the title to set + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the holdReason + */ + public String getHoldReason() + { + return this.holdReason; + } + + /** + * @param holdReason the holdReason to set + */ + public void setHoldReason(String holdReason) + { + this.holdReason = holdReason; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) + { + this.description = description; + } + + /** + * @return the description + */ + public String getDescription() + { + return this.description; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentType.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentType.java new file mode 100644 index 0000000000..26173d3a8a --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentType.java @@ -0,0 +1,72 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import static org.alfresco.rest.util.ParameterCheck.mandatoryString; + +/** + * File plan component type enumeration + * + * @author Tuna Aksoy + * @since 1.0 + */ +public enum FilePlanComponentType +{ + FILE_PLAN_TYPE("rma:filePlan"), + RECORD_CATEGORY_TYPE("rma:recordCategory"), + RECORD_FOLDER_TYPE("rma:recordFolder"), + HOLD_TYPE("rma:hold"), + UNFILED_RECORD_FOLDER_TYPE("rma:unfiledRecordFolder"), + HOLD_CONTAINER_TYPE("rma:holdContainer"), + TRANSFER_CONTAINER_TYPE("rma:transferContainer"), + UNFILED_CONTAINER_TYPE("rma:unfiledRecordContainer"); + + private String type; + + private FilePlanComponentType(String type) + { + this.type = type; + } + + public static final FilePlanComponentType getFilePlanComponentType(String type) + { + mandatoryString("type", type); + + FilePlanComponentType result = null; + FilePlanComponentType[] values = values(); + + for (FilePlanComponentType filePlanComponentType : values) + { + if (filePlanComponentType.toString().equals(filePlanComponentType)) + { + result = filePlanComponentType; + break; + } + } + + if (result == null) + { + throw new IllegalArgumentException("Invalid file plan component type enum value: '" + type + "'."); + } + + return result; + } + + /** + * @see java.lang.Enum#toString() + */ + @Override + public String toString() + { + return this.type; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentsCollection.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentsCollection.java new file mode 100644 index 0000000000..14a40d6d9e --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/fileplancomponents/FilePlanComponentsCollection.java @@ -0,0 +1,25 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.fileplancomponents; + +import org.alfresco.rest.core.RestModels; + +/** + * Handle collection of FilePlanComponents + * + * @author Kristijan Conkas + * @since 1.0 + */ +public class FilePlanComponentsCollection extends RestModels +{ + +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSite.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSite.java new file mode 100644 index 0000000000..296afaa9a1 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSite.java @@ -0,0 +1,48 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.site; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import org.alfresco.rest.model.RestSiteModel; + +/** + * POJO for RM Site component + * + * @author Rodica Sutu + * @since 1.0 + */ +public class RMSite extends RestSiteModel +{ + @JsonProperty (required = true) + private RMSiteCompliance compliance; + + /** + * Helper method to set RM site compliance + * + * @param compliance {@link RMSiteCompliance} the compliance to set + */ + public void setCompliance(RMSiteCompliance compliance) + { + this.compliance = compliance; + } + + /** + * Helper method to get RM site compliance + * + * @return compliance the RM Site compliance to get + */ + public RMSiteCompliance getCompliance() + { + return compliance; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteCompliance.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteCompliance.java new file mode 100644 index 0000000000..ceb010694e --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteCompliance.java @@ -0,0 +1,24 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.site; + +/** + * RM Site compliance + * + * @author Tuna Aksoy + * @since 1.0 + */ +public enum RMSiteCompliance +{ + STANDARD, + DOD5015 +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteFields.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteFields.java new file mode 100644 index 0000000000..2f4804e78d --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/model/site/RMSiteFields.java @@ -0,0 +1,37 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.model.site; + +/** + *RM Site properties from the RM Model Schema + *"entry": { + * "id": "string", + * "guid": "string", + * "title": "string", + * "description": "string", + * "visibility": "{@link org.springframework.social.alfresco.api.entities.Site.Visibility}", + * "compliance": "{@link RMSiteCompliance}", + * "role": "{@link org.alfresco.utility.constants.UserRole}" + *} + * @author Tuna Aksoy + * @author Rodica Sutu + * @since 1.0 + */ +public class RMSiteFields +{ + public static final String ID = "id"; + public static final String COMPLIANCE = "compliance"; + public static final String TITLE = "title"; + public static final String DESCRIPTION = "description"; + public static final String VISIBILITY ="visibility"; + public static final String ROLE = "role"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/FilePlanComponentAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/FilePlanComponentAPI.java new file mode 100644 index 0000000000..72c2375325 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/FilePlanComponentAPI.java @@ -0,0 +1,169 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.requests; + +import static org.alfresco.rest.core.RestRequest.requestWithBody; +import static org.alfresco.rest.core.RestRequest.simpleRequest; +import static org.alfresco.rest.util.ParameterCheck.mandatoryObject; +import static org.alfresco.rest.util.ParameterCheck.mandatoryString; +import static org.springframework.http.HttpMethod.DELETE; +import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.HttpMethod.PUT; + +import com.google.gson.JsonObject; + +import org.alfresco.rest.core.RestAPI; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentsCollection; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * File plan component REST API Wrapper + * + * @author Tuna Aksoy + * @author Kristijan Conkas + * @since 1.0 + */ +@Component +@Scope(value = "prototype") +public class FilePlanComponentAPI extends RestAPI +{ + /** + * Get a file plan component + * + * @param filePlanComponentId The id of the file plan component to get + * @return The {@link FilePlanComponent} for the given file plan component id + * @throws Exception for the following cases: + *
    + *
  • {@code fileplanComponentId} is not a valid format
  • + *
  • authentication fails
  • + *
  • {@code fileplanComponentId} does not exist
  • + *
+ */ + public FilePlanComponent getFilePlanComponent(String filePlanComponentId) throws Exception + { + mandatoryString("filePlanComponentId", filePlanComponentId); + + return usingRestWrapper().processModel(FilePlanComponent.class, simpleRequest( + GET, + "fileplan-components/{fileplanComponentId}?{parameters}", + filePlanComponentId, getParameters() + )); + } + + /** + * List child components of a file plan component + * + * @param filePlanComponentId The id of the file plan component of which to get child components + * @return The {@link FilePlanComponent} for the given file plan component id + * @throws Exception for the following cases: + *
    + *
  • {@code fileplanComponentId} is not a valid format
  • + *
  • authentication fails
  • + *
  • {@code fileplanComponentId} does not exist
  • + *
+ */ + public FilePlanComponentsCollection listChildComponents(String filePlanComponentId) throws Exception + { + mandatoryString("filePlanComponentId", filePlanComponentId); + + return usingRestWrapper().processModels(FilePlanComponentsCollection.class, simpleRequest( + GET, + "fileplan-components/{fileplanComponentId}/children", + filePlanComponentId + )); + } + + /** + * Creates a file plan component with the given properties under the parent node with the given id + * + * @param filePlanComponentProperties The properties of the file plan component to be created + * @param parentId The id of the parent where the new file plan component should be created + * @return The {@link FilePlanComponent} with the given properties + * @throws Exception for the following cases: + *
    + *
  • {@code fileplanComponentId} is not a valid format
  • + *
  • authentication fails
  • + *
  • current user does not have permission to add children to {@code fileplanComponentId}
  • + *
  • {@code fileplanComponentId} does not exist
  • + *
  • new name clashes with an existing node in the current parent container
  • + *
  • model integrity exception, including node name with invalid characters
  • + *
+ */ + public FilePlanComponent createFilePlanComponent(JsonObject filePlanComponentProperties, String parentId) throws Exception + { + mandatoryObject("filePlanComponentProperties", filePlanComponentProperties); + mandatoryString("parentId", parentId); + + return usingRestWrapper().processModel(FilePlanComponent.class, requestWithBody( + POST, + filePlanComponentProperties.toString(), + "fileplan-components/{fileplanComponentId}/children", + parentId + )); + } + + /** + * Updates a file plan component + * + * @param filePlanComponentProperties The properties to be updated + * @param filePlanComponentId The id of the file plan component which will be updated + * @param returns The updated {@link FilePlanComponent} + * @throws Exception for the following cases: + *
    + *
  • the update request is invalid or {@code fileplanComponentId} is not a valid format or {@code filePlanComponentProperties} is invalid
  • + *
  • authentication fails
  • + *
  • current user does not have permission to update {@code fileplanComponentId}
  • + *
  • {@code fileplanComponentId} does not exist
  • + *
  • the updated name clashes with an existing node in the current parent folder
  • + *
  • model integrity exception, including node name with invalid characters
  • + *
+ */ + public FilePlanComponent updateFilePlanComponent(JsonObject filePlanComponentProperties, String filePlanComponentId) throws Exception + { + mandatoryObject("filePlanComponentProperties", filePlanComponentProperties); + mandatoryString("filePlanComponentId", filePlanComponentId); + + return usingRestWrapper().processModel(FilePlanComponent.class, requestWithBody( + PUT, + filePlanComponentProperties.toString(), + "fileplan-components/{fileplanComponentId}", + filePlanComponentId + )); + } + + /** + * Delete file plan component + * + * @param filePlanComponentId The id of the file plan component to be deleted + * @throws Exception for the following cases: + *
    + *
  • {@code fileplanComponentId} is not a valid format
  • + *
  • authentication fails
  • + *
  • current user does not have permission to delete {@code fileplanComponentId}
  • + *
  • {@code fileplanComponentId} does not exist
  • + *
  • {@code fileplanComponentId} is locked and cannot be deleted
  • + *
+ */ + public void deleteFilePlanComponent(String filePlanComponentId) throws Exception + { + mandatoryString("filePlanComponentId", filePlanComponentId); + + usingRestWrapper().processEmptyModel(simpleRequest( + DELETE, + "fileplan-components/{fileplanComponentId}", + filePlanComponentId + )); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/RMSiteAPI.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/RMSiteAPI.java new file mode 100644 index 0000000000..580d7703ea --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/requests/RMSiteAPI.java @@ -0,0 +1,127 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.requests; + +import static org.alfresco.rest.core.RestRequest.requestWithBody; +import static org.alfresco.rest.core.RestRequest.simpleRequest; +import static org.alfresco.rest.util.ParameterCheck.mandatoryObject; +import static org.springframework.http.HttpMethod.DELETE; +import static org.springframework.http.HttpMethod.GET; +import static org.springframework.http.HttpMethod.POST; +import static org.springframework.http.HttpMethod.PUT; + +import com.google.gson.JsonObject; + +import org.alfresco.rest.core.RestAPI; +import org.alfresco.rest.model.site.RMSite; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * File plan component REST API Wrapper + * + * @author Tuna Aksoy + * @author Rodica Sutu + * @since 1.0 + */ +@Component +@Scope (value = "prototype") +public class RMSiteAPI extends RestAPI +{ + /** + * Get the RM site + * + * @return The {@link RMSite} for the given file plan component id + * @throws Exception for the following cases: + *
    + *
  • Api Response code 400 Invalid parameter: GET request is supported only for the RM site
  • + *
  • Api Response code 401 If authentication failed
  • + *
  • Api Response code 409 If RM Site does not exist
  • + *
  • Api Response code default Unexpected error
  • + *
+ */ + public RMSite getSite() throws Exception + { + return usingRestWrapper().processModel(RMSite.class, simpleRequest( + GET, + "sites/rm" + )); + } + + /** + * Create the RM site + * + * @param rmSiteProperties The properties of the rm site to be created + * @return The {@link RMSite} with the given properties + * @throws Exception for the following cases: + *
    + *
  • Api Response code 400 Invalid parameter: title, or description exceed the maximum length; or siteBodyCreate invalid
  • + *
  • Api Response code 401 If authentication failedApi Response code 409 RM Site already exists
  • + *
  • Api Response code default Unexpected error
  • + *
+ */ + public RMSite createRMSite(JsonObject rmSiteProperties) throws Exception + { + mandatoryObject("rmSiteProperties", rmSiteProperties); + + return usingRestWrapper().processModel(RMSite.class, requestWithBody( + POST, + rmSiteProperties.toString(), + "sites" + )); + } + + /** + * Delete RM site + * @throws Exception for the following cases: + *
    + *
  • Api Response code 400 Invalid parameter: DELETE request is supported only for the RM site
  • + *
  • Api Response code 401 If authentication failedApi Response code 403 Current user does not have permission to delete the site that is visible to them.
  • + *
  • Api Response code 404 RM site does not exist
  • + *
  • Api Response code default Unexpected error
  • + *
+ */ + public void deleteRMSite() throws Exception + { + usingRestWrapper().processEmptyModel(simpleRequest( + DELETE, + "sites/rm" + )); + } + + /** + * Update RM site + * + * @param rmSiteProperties The properties to be updated + * @return The updated {@link RMSite} + * @throws Exception for the following cases: + *
    + *
  • Api Response code 400 the update request is invalid {@code rmSiteProperties} is invalid
  • + *
  • Api Response code 401 If authentication fails
  • + *
  • Api Response code 403 does not have permission to update {@code RMSite}
  • + *
  • Api Response code 404 {@code RMSite} does not exist
  • + *
  • Api Response code default Unexpected error,model integrity exception
  • + *
+ */ + public RMSite updateRMSite(JsonObject rmSiteProperties) throws Exception + { + mandatoryObject("rmSiteProperties", rmSiteProperties); + + return usingRestWrapper().processModel(RMSite.class, requestWithBody( + PUT, + rmSiteProperties.toString(), + "sites/rm" + )); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/util/ParameterCheck.java b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/util/ParameterCheck.java new file mode 100644 index 0000000000..2895d538b6 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/main/java/org/alfresco/rest/util/ParameterCheck.java @@ -0,0 +1,58 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.util; + +import static org.apache.commons.lang3.StringUtils.isBlank; + +/** + * Utility class for checking parameters + * + * @author Tuna Aksoy + * @since 1.0 + */ +public class ParameterCheck +{ + private ParameterCheck() + { + // Intentionally blank + } + + /** + * Checks if a given {@link String} is blank or not, i.e. not null, "" or " ". + * + * @param paramName The name of the parameter to check + * @param paramValue The value of the parameter to check + * @throws IllegalArgumentException Throws an exception if the given value is blank + */ + public static void mandatoryString(final String paramName, final String paramValue) throws IllegalArgumentException + { + if (isBlank(paramValue)) + { + throw new IllegalArgumentException("'" + paramName + "' is a mandatory parameter."); + } + } + + /** + * Checks if a given {@link Object} is null or not + * + * @param paramName The name of the parameter to check + * @param object The value of the parameter to check + * @throws IllegalArgumentException Throws an exception if the given value is null + */ + public static void mandatoryObject(final String paramName, final Object object) throws IllegalArgumentException + { + if (object == null) + { + throw new IllegalArgumentException("'" + paramName + "' is a mandatory parameter."); + } + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/AllowableOperations.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/AllowableOperations.java new file mode 100644 index 0000000000..e48322595c --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/AllowableOperations.java @@ -0,0 +1,25 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.base; + +/** + * List of allowable operations + * + * @author Tuna Aksoy + * @since 1.0 + */ +public class AllowableOperations +{ + public static final String CREATE = "create"; + public static final String UPDATE = "update"; + public static final String DELETE = "delete"; +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/BaseRestTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/BaseRestTest.java new file mode 100644 index 0000000000..6151551afa --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/BaseRestTest.java @@ -0,0 +1,122 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.base; + +import static java.lang.Integer.parseInt; + +import static org.alfresco.rest.model.site.RMSiteCompliance.STANDARD; +import static org.alfresco.rest.model.site.RMSiteFields.COMPLIANCE; +import static org.alfresco.rest.model.site.RMSiteFields.DESCRIPTION; +import static org.alfresco.rest.model.site.RMSiteFields.TITLE; +import static org.jglue.fluentjson.JsonBuilderFactory.buildObject; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; + +import com.google.gson.JsonObject; +import com.jayway.restassured.RestAssured; + +import org.alfresco.rest.RestTest; +import org.alfresco.rest.core.RestWrapper; +import org.alfresco.rest.requests.RMSiteAPI; +import org.alfresco.utility.data.DataUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.testng.annotations.BeforeClass; + +/** + * Base class for all IG REST API Tests + * + * @author Kristijan Conkas + * @author Tuna Aksoy + * @since 1.0 + */ +@Configuration +@PropertySource("classpath:default.properties") +@PropertySource(value = "classpath:local.properties", ignoreResourceNotFound = true) +public class BaseRestTest extends RestTest +{ + @Value ("${alfresco.scheme}") + private String scheme; + + @Value ("${alfresco.server}") + private String server; + + @Value ("${alfresco.port}") + private String port; + + @Value ("${rest.rmPath}") + private String restRmPath; + + @Autowired + private RMSiteAPI rmSiteAPI; + + @Autowired + private DataUser dataUser; + + // Constants + public static final String RM_ID = "rm"; + public static final String RM_TITLE = "Records Management"; + public static final String RM_DESCRIPTION = "Records Management Site"; + + /** + * @see org.alfresco.rest.RestTest#checkServerHealth() + */ + @Override + @BeforeClass(alwaysRun = true) + public void checkServerHealth() throws Exception + { + RestAssured.baseURI = scheme + "://" + server; + RestAssured.port = parseInt(port); + RestAssured.basePath = restRmPath; + + // Create RM Site if not exist + createRMSiteIfNotExists(); + } + + /** + * Helper method to create the RM Site via the POST request + * if the site doesn't exist + */ + public void createRMSiteIfNotExists() throws Exception + { + // Check RM site doesn't exist + if (!siteRMExists()) + { + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Build the RM site properties + JsonObject rmSiteProperties = buildObject() + .add(TITLE, RM_TITLE) + .add(DESCRIPTION, RM_DESCRIPTION) + .add(COMPLIANCE, STANDARD.toString()) + .getJson(); + + // Create the RM site + rmSiteAPI.createRMSite(rmSiteProperties); + + // Verify the status code + rmSiteAPI.usingRestWrapper().assertStatusCodeIs(CREATED); + } + } + + /** + * Check if the RM site exists via the GET request + */ + public boolean siteRMExists() throws Exception + { + RestWrapper restWrapper = rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + rmSiteAPI.getSite(); + return restWrapper.getStatusCode().equals(OK.toString()); + } +} \ No newline at end of file diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/TestData.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/TestData.java new file mode 100644 index 0000000000..fb71b4f37c --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/base/TestData.java @@ -0,0 +1,80 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.base; + +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.HOLDS_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.FILE_PLAN_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.HOLD_CONTAINER_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.TRANSFER_CONTAINER_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE; + +import org.testng.annotations.DataProvider; + +/** + * Test data used in tests + * + * @author Rodica Sutu + * @since 1.0 + */ +public interface TestData +{ + /** + * A user with ALFRESCO_ADMINISTRATORS role. + *

"GROUP_ANOTHER_ADMIN_EXISTS" The ANOTHER_ADMIN user has been created. + */ + public static final String ANOTHER_ADMIN = "another_admin"; + + /** + * The default password used when creating test users. + */ + public static final String DEFAULT_PASSWORD = "password"; + + /** + * The default email address used when creating test users. + */ + public static final String DEFAULT_EMAIL = "default@alfresco.com"; + + /** + * Data Provider with the special file plan components alias + * @return file plan component alias + */ + @DataProvider + public static Object[][] getContainers() + { + return new Object[][] { + { FILE_PLAN_ALIAS.toString() }, + { TRANSFERS_ALIAS.toString() }, + { HOLDS_ALIAS.toString() }, + { UNFILED_RECORDS_CONTAINER_ALIAS.toString() }, + }; + } + + /** + * Data Provider with: + * the special file plan components alias + * file plan component node type + * @return file plan component alias + */ + @DataProvider + public static Object[][] getContainersAndTypes() + { + return new Object[][] { + { FILE_PLAN_ALIAS, FILE_PLAN_TYPE }, + { TRANSFERS_ALIAS, TRANSFER_CONTAINER_TYPE }, + { HOLDS_ALIAS, HOLD_CONTAINER_TYPE }, + { UNFILED_RECORDS_CONTAINER_ALIAS, UNFILED_CONTAINER_TYPE }, + }; + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/FilePlanTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/FilePlanTests.java new file mode 100644 index 0000000000..427e080cde --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/FilePlanTests.java @@ -0,0 +1,302 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.fileplancomponents; + +import static java.util.Arrays.asList; + +import static org.alfresco.rest.base.AllowableOperations.CREATE; +import static org.alfresco.rest.base.AllowableOperations.DELETE; +import static org.alfresco.rest.base.AllowableOperations.UPDATE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.NAME; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.NODE_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE; +import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.jglue.fluentjson.JsonBuilderFactory.buildObject; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.OK; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import com.google.gson.JsonObject; + +import org.alfresco.rest.base.BaseRestTest; +import org.alfresco.rest.base.TestData; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentType; +import org.alfresco.rest.requests.FilePlanComponentAPI; +import org.alfresco.rest.requests.RMSiteAPI; +import org.alfresco.utility.data.DataUser; +import org.alfresco.utility.model.UserModel; +import org.alfresco.utility.report.Bug; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.Test; + +/** + * This class contains the tests for + * the File Plan CRUD API + * + * @author Rodica Sutu + * @since 1.0 + */ +public class FilePlanTests extends BaseRestTest +{ + @Autowired + private FilePlanComponentAPI filePlanComponentAPI; + + @Autowired + private RMSiteAPI rmSiteAPI; + + @Autowired + private DataUser dataUser; + + /** + * Given that the RM site doesn't exist + * When I use the API to get the File Plan/Holds/Unfiled Records Container/Transfers + * Then I get the 404 response code + */ + @Test + ( + description = "Check the GET response code when the RM site doesn't exist", + dataProviderClass = TestData.class, + dataProvider = "getContainers" + ) + public void getFilePlanComponentWhenRMIsNotCreated(String filePlanAlias) throws Exception + { + // Check RM Site Exist + if (siteRMExists()) + { + // Delete RM Site + rmSiteAPI.deleteRMSite(); + } + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Get the file plan component + filePlanComponentAPI.getFilePlanComponent(filePlanAlias.toString()); + + //check the response code is NOT_FOUND + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(NOT_FOUND); + } + + /** + * Given that a file plan exists + * When I ask the API for the details of the file plan + * Then I am given the details of the file plan + */ + @Test + ( + description = "Check the GET response for special file plan components when the RM site exit", + dataProviderClass = TestData.class, + dataProvider = "getContainersAndTypes" + ) + public void getFilePlanComponentWhenRMIsCreated(FilePlanComponentAlias filePlanAlias, FilePlanComponentType rmType) throws Exception + { + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Get the file plan special container + FilePlanComponent filePlanComponent = filePlanComponentAPI.getFilePlanComponent(filePlanAlias.toString()); + + // Check the response code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // Check the response contains the right node type + assertEquals(filePlanComponent.getNodeType(), rmType.toString()); + } + + /** + * Given that a file plan exists + * When I ask the API for the details of the file plan to include the allowableOperations property + * Then I am given the allowableOperations property with the update and create operations. + */ + @Test + ( + description = "Check the allowableOperations list returned ", + dataProviderClass = TestData.class, + dataProvider = "getContainers" + ) + public void includeAllowableOperations(String specialContainerAlias) throws Exception + { + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Get the file plan special containers with the optional parameter allowableOperations + FilePlanComponent filePlanComponent = filePlanComponentAPI.withParams("include=allowableOperations").getFilePlanComponent(specialContainerAlias); + + // Check the list of allowableOperations returned + assertTrue(filePlanComponent.getAllowableOperations().containsAll(asList(UPDATE, CREATE)), + "Wrong list of the allowable operations is return" + filePlanComponent.getAllowableOperations().toString()); + + // Check the list of allowableOperations doesn't contains DELETE operation + assertFalse(filePlanComponent.getAllowableOperations().contains(DELETE), + "The list of allowable operations contains delete option" + filePlanComponent.getAllowableOperations().toString()); + } + + /** + * Given that a file plan exists + * When I ask the API to modify the details of the file plan + * Then the details of the file are modified + * Note: the details of the file plan are limited to title and description. + */ + @Test + @Bug (id = "RM-4295") + public void updateFilePlan() throws Exception + { + String FILE_PLAN_DESCRIPTION = "Description updated " + getRandomAlphanumeric(); + String FILE_PLAN_TITLE = "Title updated " + getRandomAlphanumeric(); + + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Build the file plan root properties + JsonObject filePlanProperties = buildObject() + .addObject(PROPERTIES) + .add(PROPERTIES_TITLE, FILE_PLAN_TITLE) + .add(PROPERTIES_DESCRIPTION, FILE_PLAN_DESCRIPTION) + .end() + .getJson(); + + // Update the record category + FilePlanComponent renamedFilePlanComponent = filePlanComponentAPI.updateFilePlanComponent(filePlanProperties,FILE_PLAN_ALIAS.toString()); + + // Verify the response status code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(OK); + + // Verify the returned description field for the file plan component + assertEquals(renamedFilePlanComponent.getProperties().getDescription(), FILE_PLAN_DESCRIPTION); + + // Verify the returned title field for the file plan component + assertEquals(renamedFilePlanComponent.getProperties().getTitle(), FILE_PLAN_TITLE); + } + + /** + * Given that a file plan exists + * When I ask the API to delete the file plan + * Then the 403 response code is returned. + */ + @Test + ( + description = "Check the response code when deleting the special file plan components", + dataProviderClass = TestData.class, + dataProvider = "getContainers" + ) + public void deleteFilePlanSpecialComponents(String filePlanAlias) throws Exception + { + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + + // Delete the file plan component + filePlanComponentAPI.deleteFilePlanComponent(filePlanAlias.toString()); + + // Check the DELETE response status code + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + + /** + * Given that RM site exists + * When I ask to create the file plan + * Then the 403 response code is returned. + */ + @Test + ( + description = "Check the response code when creating the special file plan components", + dataProviderClass = TestData.class, + dataProvider = "getContainersAndTypes" + ) + @Bug(id="RM-4296") + public void createFilePlanSpecialContainerWhenExists(FilePlanComponentAlias filePlanAlias, FilePlanComponentType rmType) throws Exception + { + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Authenticate with admin user + rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + // Get the RM site ID + String rmSiteId = rmSiteAPI.getSite().getGuid(); + + String name = filePlanAlias + getRandomAlphanumeric(); + + // Build the file plan root properties + JsonObject componentProperties = buildObject() + .add(NAME, name) + .add(NODE_TYPE, rmType.toString()) + .getJson(); + + // Authenticate with admin user + filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser()); + // Create the special containers into RM site - parent folder + filePlanComponentAPI.createFilePlanComponent(componentProperties, rmSiteId); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + + // Create the special containers into RM site - parent folder + filePlanComponentAPI.createFilePlanComponent(componentProperties, FILE_PLAN_ALIAS.toString()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + + // Create the special containers into the root of special containers containers + filePlanComponentAPI.createFilePlanComponent(componentProperties, filePlanAlias.toString()); + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } + + /** + * Given that RM site exists + * When a non-RM user ask the API for the details of the file plan + * Then the status code 403 (Permission denied) is return + */ + @Test + ( + description = "Check the response code when the RM site containers are get with non rm users", + dataProviderClass = TestData.class, + dataProvider = "getContainers" + ) + public void getSpecialFilePlanComponentsWithNonRMuser(String filePlanAlias) throws Exception + { + // Create RM Site if doesn't exist + createRMSiteIfNotExists(); + + // Disconnect user from REST API session + rmSiteAPI.usingRestWrapper().disconnect(); + + // Authenticate admin user to Alfresco REST API + restClient.authenticateUser(dataUser.getAdminUser()); + + // Create a random user + UserModel nonRMuser = dataUser.createRandomTestUser("testUser"); + + // Authenticate using the random user + filePlanComponentAPI.usingRestWrapper().authenticateUser(nonRMuser); + + // Get the special file plan components + filePlanComponentAPI.getFilePlanComponent(filePlanAlias.toString()); + + // Check the response status code is FORBIDDEN + filePlanComponentAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN); + } +} diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/RecordCategoryTest.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/RecordCategoryTest.java new file mode 100644 index 0000000000..67d73d42c6 --- /dev/null +++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/fileplancomponents/RecordCategoryTest.java @@ -0,0 +1,374 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * License rights for this program may be obtained from Alfresco Software, Ltd. + * pursuant to a written agreement and any use of this program without such an + * agreement is prohibited. + * #L% + */ +package org.alfresco.rest.fileplancomponents; + +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.NAME; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.NODE_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE; +import static org.alfresco.rest.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE; +import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric; +import static org.jglue.fluentjson.JsonBuilderFactory.buildObject; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.NO_CONTENT; +import static org.springframework.http.HttpStatus.OK; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.util.ArrayList; +import java.util.NoSuchElementException; + +import com.google.gson.JsonObject; + +import org.alfresco.rest.base.BaseRestTest; +import org.alfresco.rest.core.RestWrapper; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponent; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentProperties; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentType; +import org.alfresco.rest.model.fileplancomponents.FilePlanComponentsCollection; +import org.alfresco.rest.requests.FilePlanComponentAPI; +import org.alfresco.utility.data.DataUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.Test; + +/** + * Record category related API tests + * + * @author Kristijan Conkas + * @author Tuna Aksoy + * @since 1.0 + */ +public class RecordCategoryTest extends BaseRestTest +{ + @Autowired + private FilePlanComponentAPI filePlanComponentAPI; + + @Autowired + private DataUser dataUser; + + // Number of children (for children creation test) + private static final int NUMBER_OF_CHILDREN = 10; + + /** + *

+     * Given that a file plan exists
+     * When I ask the API to create a root record category
+     * Then it is created as a root record category
+     */
+    @Test
+    (
+        description = "Create root category"
+    )
+    public void createCategoryTest() throws Exception
+    {
+        // Authenticate with admin user
+        RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        String categoryName = "Category name " + getRandomAlphanumeric();
+        String categoryTitle = "Category title " + getRandomAlphanumeric();
+
+        // Build the record category properties
+        JsonObject recordCategoryProperties = buildObject().
+                add(NAME, categoryName).
+                add(NODE_TYPE, RECORD_CATEGORY_TYPE.toString()).
+                addObject(PROPERTIES).
+                    add(PROPERTIES_TITLE, categoryTitle).
+                    end().
+                getJson();
+
+        // Create the record category
+        FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategoryProperties, FILE_PLAN_ALIAS.toString());
+
+        // Verify the status code
+        restWrapper.assertStatusCodeIs(CREATED);
+
+        // Verify the returned file plan component
+        assertTrue(filePlanComponent.isIsCategory());
+        assertFalse(filePlanComponent.isIsFile());
+        assertFalse(filePlanComponent.isIsRecordFolder());
+
+        assertEquals(filePlanComponent.getName(), categoryName);
+        assertEquals(filePlanComponent.getNodeType(), RECORD_CATEGORY_TYPE.toString());
+        assertFalse(filePlanComponent.isHasRetentionSchedule());
+
+        assertEquals(filePlanComponent.getCreatedByUser().getId(), dataUser.getAdminUser().getUsername());
+
+        // Verify the returned file plan component properties
+        FilePlanComponentProperties filePlanComponentProperties = filePlanComponent.getProperties();
+        assertEquals(filePlanComponentProperties.getTitle(), categoryTitle);
+
+        logger.info("Aspects: " + filePlanComponent.getAspectNames());
+    }
+
+    /**
+     * 
+     * Given that a record category exists
+     * When I ask the API to update the details of the record category
+     * Then the details of the record category are updated
+     */
+    @Test
+    (
+        description = "Rename root category"
+    )
+    public void renameCategory() throws Exception
+    {
+        // Authenticate with admin user
+        RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Create record category first
+        String categoryName = "Category name " + getRandomAlphanumeric();
+        String categoryTitle = "Category title " + getRandomAlphanumeric();
+
+        // Build the record category properties
+        JsonObject recordCategoryProperties = buildObject().
+                add(NAME, categoryName).
+                add(NODE_TYPE, RECORD_CATEGORY_TYPE.toString()).
+                addObject(PROPERTIES).
+                    add(PROPERTIES_TITLE, categoryTitle).
+                    end().
+                getJson();
+
+        // Create the record category
+        FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategoryProperties, FILE_PLAN_ALIAS.toString());
+
+        String newCategoryName = "Rename " + categoryName;
+
+        // Build the properties which will be updated
+        JsonObject updateRecordCategoryProperties = buildObject().
+                add(NAME, newCategoryName).
+                getJson();
+
+        // Update the record category
+        FilePlanComponent renamedFilePlanComponent = filePlanComponentAPI.updateFilePlanComponent(updateRecordCategoryProperties, filePlanComponent.getId());
+
+        // Verify the status code
+        restWrapper.assertStatusCodeIs(OK);
+
+        // Verify the returned file plan component
+        assertEquals(renamedFilePlanComponent.getName(), newCategoryName);
+
+        // Get actual FILE_PLAN_ALIAS id
+        FilePlanComponent parentComponent = filePlanComponentAPI.getFilePlanComponent(FILE_PLAN_ALIAS.toString());
+
+        // verify renamed component still has this parent
+        assertEquals(renamedFilePlanComponent.getParentId(), parentComponent.getId());
+    }
+
+    /**
+     * 
+     * Given that a record category exists
+     * When I ask the API to delete the record category
+     * Then the record category and all its contents is deleted
+     */
+    @Test
+    (
+        description = "Delete category"
+    )
+    public void deleteCategory() throws Exception
+    {
+        // Authenticate with admin user
+        RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Create record category first
+        String categoryName = "Category name " + getRandomAlphanumeric();
+        String categoryTitle = "Category title " + getRandomAlphanumeric();
+
+        // Build the record category properties
+        JsonObject recordCategoryProperties = buildObject().
+                add(NAME, categoryName).
+                add(NODE_TYPE, RECORD_CATEGORY_TYPE.toString()).
+                addObject(PROPERTIES).
+                    add(PROPERTIES_TITLE, categoryTitle).
+                    end().
+                getJson();
+
+        // Create the record category
+        FilePlanComponent filePlanComponent = filePlanComponentAPI.createFilePlanComponent(recordCategoryProperties, FILE_PLAN_ALIAS.toString());
+
+        // Delete the record category
+        filePlanComponentAPI.deleteFilePlanComponent(filePlanComponent.getId());
+
+        // Verify the status code
+        restWrapper.assertStatusCodeIs(NO_CONTENT);
+
+        // Deleted component should no longer be retrievable
+        filePlanComponentAPI.getFilePlanComponent(filePlanComponent.getId());
+        restWrapper.assertStatusCodeIs(NOT_FOUND);
+    }
+
+    /**
+     * 
+     * Given that a record category exists
+     * When I ask the API to create a record category
+     * Then it is created within the record category
+     */
+    @Test
+    (
+        description = "Create child category"
+    )
+    public void createSubcategory() throws Exception
+    {
+        // Create root level category
+        FilePlanComponent rootCategory = createCategory(FILE_PLAN_ALIAS.toString(), getRandomAlphanumeric());
+        assertNotNull(rootCategory.getId());
+
+        // Create subcategory as a child of rootCategory
+        FilePlanComponent childCategory = createCategory(rootCategory.getId(), getRandomAlphanumeric());
+
+        // Child category created?
+        assertNotNull(childCategory.getId());
+
+        // Verify child category
+        assertEquals(childCategory.getParentId(), rootCategory.getId());
+        assertTrue(childCategory.isIsCategory());
+        assertFalse(childCategory.isIsFile());
+        assertFalse(childCategory.isIsRecordFolder());
+        assertEquals(childCategory.getNodeType(), RECORD_CATEGORY_TYPE.toString());
+    }
+
+    /**
+     * 
+     * Given that a record category exists
+     * And contains a number of record categories and record folders
+     * When I ask the APi to get me the children of the record category
+     * Then I am returned the contained record categories and record folders
+     * And their details
+     */
+    @Test
+    (
+        description = "List children of a category"
+    )
+    public void listChildren() throws Exception
+    {
+        // Create root level category
+        FilePlanComponent rootCategory = createCategory(FILE_PLAN_ALIAS.toString(), getRandomAlphanumeric());
+        assertNotNull(rootCategory.getId());
+
+        // Add child categories/folders
+        ArrayList children = new ArrayList();
+        for (int i=0; i < NUMBER_OF_CHILDREN; i++)
+        {
+            // Create a child
+            FilePlanComponent child = createComponent(rootCategory.getId(),
+                getRandomAlphanumeric(),
+                // half of the children should be subcategories, the other subfolders
+                (i <= NUMBER_OF_CHILDREN / 2) ? RECORD_CATEGORY_TYPE : RECORD_FOLDER_TYPE);
+            assertNotNull(child.getId());
+            children.add(child);
+        }
+
+        // Authenticate with admin user
+        RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // List children from API
+        FilePlanComponentsCollection apiChildren = filePlanComponentAPI.listChildComponents(rootCategory.getId());
+
+        // Check status code
+        restWrapper.assertStatusCodeIs(OK);
+        logger.info("parent: " + rootCategory.getId());
+
+        // Check listed children against created list
+        apiChildren.getEntries().forEach(c ->
+        {
+            FilePlanComponent filePlanComponent = c.getFilePlanComponent();
+            assertNotNull(filePlanComponent.getId());
+            logger.info("Checking child " + filePlanComponent.getId());
+
+            try
+            {
+                // Find this child in created children list
+                FilePlanComponent createdComponent = children.stream()
+                    .filter(child -> child.getId().equals(filePlanComponent.getId()))
+                    .findFirst()
+                    .get();
+
+                // Created by
+                assertEquals(filePlanComponent.getCreatedByUser().getId(), dataUser.getAdminUser().getUsername());
+
+                // Is parent Id set correctly?
+                assertEquals(filePlanComponent.getParentId(), rootCategory.getId());
+
+                // Only categories or folders have been created
+                assertFalse(filePlanComponent.isIsFile());
+
+                // Boolean properties related to node type
+                // Only RECORD_CATEGORY_TYPE and RECORD_FOLDER_TYPE have been created
+                if (filePlanComponent.getNodeType().equals(RECORD_CATEGORY_TYPE.toString()))
+                {
+                    assertTrue(filePlanComponent.isIsCategory());
+                    assertFalse(filePlanComponent.isIsRecordFolder());
+                }
+                else
+                {
+                    assertTrue(filePlanComponent.isIsRecordFolder());
+                    assertFalse(filePlanComponent.isIsCategory());
+                }
+
+                // Does returned object have the same contents as the created one?
+                assertEquals(createdComponent.getName(), filePlanComponent.getName());
+                assertEquals(createdComponent.getNodeType(), filePlanComponent.getNodeType());
+
+                // Verify properties
+                // FIXME: Verify properties
+            }
+            catch (NoSuchElementException e)
+            {
+                fail("No child element for " + filePlanComponent.getId());
+            }
+        });
+    }
+
+    /**
+     * Helper method to create child category
+     *
+     * @param parentCategoryId The id of the parent category
+     * @param categoryName The name of the category
+     * @return The created category
+     * @throws Exception on unsuccessful component creation
+     */
+    private FilePlanComponent createCategory(String parentCategoryId, String categoryName) throws Exception
+    {
+        return createComponent(parentCategoryId, categoryName, RECORD_CATEGORY_TYPE);
+    }
+
+    /**
+     * Helper method to create generic child component
+     *
+     * @param parentComponentId The id of the parent file plan component
+     * @param componentName The name of the file plan component
+     * @param componentType The name of the file plan component
+     * @return The created file plan component
+     * @throws Exception
+     */
+    private FilePlanComponent createComponent(String parentComponentId, String componentName, FilePlanComponentType componentType) throws Exception
+    {
+        RestWrapper restWrapper = filePlanComponentAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        JsonObject componentProperties = buildObject().
+            add(NAME, componentName).
+            add(NODE_TYPE, componentType.toString()).
+            addObject(PROPERTIES).
+                add(PROPERTIES_TITLE, "Title for " + componentName).
+                end().
+            getJson();
+
+        FilePlanComponent fpc = filePlanComponentAPI.createFilePlanComponent(componentProperties, parentComponentId);
+        restWrapper.assertStatusCodeIs(CREATED);
+        return fpc;
+    }
+}
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/site/RMSiteTests.java b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/site/RMSiteTests.java
new file mode 100644
index 0000000000..14b480cd1e
--- /dev/null
+++ b/rm-automation/rm-automation-community-rest-api/src/test/java/org/alfresco/rest/site/RMSiteTests.java
@@ -0,0 +1,346 @@
+/*
+ * #%L
+ * Alfresco Records Management Module
+ * %%
+ * Copyright (C) 2005 - 2016 Alfresco Software Limited
+ * %%
+ * License rights for this program may be obtained from Alfresco Software, Ltd.
+ * pursuant to a written agreement and any use of this program without such an
+ * agreement is prohibited.
+ * #L%
+ */
+package org.alfresco.rest.site;
+
+import static org.alfresco.rest.base.TestData.ANOTHER_ADMIN;
+import static org.alfresco.rest.base.TestData.DEFAULT_EMAIL;
+import static org.alfresco.rest.base.TestData.DEFAULT_PASSWORD;
+import static org.alfresco.rest.model.site.RMSiteCompliance.DOD5015;
+import static org.alfresco.rest.model.site.RMSiteCompliance.STANDARD;
+import static org.alfresco.rest.model.site.RMSiteFields.COMPLIANCE;
+import static org.alfresco.rest.model.site.RMSiteFields.DESCRIPTION;
+import static org.alfresco.rest.model.site.RMSiteFields.TITLE;
+import static org.jglue.fluentjson.JsonBuilderFactory.buildObject;
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+import static org.springframework.http.HttpStatus.CONFLICT;
+import static org.springframework.http.HttpStatus.CREATED;
+import static org.springframework.http.HttpStatus.FORBIDDEN;
+import static org.springframework.http.HttpStatus.NOT_FOUND;
+import static org.springframework.http.HttpStatus.NO_CONTENT;
+import static org.springframework.http.HttpStatus.OK;
+import static org.springframework.social.alfresco.api.entities.Site.Visibility.PUBLIC;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import com.google.gson.JsonObject;
+
+import org.alfresco.dataprep.UserService;
+import org.alfresco.rest.base.BaseRestTest;
+import org.alfresco.rest.core.RestWrapper;
+import org.alfresco.rest.model.site.RMSite;
+import org.alfresco.rest.requests.RMSiteAPI;
+import org.alfresco.utility.constants.UserRole;
+import org.alfresco.utility.data.DataUser;
+import org.alfresco.utility.data.RandomData;
+import org.alfresco.utility.model.UserModel;
+import org.alfresco.utility.report.Bug;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.testng.annotations.Test;
+
+/**
+ * This class contains the tests for
+ * the RM site CRUD API
+ *
+ * @author Rodica Sutu
+ * @since 1.0
+ */
+public class RMSiteTests extends BaseRestTest
+{
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private RMSiteAPI rmSiteAPI;
+
+    @Autowired
+    private DataUser dataUser;
+
+    /**
+     * Given that RM module is installed
+     * When I want to create the RM site with specific title, description and compliance
+     * Then the RM site is created
+     */
+    @Test
+    (
+        description = "Create RM site with Standard Compliance as admin user"
+    )
+    public void createRMSiteAsAdminUser() throws Exception
+    {
+        // Authenticate with admin user
+        rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Check if the RM site exists
+        if (siteRMExists())
+        {
+            // Delete the RM site
+            rmSiteAPI.deleteRMSite();
+        }
+
+        // Build the RM site properties
+        JsonObject rmSiteProperties = buildObject()
+                .add(TITLE, RM_TITLE)
+                .add(DESCRIPTION, RM_DESCRIPTION)
+                .add(COMPLIANCE, STANDARD.toString())
+                .getJson();
+
+        // Create the RM site
+        RMSite rmSite = rmSiteAPI.createRMSite(rmSiteProperties);
+
+        // Verify the status code
+        rmSiteAPI.usingRestWrapper().assertStatusCodeIs(CREATED);
+
+        // Verify the returned file plan component
+        assertEquals(rmSite.getId(), RM_ID);
+        assertEquals(rmSite.getTitle(), RM_TITLE);
+        assertEquals(rmSite.getDescription(), RM_DESCRIPTION);
+        assertEquals(rmSite.getCompliance(), STANDARD);
+        assertEquals(rmSite.getVisibility(), PUBLIC);
+        assertEquals(rmSite.getRole(), UserRole.SiteManager.toString());
+    }
+
+    /**
+     * Given that RM site exists
+     * When I want to  create the RM site
+     * Then the response code 409 (Site with the given identifier already exists) is return
+     */
+    @Test
+    (
+        description = "Create RM site when site already exist with admin user"
+    )
+    public void createRMSiteWhenSiteExists() throws Exception
+    {
+        // Create the RM site if it does not exist
+        createRMSiteIfNotExists();
+
+        // Authenticate with admin user
+        RestWrapper restWrapper = rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Construct new properties
+        String newTitle = RM_TITLE + "createRMSiteWhenSiteExists";
+        String newDescription = RM_DESCRIPTION + "createRMSiteWhenSiteExists";
+
+        // Build the RM site properties
+        JsonObject rmSiteProperties = buildObject()
+                .add(TITLE, newTitle)
+                .add(DESCRIPTION, newDescription)
+                .add(COMPLIANCE, STANDARD.toString())
+                .getJson();
+
+        // Create the RM site
+        rmSiteAPI.createRMSite(rmSiteProperties);
+
+        // Verify the status code
+        restWrapper.assertStatusCodeIs(CONFLICT);
+    }
+
+    /**
+     * Given that RM site exists
+     * When I want to delete the RM site
+     * Then RM site is successfully deleted
+     */
+    @Test
+    (
+        description = "Delete RM site as admin user"
+    )
+    public void deleteRMSite() throws Exception
+    {
+        // Authenticate with admin user
+        RestWrapper restWrapper = rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Delete the RM site
+        rmSiteAPI.deleteRMSite();
+
+        // Verify the status code
+        restWrapper.assertStatusCodeIs(NO_CONTENT);
+    }
+
+    /**
+     * Given that RM site exists
+     * When I GET the retrieve the RM site details
+     * Then RM site details are returned
+     */
+    @Test
+    (
+        description = "GET the RM site as admin user"
+    )
+    public void getRMSite() throws Exception
+    {
+        // Authenticate with admin user
+        RestWrapper restWrapper = rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Get the RM site
+        RMSite rmSite = rmSiteAPI.getSite();
+        if (!siteRMExists())
+        {
+            // Verify the status code when RM site  doesn't exist
+            restWrapper.assertStatusCodeIs(NOT_FOUND);
+            createRMSiteIfNotExists();
+        }
+        else
+        {
+            // Verify the status code
+            restWrapper.assertStatusCodeIs(OK);
+            assertEquals(rmSite.getId(), RM_ID);
+            assertEquals(rmSite.getDescription(), RM_DESCRIPTION);
+            assertEquals(rmSite.getCompliance(), STANDARD);
+            assertEquals(rmSite.getVisibility(), PUBLIC);
+        }
+    }
+
+    /**
+     * Given that an user is created and RM site doesn't exist
+     * When the user wants to create a RM site with DOD compliance
+     * Then RM site is created
+     */
+    @Test
+    (
+        description = "Create RM site with DOD compliance as an another admin user"
+    )
+    @Bug (id="RM-4289")
+    public void createRMSiteAsAnotherAdminUser() throws Exception
+    {
+        // Authenticate with admin user
+        rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Check if the RM site exists
+        if (siteRMExists())
+        {
+            // Delete the RM site
+            rmSiteAPI.deleteRMSite();
+        }
+
+        // Disconnect the current user from the API session
+        rmSiteAPI.usingRestWrapper().disconnect();
+
+        // Create user
+        userService.create(dataUser.getAdminUser().getUsername(),
+                dataUser.getAdminUser().getPassword(),
+                ANOTHER_ADMIN,
+                DEFAULT_PASSWORD,
+                DEFAULT_EMAIL,
+                ANOTHER_ADMIN,
+                ANOTHER_ADMIN);
+
+        // Build the user model
+        UserModel userModel = new UserModel(ANOTHER_ADMIN,DEFAULT_PASSWORD);
+
+        // Authenticate as that new user
+        rmSiteAPI.usingRestWrapper().authenticateUser(userModel);
+
+        // Build the RM site properties
+        JsonObject rmSiteProperties = buildObject()
+                .add(TITLE, RM_TITLE)
+                .add(DESCRIPTION, RM_DESCRIPTION)
+                .add(COMPLIANCE, DOD5015.toString())
+                .getJson();
+
+        // Create the RM site
+        RMSite rmSite = rmSiteAPI.createRMSite(rmSiteProperties);
+
+        // Verify the status code
+        rmSiteAPI.usingRestWrapper().assertStatusCodeIs(CREATED);
+
+        // Verify the returned file plan component
+        assertEquals(rmSite.getId(), RM_ID);
+        assertEquals(rmSite.getTitle(), RM_TITLE);
+        assertEquals(rmSite.getDescription(), RM_DESCRIPTION);
+        assertEquals(rmSite.getCompliance(), DOD5015);
+        assertEquals(rmSite.getVisibility(), PUBLIC);
+        assertEquals(rmSite.getRole(), UserRole.SiteManager.toString());
+    }
+
+    /**
+     * Given that RM site exist
+     * When a non-RM user wants to update the RM site details (title or description)
+     * Then 403 response status code is return
+     * When the admin user wants to update the RM site details (title or description)
+     * Then RM site details are updated
+     */
+    @Test
+    public void updateRMSiteDetails()throws Exception
+    {
+        String NEW_TITLE = RM_TITLE + RandomData.getRandomAlphanumeric();
+        String NEW_DESCRIPTION=RM_DESCRIPTION+ RandomData.getRandomAlphanumeric();
+
+        // Build the RM site properties
+        JsonObject rmSiteToUpdate = buildObject()
+                .add(TITLE, NEW_TITLE)
+                .add(DESCRIPTION, NEW_DESCRIPTION)
+                .getJson();
+
+        // Authenticate with admin user
+        rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Create the site if it does not exist
+        createRMSiteIfNotExists();
+
+        // Disconnect the user from the API session
+        rmSiteAPI.usingRestWrapper().disconnect();
+
+        // Create a random user
+        UserModel nonRMuser = dataUser.createRandomTestUser("testUser");
+
+        // Authenticate as that random user
+        rmSiteAPI.usingRestWrapper().authenticateUser(nonRMuser);
+
+        // Create the RM site
+        RMSite rmSite = rmSiteAPI.updateRMSite(rmSiteToUpdate);
+
+        // Verify the status code
+        rmSiteAPI.usingRestWrapper().assertStatusCodeIs(FORBIDDEN);
+
+        // Disconnect the user from the API session
+        rmSiteAPI.usingRestWrapper().disconnect();
+
+        // Authenticate with admin user
+        rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Update the RM Site
+        rmSite = rmSiteAPI.updateRMSite(rmSiteToUpdate);
+
+        // Verify the response status code
+        rmSiteAPI.usingRestWrapper().assertStatusCodeIs(OK);
+
+        // Verify the returned file plan component
+        assertEquals(rmSite.getId(), RM_ID);
+        assertEquals(rmSite.getTitle(), NEW_TITLE);
+        assertEquals(rmSite.getDescription(), NEW_DESCRIPTION);
+        assertNotNull(rmSite.getCompliance());
+        assertEquals(rmSite.getVisibility(), PUBLIC);
+    }
+
+    /**
+     * Given that RM site exist
+     * When the admin user wants to update the RM site compliance
+     * Then RM site compliance is not updated
+     */
+    @Test
+    public void updateRMSiteComplianceAsAdmin() throws Exception
+    {
+        // Authenticate with admin user
+        rmSiteAPI.usingRestWrapper().authenticateUser(dataUser.getAdminUser());
+
+        // Create the RM site if it does not exist
+        createRMSiteIfNotExists();
+
+        // Build the RM site properties
+        JsonObject rmSiteToUpdate = buildObject()
+                .add(COMPLIANCE, DOD5015.toString())
+                .getJson();
+
+        // Update the RM site
+        rmSiteAPI.updateRMSite(rmSiteToUpdate);
+
+        // Verify the response status code
+        rmSiteAPI.usingRestWrapper().assertStatusCodeIs(BAD_REQUEST);
+    }
+}
diff --git a/rm-automation/rm-automation-community-rest-api/src/test/resources/default.properties b/rm-automation/rm-automation-community-rest-api/src/test/resources/default.properties
new file mode 100644
index 0000000000..911f2a44fc
--- /dev/null
+++ b/rm-automation/rm-automation-community-rest-api/src/test/resources/default.properties
@@ -0,0 +1,25 @@
+#########################################################################
+#           Original property values from default.properties            #
+#########################################################################
+
+# Dataprep related
+alfresco.scheme=http
+alfresco.server=localhost
+alfresco.port=8080
+
+# Credentials
+admin.user=admin
+admin.password=admin
+
+# Rest related
+rest.basePath=alfresco/api/-default-/public/alfresco/versions/1
+rest.workflowPath=alfresco/api/-default-/public/workflow/versions/1
+
+# Database Section
+db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
+db.username = alfresco
+db.password = alfresco
+
+#########################################################################
+
+rest.rmPath=alfresco/api/-default-/public/ig/versions/1
\ No newline at end of file