Merge branch 'master' of https://github.com/DSpace/DSpace into resourcepolicy-DS-4418

This commit is contained in:
Mykhaylo
2020-03-02 09:44:50 +01:00
95 changed files with 3119 additions and 363 deletions

View File

@@ -367,7 +367,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
@Override
public void setWorkflowGroup(Context context, Collection collection, int step, Group group)
throws SQLException, AuthorizeException {
throws SQLException {
Workflow workflow = null;
try {
workflow = workflowFactory.getWorkflow(collection);
@@ -889,4 +889,4 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
throws SQLException {
return collectionDAO.getCollectionsWithBitstreamSizesTotal(context);
}
}
}

View File

@@ -7,29 +7,53 @@
*/
package org.dspace.xmlworkflow;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.handle.service.HandleService;
import org.dspace.utils.DSpace;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.Workflow;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
/**
* The workflowfactory is responsible for parsing the
* workflow xml file and is used to retrieve the workflow for
* a certain collection
* The workflowfactory is responsible for parsing the workflow xml file and is used to retrieve info about the workflow:
* - the workflow for a certain collection
* - collections mapped to a certain workflow
* - collections not mapped to any workflow
* - configured workflows and the default workflow
* - workflow action by name
*
* @author Bram De Schouwer (bram.deschouwer at dot com)
* @author Kevin Van de Velde (kevin at atmire dot com)
* @author Ben Bosman (ben at atmire dot com)
* @author Mark Diggory (markd at atmire dot com)
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
public static final String LEGACY_WORKFLOW_NAME = "defaultWorkflow";
private Logger log = org.apache.logging.log4j.LogManager.getLogger(XmlWorkflowFactoryImpl.class);
private Map<String, Workflow> workflowMapping;
@Autowired
protected CollectionService collectionService;
@Autowired
protected HandleService handleService;
@Override
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException {
// Attempt to retrieve our workflow object
@@ -50,4 +74,93 @@ public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
public void setWorkflowMapping(Map<String, Workflow> workflowMapping) {
this.workflowMapping = workflowMapping;
}
}
@Override
public Workflow getWorkflowByName(String workflowName) throws WorkflowConfigurationException {
for (Workflow workflow : workflowMapping.values()) {
if (workflow.getID().equals(workflowName)) {
return workflow;
}
}
throw new WorkflowConfigurationException(
"Error while retrieving workflow by the following name: " + workflowName);
}
@Override
public Workflow getDefaultWorkflow() {
return this.workflowMapping.get(LEGACY_WORKFLOW_NAME);
}
@Override
public List<Workflow> getAllConfiguredWorkflows() {
return new ArrayList<>(this.workflowMapping.values());
}
@Override
public List<Collection> getCollectionHandlesMappedToWorklow(Context context, String workflowName) {
List<Collection> collectionsMapped = new ArrayList<>();
for (String handle : this.workflowMapping.keySet()) {
if (this.workflowMapping.get(handle).getID().equals(workflowName)) {
try {
Collection collection = (Collection) handleService.resolveToObject(context, handle);
if (collection != null) {
collectionsMapped.add(collection);
}
} catch (SQLException e) {
log.error("SQLException in XmlWorkflowFactoryImpl.getCollectionHandlesMappedToWorklow trying to " +
"retrieve collection with handle: " + handle, e);
}
}
}
return collectionsMapped;
}
@Override
public List<Collection> getAllNonMappedCollectionsHandles(Context context) {
List<Collection> nonMappedCollections = new ArrayList<>();
try {
for (Collection collection : this.collectionService.findAll(context)) {
if (workflowMapping.get(collection.getHandle()) == null) {
nonMappedCollections.add(collection);
}
}
} catch (SQLException e) {
log.error("SQLException in XmlWorkflowFactoryImpl.getAllNonMappedCollectionsHandles trying to " +
"retrieve all collections", e);
}
return nonMappedCollections;
}
@Override
public boolean workflowByThisNameExists(String workflowName) {
for (Workflow workflow : this.workflowMapping.values()) {
if (workflow.getID().equals(workflowName)) {
return true;
}
}
return false;
}
@Override
public boolean isDefaultWorkflow(String workflowName) {
if (StringUtils.isNotBlank(workflowName)) {
Workflow defaultWorkflow = this.getDefaultWorkflow();
if (defaultWorkflow != null && StringUtils.isNotBlank(defaultWorkflow.getID())) {
return (defaultWorkflow.getID().equals(workflowName));
}
}
return false;
}
@Override
public WorkflowActionConfig getActionByName(String workflowActionName) {
return new DSpace().getServiceManager().getServiceByName(workflowActionName, WorkflowActionConfig.class);
}
@Override
public Step getStepByName(String workflowStepName) {
return new DSpace().getServiceManager().getServiceByName(workflowStepName, Step.class);
}
}

View File

@@ -7,23 +7,31 @@
*/
package org.dspace.xmlworkflow.factory;
import java.util.List;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.Workflow;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
/**
* The xmlworkflowfactory is responsible for parsing the
* workflow xml file and is used to retrieve the workflow for
* a certain collection
* The workflowfactory is responsible for parsing the workflow xml file and is used to retrieve info about the workflow:
* - the workflow for a certain collection
* - collections mapped to a certain workflow
* - collections not mapped to any workflow
* - configured workflows and the default workflow
* - workflow action by name
*
* @author Bram De Schouwer (bram.deschouwer at dot com)
* @author Kevin Van de Velde (kevin at atmire dot com)
* @author Ben Bosman (ben at atmire dot com)
* @author Mark Diggory (markd at atmire dot com)
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
public interface XmlWorkflowFactory {
/**
* Retrieve the workflow configuration for a single collection
*
@@ -32,4 +40,74 @@ public interface XmlWorkflowFactory {
* @throws WorkflowConfigurationException occurs if there is a configuration error in the workflow
*/
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException;
/**
* Retrieves the workflow configuration by name
*
* @param workflowName the name for which we want our workflow
* @return the workflow configuration
* @throws WorkflowConfigurationException occurs if there is no workflow configured by that name
*/
public Workflow getWorkflowByName(String workflowName) throws WorkflowConfigurationException;
/**
* Creates a list of all configured workflows, or returns the cache of this if it was already created
*
* @return List of all configured workflows
*/
public List<Workflow> getAllConfiguredWorkflows();
/**
* Check to see if there is a workflow configured by the given name
*
* @param workflowName Name of a possible configured workflow
* @return True if there is a workflow configured by this name, false otherwise
*/
public boolean workflowByThisNameExists(String workflowName);
/**
* Check to see if the given workflowName is the workflow configured to be default for collections
*
* @param workflowName Name of workflow to check if default
* @return True if given workflowName is the workflow mapped to default for collections, otherwise false
*/
public boolean isDefaultWorkflow(String workflowName);
/**
* Gets the default workflow, i.e. the workflow that is mapped to collection=default in workflow.xml
*/
public Workflow getDefaultWorkflow();
/**
* Return a list of collections that are mapped to the given workflow in the workflow configuration.
* * Makes use of a cache so it only retrieves the workflowName->List<collectionHandle> if it's not cached
*
* @param context Dspace context
* @param workflowName Name of workflow we want the collections of that are mapped to is
* @return List of collections mapped to the requested workflow
*/
public List<Collection> getCollectionHandlesMappedToWorklow(Context context, String workflowName);
/**
* Returns list of collections that are not mapped to any configured workflow, and thus use the default workflow
*
* @return List of collections not mapped to any workflow
*/
public List<Collection> getAllNonMappedCollectionsHandles(Context context);
/**
* Retrieves a {@link WorkflowActionConfig} object based on its name, should correspond with bean id in workflow-actions.xml
*
* @param workflowActionName Name of workflow action we want to retrieve
* @return Workflow action object corresponding to the given workflowActionName
*/
public WorkflowActionConfig getActionByName(String workflowActionName);
/**
* Retrieves a {@link Step} object based on its name, should correspond with bean id in workflow.xml
*
* @param workflowStepName Name of workflow step we want to retrieve
* @return Workflow step object corresponding to the given workflowStepName
*/
public Step getStepByName(String workflowStepName);
}

View File

@@ -36,8 +36,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
public abstract class Action {
private WorkflowActionConfig parent;
private static String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields";
private static final String ERROR_FIELDS_ATTRIBUTE = "dspace.workflow.error_fields";
public abstract void activate(Context c, XmlWorkflowItem wf)
throws SQLException, IOException, AuthorizeException, WorkflowException;
@@ -45,6 +44,12 @@ public abstract class Action {
public abstract ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException;
/**
* Returns a list of options that the user can select at this action which results in the next step in the workflow
* @return A list of options of this action, resulting in the next step of the workflow
*/
public abstract List<String> getOptions();
public WorkflowActionConfig getParent() {
return parent;
}

View File

@@ -7,6 +7,8 @@
*/
package org.dspace.xmlworkflow.state.actions;
import java.util.List;
import org.dspace.xmlworkflow.state.Step;
/**
@@ -59,4 +61,12 @@ public class WorkflowActionConfig {
return step;
}
/**
* Returns a list of options the user has on this action, resulting in the next step of the workflow
* @return A list of options of this action, resulting in the next step of the workflow
*/
public List<String> getOptions() {
return this.processingAction.getOptions();
}
}

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException;
@@ -31,40 +33,49 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/
public class AcceptEditRejectAction extends ProcessingAction {
public static final int MAIN_PAGE = 0;
public static final int REJECT_PAGE = 1;
private static final String SUBMIT_APPROVE = "submit_approve";
private static final String SUBMIT_REJECT = "submit_reject";
//TODO: rename to AcceptAndEditMetadataAction
@Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
throws SQLException, AuthorizeException, IOException {
if (request.getParameter("submit_approve") != null) {
return processAccept(c, wfi, step, request);
if (request.getParameter(SUBMIT_APPROVE) != null) {
return processAccept(c, wfi);
} else {
if (request.getParameter("submit_reject") != null) {
return processRejectPage(c, wfi, step, request);
if (request.getParameter(SUBMIT_REJECT) != null) {
return processRejectPage(c, wfi, request);
}
}
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
}
public ActionResult processAccept(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException {
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
options.add(ProcessingAction.SUBMIT_EDIT_METADATA);
return options;
}
public ActionResult processAccept(Context c, XmlWorkflowItem wfi)
throws SQLException, AuthorizeException {
//Delete the tasks
addApprovedProvenance(c, wfi);
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
public ActionResult processRejectPage(Context c, XmlWorkflowItem wfi, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
String reason = request.getParameter("reason");
if (reason == null || 0 == reason.trim().length()) {
addErrorField(request, "reason");
@@ -85,14 +96,14 @@ public class AcceptEditRejectAction extends ProcessingAction {
// Get user's name + email address
String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService()
.getEPersonName(c.getCurrentUser());
.getEPersonName(c.getCurrentUser());
String provDescription = getProvenanceStartId() + " Approved for entry into archive by "
+ usersName + " on " + now + " (GMT) ";
+ usersName + " on " + now + " (GMT) ";
// Add to item as a DC field
itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en",
provDescription);
provDescription);
itemService.update(c, wfi.getItem());
}
}

View File

@@ -7,8 +7,9 @@
*/
package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException;
@@ -31,21 +32,22 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/
public class FinalEditAction extends ProcessingAction {
private static final String SUBMIT_APPROVE = "submit_approve";
@Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
throws SQLException, AuthorizeException {
return processMainPage(c, wfi, step, request);
}
public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException {
if (request.getParameter("submit_approve") != null) {
throws SQLException, AuthorizeException {
if (request.getParameter(SUBMIT_APPROVE) != null) {
//Delete the tasks
addApprovedProvenance(c, wfi);
@@ -56,20 +58,28 @@ public class FinalEditAction extends ProcessingAction {
}
}
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(ProcessingAction.SUBMIT_EDIT_METADATA);
return options;
}
private void addApprovedProvenance(Context c, XmlWorkflowItem wfi) throws SQLException, AuthorizeException {
//Add the provenance for the accept
String now = DCDate.getCurrent().toString();
// Get user's name + email address
String usersName = XmlWorkflowServiceFactory.getInstance().getXmlWorkflowService()
.getEPersonName(c.getCurrentUser());
.getEPersonName(c.getCurrentUser());
String provDescription = getProvenanceStartId() + " Approved for entry into archive by "
+ usersName + " on " + now + " (GMT) ";
+ usersName + " on " + now + " (GMT) ";
// Add to item as a DC field
itemService.addMetadata(c, wfi.getItem(), MetadataSchemaEnum.DC.getName(), "description", "provenance", "en",
provDescription);
provDescription);
itemService.update(c, wfi.getItem());
}

View File

@@ -34,6 +34,7 @@ public abstract class ProcessingAction extends Action {
@Autowired(required = true)
protected ItemService itemService;
protected static final String SUBMIT_EDIT_METADATA = "submit_edit_metadata";
@Override
public boolean isAuthorized(Context context, HttpServletRequest request, XmlWorkflowItem wfi) throws SQLException {

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -34,6 +36,8 @@ public class ReviewAction extends ProcessingAction {
public static final int MAIN_PAGE = 0;
public static final int REJECT_PAGE = 1;
private static final String SUBMIT_APPROVE = "submit_approve";
private static final String SUBMIT_REJECT = "submit_reject";
@Override
public void activate(Context c, XmlWorkflowItem wfItem) {
@@ -43,10 +47,10 @@ public class ReviewAction extends ProcessingAction {
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
if (request.getParameter("submit_approve") != null) {
if (request.getParameter(SUBMIT_APPROVE) != null) {
return processAccept(c, wfi, step, request);
} else {
if (request.getParameter("submit_reject") != null) {
if (request.getParameter(SUBMIT_REJECT) != null) {
return processRejectPage(c, wfi, step, request);
}
}
@@ -54,6 +58,14 @@ public class ReviewAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
}
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
return options;
}
public ActionResult processAccept(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException {
//Delete the tasks

View File

@@ -9,6 +9,7 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -17,7 +18,6 @@ import org.dspace.content.Item;
import org.dspace.content.MetadataSchemaEnum;
import org.dspace.content.MetadataValue;
import org.dspace.core.Context;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.service.WorkflowRequirementsService;
import org.dspace.xmlworkflow.state.Step;
@@ -40,14 +40,13 @@ public class ScoreEvaluationAction extends ProcessingAction {
private int minimumAcceptanceScore;
@Override
public void activate(Context c, XmlWorkflowItem wf)
throws SQLException, IOException, AuthorizeException, WorkflowException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException {
throws SQLException, AuthorizeException, IOException {
boolean hasPassed = false;
//Retrieve all our scores from the metadata & add em up
List<MetadataValue> scores = itemService
@@ -82,6 +81,11 @@ public class ScoreEvaluationAction extends ProcessingAction {
}
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
public int getMinimumAcceptanceScore() {
return minimumAcceptanceScore;
}

View File

@@ -7,14 +7,14 @@
*/
package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.util.Util;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.service.WorkflowRequirementsService;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult;
@@ -32,20 +32,21 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
*/
public class ScoreReviewAction extends ProcessingAction {
private static final String SUBMIT_SCORE = "submit_score";
@Override
public void activate(Context c, XmlWorkflowItem wf)
throws SQLException, IOException, AuthorizeException, WorkflowException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException {
if (request.getParameter("submit_score") != null) {
throws SQLException, AuthorizeException {
if (request.getParameter(SUBMIT_SCORE) != null) {
int score = Util.getIntParameter(request, "score");
//Add our score to the metadata
itemService.addMetadata(c, wfi.getItem(), WorkflowRequirementsService.WORKFLOW_SCHEMA, "score", null, null,
String.valueOf(score));
String.valueOf(score));
itemService.update(c, wfi.getItem());
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
@@ -54,4 +55,9 @@ public class ScoreReviewAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_SUBMISSION_PAGE);
}
}
@Override
public List<String> getOptions() {
return Arrays.asList(SUBMIT_SCORE);
}
}

View File

@@ -7,8 +7,8 @@
*/
package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
@@ -18,7 +18,6 @@ import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.service.EPersonService;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.Role;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult;
@@ -39,36 +38,38 @@ import org.springframework.beans.factory.annotation.Required;
*/
public class SelectReviewerAction extends ProcessingAction {
public static final int MAIN_PAGE = 0;
public static final int SEARCH_RESULTS_PAGE = 1;
public static final int RESULTS_PER_PAGE = 5;
private static final String SUBMIT_CANCEL = "submit_cancel";
private static final String SUBMIT_SEARCH = "submit_search";
private static final String SUBMIT_SELECT_REVIEWER = "submit_select_reviewer_";
private Role role;
@Autowired(required = true)
protected EPersonService ePersonService;
private EPersonService ePersonService;
@Autowired(required = true)
protected WorkflowItemRoleService workflowItemRoleService;
private WorkflowItemRoleService workflowItemRoleService;
@Override
public void activate(Context c, XmlWorkflowItem wf)
throws SQLException, IOException, AuthorizeException, WorkflowException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException, WorkflowException {
String submitButton = Util.getSubmitButton(request, "submit_cancel");
throws SQLException, AuthorizeException {
String submitButton = Util.getSubmitButton(request, SUBMIT_CANCEL);
//Check if our user has pressed cancel
if (submitButton.equals("submit_cancel")) {
if (submitButton.equals(SUBMIT_CANCEL)) {
//Send us back to the submissions page
return new ActionResult(ActionResult.TYPE.TYPE_CANCEL);
} else if (submitButton.equals("submit_search")) {
} else if (submitButton.equals(SUBMIT_SEARCH)) {
//Perform the search
String query = request.getParameter("query");
int page = Util.getIntParameter(request, "result-page");
@@ -85,7 +86,7 @@ public class SelectReviewerAction extends ProcessingAction {
request.setAttribute("result-page", page);
request.setAttribute("page", SEARCH_RESULTS_PAGE);
return new ActionResult(ActionResult.TYPE.TYPE_PAGE, SEARCH_RESULTS_PAGE);
} else if (submitButton.startsWith("submit_select_reviewer_")) {
} else if (submitButton.startsWith(SUBMIT_SELECT_REVIEWER)) {
//Retrieve the identifier of the eperson which will do the reviewing
UUID reviewerId = UUID.fromString(submitButton.substring(submitButton.lastIndexOf("_") + 1));
EPerson reviewer = ePersonService.find(c, reviewerId);
@@ -102,6 +103,14 @@ public class SelectReviewerAction extends ProcessingAction {
return new ActionResult(ActionResult.TYPE.TYPE_ERROR);
}
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_SEARCH);
options.add(SUBMIT_SELECT_REVIEWER);
return options;
}
public Role getRole() {
return role;
}

View File

@@ -9,6 +9,8 @@ package org.dspace.xmlworkflow.state.actions.processingaction;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.util.Util;
@@ -38,6 +40,10 @@ public class SingleUserReviewAction extends ProcessingAction {
public static final int OUTCOME_REJECT = 1;
protected static final String SUBMIT_APPROVE = "submit_approve";
protected static final String SUBMIT_REJECT = "submit_reject";
protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task";
@Override
public void activate(Context c, XmlWorkflowItem wfItem) {
@@ -58,19 +64,28 @@ public class SingleUserReviewAction extends ProcessingAction {
}
}
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
options.add(SUBMIT_APPROVE);
options.add(SUBMIT_REJECT);
options.add(SUBMIT_DECLINE_TASK);
return options;
}
public ActionResult processMainPage(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException {
if (request.getParameter("submit_approve") != null) {
if (request.getParameter(SUBMIT_APPROVE) != null) {
//Delete the tasks
addApprovedProvenance(c, wfi);
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
} else if (request.getParameter("submit_reject") != null) {
} else if (request.getParameter(SUBMIT_REJECT) != null) {
// Make sure we indicate which page we want to process
request.setAttribute("page", REJECT_PAGE);
// We have pressed reject item, so take the user to a page where he can reject
return new ActionResult(ActionResult.TYPE.TYPE_PAGE);
} else if (request.getParameter("submit_decline_task") != null) {
} else if (request.getParameter(SUBMIT_DECLINE_TASK) != null) {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, OUTCOME_REJECT);
} else {

View File

@@ -8,6 +8,8 @@
package org.dspace.xmlworkflow.state.actions.userassignment;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.core.Context;
@@ -34,6 +36,11 @@ public class AssignAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
public void generateTasks() {
}

View File

@@ -9,7 +9,9 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
@@ -112,6 +114,11 @@ public class AssignOriginalSubmitterAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
/**
* Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item
*

View File

@@ -9,6 +9,7 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
@@ -106,6 +107,11 @@ public class AutoAssignAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
/**
* Create a claimed task for the user IF this user doesn't have a claimed action for this workflow item
*

View File

@@ -10,6 +10,7 @@ package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
@@ -67,6 +68,11 @@ public class ClaimAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
@Override
public void alertUsersOnActivation(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers)
throws IOException, SQLException {

View File

@@ -8,6 +8,8 @@
package org.dspace.xmlworkflow.state.actions.userassignment;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.core.Context;
@@ -37,6 +39,11 @@ public class InheritUsersAction extends UserSelectionAction {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
@Override
public boolean isFinished(XmlWorkflowItem wfi) {
return false;

View File

@@ -7,14 +7,12 @@
*/
package org.dspace.xmlworkflow.state.actions.userassignment;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.RoleMembers;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.state.Step;
import org.dspace.xmlworkflow.state.actions.ActionResult;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
@@ -34,12 +32,11 @@ public class NoUserSelectionAction extends UserSelectionAction {
}
@Override
public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) throws SQLException {
public void regenerateTasks(Context c, XmlWorkflowItem wfi, RoleMembers roleMembers) {
}
@Override
public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI)
throws WorkflowConfigurationException, SQLException {
public boolean isValidUserSelection(Context context, XmlWorkflowItem wfi, boolean hasUI) {
return true;
}
@@ -49,12 +46,16 @@ public class NoUserSelectionAction extends UserSelectionAction {
}
@Override
public void activate(Context c, XmlWorkflowItem wf) throws SQLException, IOException {
public void activate(Context c, XmlWorkflowItem wf) {
}
@Override
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request)
throws SQLException, AuthorizeException, IOException {
public ActionResult execute(Context c, XmlWorkflowItem wfi, Step step, HttpServletRequest request) {
return new ActionResult(ActionResult.TYPE.TYPE_OUTCOME, ActionResult.OUTCOME_COMPLETE);
}
@Override
public List<String> getOptions() {
return new ArrayList<>();
}
}

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="claimactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.ClaimAction" scope="prototype"/>
<bean id="reviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ReviewAction" scope="prototype"/>
<bean id="editactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.AcceptEditRejectAction" scope="prototype"/>
<bean id="finaleditactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.FinalEditAction" scope="prototype"/>
<bean id="singleuserreviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SingleUserReviewAction" scope="prototype"/>
<bean id="selectrevieweractionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SelectReviewerAction" scope="prototype">
<property name="role" ref="scoreAssignedReviewer"/>
</bean>
<bean id="scorereviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreReviewAction" scope="prototype"/>
<bean id="evaluationactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreEvaluationAction" scope="prototype">
<property name="minimumAcceptanceScore" value="50" />
</bean>
<bean id="autoassignactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AutoAssignAction" scope="prototype"/>
<bean id="noUserSelectionActionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.NoUserSelectionAction" scope="prototype"/>
<bean id="assignoriginalsubmitteractionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AssignOriginalSubmitterAction" scope="prototype"/>
<bean id="reviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="reviewaction"/>
<property name="processingAction" ref="reviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="editaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="editaction"/>
<property name="processingAction" ref="editactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="finaleditaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="finaleditaction"/>
<property name="processingAction" ref="finaleditactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<!--Action for the select single reviewer workflow -->
<bean id="selectrevieweraction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="selectrevieweraction"/>
<property name="processingAction" ref="selectrevieweractionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="singleuserreviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="singleuserreviewaction"/>
<property name="processingAction" ref="singleuserreviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="scorereviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="scorereviewaction"/>
<property name="processingAction" ref="scorereviewactionAPI" />
<property name="requiresUI" value="true"/>
</bean>
<!--Autmatic step that evaluates scores (workflow.score) and checks if they match the configured minimum for archiving -->
<bean id="evaluationaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="evaluationaction"/>
<property name="processingAction" ref="evaluationactionAPI" />
<property name="requiresUI" value="false"/>
</bean>
<!--User selection actions-->
<bean id="claimaction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="claimaction"/>
<property name="processingAction" ref="claimactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="autoassignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="autoassignAction"/>
<property name="processingAction" ref="autoassignactionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="noUserSelectionAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="noUserSelectionAction"/>
<property name="processingAction" ref="noUserSelectionActionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="originalSubmitterAssignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value=""/>
<property name="processingAction" ref="assignoriginalsubmitteractionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
</beans>

View File

@@ -9,8 +9,8 @@
<util:map>
<entry key="defaultWorkflow"
value-ref="defaultWorkflow"/>
<entry key="123456789/4" value-ref="selectSingleReviewer"/>
<!-- <entry key="123456789/5" value-ref="scoreReview"/>-->
<entry key="123456789/workflow-test-1" value-ref="selectSingleReviewer"/>
<!-- <entry key="123456789/5" value-ref="scoreReview"/>-->
</util:map>
</property>
</bean>

View File

@@ -25,6 +25,7 @@ import org.dspace.utils.DSpace;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -42,6 +43,8 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
= new DSpace().getServiceManager().getServiceByName("xmlWorkflowFactory",
XmlWorkflowFactoryImpl.class);
private Community owningCommunity;
private Collection mappedCollection;
private Collection nonMappedCollection;
/**
* log4j category
@@ -63,6 +66,9 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
//we have to create a new community in the database
context.turnOffAuthorisationSystem();
this.owningCommunity = communityService.create(null, context);
this.mappedCollection =
this.collectionService.create(context, owningCommunity, "123456789/workflow-test-1");
this.nonMappedCollection = this.collectionService.create(context, owningCommunity, "123456789/999");
//we need to commit the changes so we don't block the table for testing
context.restoreAuthSystemState();
} catch (SQLException e) {
@@ -74,38 +80,46 @@ public class XmlWorkflowFactoryTest extends AbstractUnitTest {
}
}
/**
* This method will be run after every test as per @After. It will
* clean resources initialized by the @Before methods.
*
* Other methods can be annotated with @After here or in subclasses
* but no execution order is guaranteed
*/
@After
@Override
public void destroy() {
context.turnOffAuthorisationSystem();
try {
this.collectionService.delete(context, this.nonMappedCollection);
this.collectionService.delete(context, this.mappedCollection);
this.communityService.delete(context, this.owningCommunity);
} catch (Exception e) {
log.error("Error in destroy", e);
}
context.restoreAuthSystemState();
this.owningCommunity = null;
this.nonMappedCollection = null;
this.mappedCollection = null;
try {
super.destroy();
} catch (Exception e) {
log.error("Error in destroy", e);
}
}
@Test
public void workflowMapping_NonMappedCollection() throws WorkflowConfigurationException {
Collection collection = this.findOrCreateCollectionWithHandle("123456789/6");
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection);
assertEquals("defaultWorkflow", workflow.getID());
Workflow workflow = xmlWorkflowFactory.getWorkflow(this.nonMappedCollection);
assertEquals(workflow.getID(), "defaultWorkflow");
}
@Test
public void workflowMapping_MappedCollection() throws WorkflowConfigurationException {
Collection collection = this.findOrCreateCollectionWithHandle("123456789/4");
Workflow workflow = xmlWorkflowFactory.getWorkflow(collection);
assertEquals("selectSingleReviewer", workflow.getID());
}
private Collection findOrCreateCollectionWithHandle(String handle) {
try {
context.turnOffAuthorisationSystem();
for (Collection collection : this.collectionService.findAll(context)) {
if (collection.getHandle().equalsIgnoreCase(handle)) {
return collection;
}
}
Collection collection = this.collectionService.create(context, owningCommunity, handle);
context.restoreAuthSystemState();
return collection;
} catch (SQLException e) {
log.error("SQL Error in findOrCreateCollectionWithHandle", e);
fail("SQL Error in findOrCreateCollectionWithHandle: " + e.getMessage());
} catch (AuthorizeException e) {
log.error("Authorization Error in findOrCreateCollectionWithHandle", e);
fail("Authorization Error in findOrCreateCollectionWithHandle: " + e.getMessage());
}
return null;
Workflow workflow = xmlWorkflowFactory.getWorkflow(this.mappedCollection);
assertEquals(workflow.getID(), "selectSingleReviewer");
}
}

View File

@@ -15,7 +15,7 @@
<properties>
<!-- This is the path to the root [dspace-src] directory. -->
<root.basedir>${basedir}/..</root.basedir>
<xoai.version>3.2.11</xoai.version>
<xoai.version>3.3.0</xoai.version>
<jtwig.version>5.87.0.RELEASE</jtwig.version>
</properties>
@@ -89,7 +89,7 @@
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
@@ -103,6 +103,11 @@
<groupId>org.codehaus.woodstox</groupId>
<artifactId>wstx-asl</artifactId>
</exclusion>
<!-- Later version provided by Hibernate -->
<exclusion>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>

View File

@@ -26,11 +26,12 @@ public class DSpaceSolrServerResolver implements SolrServerResolver {
@Override
public SolrClient getServer() throws SolrServerException {
if (server == null) {
String serverUrl = configurationService.getProperty("oai.solr.url");
try {
server = new HttpSolrClient.Builder(configurationService.getProperty("oai", "solr.url")).build();
log.debug("Solr Server Initialized");
server = new HttpSolrClient.Builder(serverUrl).build();
log.debug("OAI Solr Server Initialized");
} catch (Exception e) {
log.error(e.getMessage(), e);
log.error("Could not initialize OAI Solr Server at " + serverUrl , e);
}
}
return server;

View File

@@ -30,12 +30,12 @@ public class DSpaceSolrServer {
public static SolrClient getServer() throws SolrServerException {
if (_server == null) {
String serverUrl = ConfigurationManager.getProperty("oai.solr.url");
try {
_server = new HttpSolrClient.Builder(
ConfigurationManager.getProperty("oai", "solr.url")).build();
log.debug("Solr Server Initialized");
_server = new HttpSolrClient.Builder(serverUrl).build();
log.debug("OAI Solr Server Initialized");
} catch (Exception e) {
log.error(e.getMessage(), e);
log.error("Could not initialize OAI Solr Server at " + serverUrl , e);
}
}
return _server;

View File

@@ -27,7 +27,6 @@ import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.hateoas.BitstreamResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.MultipartFileSender;
import org.dspace.app.rest.utils.Utils;
@@ -243,7 +242,7 @@ public class BitstreamRestController {
context.commit();
BitstreamRest bitstreamRest = converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT);
BitstreamRest bitstreamRest = converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
return converter.toResource(bitstreamRest);
}
}

View File

@@ -22,7 +22,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.hateoas.BundleResource;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.ItemRestRepository;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
@@ -108,7 +107,7 @@ public class ItemAddBundleController {
}
Bundle bundle = itemRestRepository.addBundleToItem(context, item, bundleRest);
BundleResource bundleResource = converter.toResource(converter.toRest(bundle, Projection.DEFAULT));
BundleResource bundleResource = converter.toResource(converter.toRest(bundle, utils.obtainProjection()));
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), bundleResource);
}

View File

@@ -21,7 +21,6 @@ import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.Utils;
import org.dspace.authorize.AuthorizeException;
@@ -97,7 +96,7 @@ public class ItemOwningCollectionUpdateRestController {
if (targetCollection == null) {
return null;
}
return converter.toRest(targetCollection, Projection.DEFAULT);
return converter.toRest(targetCollection, utils.obtainProjection());
}

View File

@@ -0,0 +1,82 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.app.rest.utils.Utils;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "collections" subresource of an individual workflow definition.
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME + "."
+ WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO)
public class WorkflowDefinitionCollectionsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
protected ConverterService converter;
@Autowired
protected Utils utils;
/**
* GET endpoint that returns the list of collections that make an explicit use of the workflow-definition.
* If a collection doesn't specify the workflow-definition to be used, the default mapping applies,
* but this collection is not included in the list returned by this method.
*
* @param request The request object
* @param workflowName Name of workflow we want the collections of that are mapped to is
* @return List of collections mapped to the requested workflow
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<CollectionRest> getCollections(@Nullable HttpServletRequest request,
String workflowName,
@Nullable Pageable optionalPageable,
Projection projection) {
if (xmlWorkflowFactory.workflowByThisNameExists(workflowName)) {
Context context = obtainContext();
List<Collection> collectionsMappedToWorkflow = new ArrayList<>();
if (xmlWorkflowFactory.isDefaultWorkflow(workflowName)) {
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context));
}
collectionsMappedToWorkflow.addAll(xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context,
workflowName));
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(collectionsMappedToWorkflow, pageable),
projection);
} else {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
}

View File

@@ -0,0 +1,63 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "steps" subresource of an individual workflow definition.
*
* @author Maria Verdonck (Atmire) on 24/02/2020
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME + "."
+ WorkflowDefinitionRest.STEPS)
public class WorkflowDefinitionStepsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
/**
* GET endpoint that returns the list of steps of a workflow-definition.
*
* @param request The request object
* @param workflowName Name of workflow we want the steps from
* @return List of steps of the requested workflow
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowStepRest> getSteps(@Nullable HttpServletRequest request,
String workflowName,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
List<Step> steps = xmlWorkflowFactory.getWorkflowByName(workflowName).getSteps();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(steps, pageable), projection);
} catch (WorkflowConfigurationException e) {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
}

View File

@@ -0,0 +1,57 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import java.util.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.AbstractDSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* Link repository for "actions" subresource of an individual workflow step.
*
* @author Maria Verdonck (Atmire) on 24/02/2020
*/
@Component(WorkflowStepRest.CATEGORY + "." + WorkflowStepRest.NAME + "."
+ WorkflowStepRest.ACTIONS)
public class WorkflowStepActionsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
/**
* GET endpoint that returns the list of actions of a workflow step.
*
* @param request The request object
* @param workflowStepName Name of workflow step we want the actions from
* @return List of actions of the requested workflow step
*/
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowActionRest> getActions(@Nullable HttpServletRequest request,
String workflowStepName,
@Nullable Pageable optionalPageable,
Projection projection) {
List<WorkflowActionConfig> actions = xmlWorkflowFactory.getStepByName(workflowStepName).getActions();
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(actions, pageable), projection);
}
}

View File

@@ -0,0 +1,36 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.stereotype.Component;
/**
* Converter to translate {@link WorkflowActionConfig} to a {@link WorkflowActionRest} object
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@Component
public class WorkflowActionConverter implements DSpaceConverter<WorkflowActionConfig, WorkflowActionRest> {
@Override
public WorkflowActionRest convert(WorkflowActionConfig modelObject, Projection projection) {
WorkflowActionRest restModel = new WorkflowActionRest();
restModel.setProjection(projection);
restModel.setId(modelObject.getId());
restModel.setOptions(modelObject.getOptions());
return restModel;
}
@Override
public Class<WorkflowActionConfig> getModelClass() {
return WorkflowActionConfig.class;
}
}

View File

@@ -0,0 +1,50 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Converter to translate Workflow to a Workflow Definition
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component
public class WorkflowDefinitionConverter implements DSpaceConverter<Workflow, WorkflowDefinitionRest> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
ConverterService converter;
@Override
public WorkflowDefinitionRest convert(Workflow modelObject, Projection projection) {
WorkflowDefinitionRest restModel = new WorkflowDefinitionRest();
restModel.setName(modelObject.getID());
restModel.setIsDefault(xmlWorkflowFactory.isDefaultWorkflow(modelObject.getID()));
restModel.setProjection(projection);
restModel.setSteps(modelObject.getSteps().stream()
.map(x -> (WorkflowStepRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
return restModel;
}
@Override
public Class<Workflow> getModelClass() {
return Workflow.class;
}
}

View File

@@ -0,0 +1,45 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.converter;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Converter to translate {@link Step} to a {@link WorkflowStepRest} object
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@Component
public class WorkflowStepConverter implements DSpaceConverter<Step, WorkflowStepRest> {
@Autowired
ConverterService converter;
@Override
public WorkflowStepRest convert(Step modelObject, Projection projection) {
WorkflowStepRest restModel = new WorkflowStepRest();
restModel.setProjection(projection);
restModel.setId(modelObject.getId());
restModel.setWorkflowactions(modelObject.getActions().stream()
.map(x -> (WorkflowActionRest) converter.toRest(x, projection))
.collect(Collectors.toList()));
return restModel;
}
@Override
public Class<Step> getModelClass() {
return Step.class;
}
}

View File

@@ -26,6 +26,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = CollectionRest.MAPPED_ITEMS,
method = "getMappedItems"
),
@LinkRest(
name = CollectionRest.PARENT_COMMUNITY,
method = "getParentCommunity"
)
})
public class CollectionRest extends DSpaceObjectRest {
@@ -37,6 +41,7 @@ public class CollectionRest extends DSpaceObjectRest {
public static final String LICENSE = "license";
public static final String LOGO = "logo";
public static final String MAPPED_ITEMS = "mappedItems";
public static final String PARENT_COMMUNITY = "parentCommunity";
@Override
public String getCategory() {

View File

@@ -26,6 +26,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = CommunityRest.SUBCOMMUNITIES,
method = "getSubcommunities"
),
@LinkRest(
name = CommunityRest.PARENT_COMMUNITY,
method = "getParentCommunity"
)
})
public class CommunityRest extends DSpaceObjectRest {
@@ -36,6 +40,8 @@ public class CommunityRest extends DSpaceObjectRest {
public static final String COLLECTIONS = "collections";
public static final String LOGO = "logo";
public static final String SUBCOMMUNITIES = "subcommunities";
public static final String PARENT_COMMUNITY = "parentCommunity";
@Override
public String getCategory() {

View File

@@ -0,0 +1,59 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow actions
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionRest extends BaseObjectRest<String> {
public static final String CATEGORY = "config";
public static final String NAME = "workflowaction";
public static final String NAME_PLURAL = "workflowactions";
private List<String> options;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
/**
* Generic getter for the options
*
* @return the options value of this WorkflowActionRest
*/
public List<String> getOptions() {
return options;
}
/**
* Generic setter for the options
*
* @param options The options to be set on this WorkflowActionRest
*/
public void setOptions(List<String> options) {
this.options = options;
}
}

View File

@@ -0,0 +1,88 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow definitions
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@LinksRest(links = {
@LinkRest(
name = WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO,
method = "getCollections"
),
@LinkRest(
name = WorkflowDefinitionRest.STEPS,
method = "getSteps"
)
})
public class WorkflowDefinitionRest extends BaseObjectRest<String> {
public static final String CATEGORY = "config";
public static final String NAME = "workflowdefinition";
public static final String NAME_PLURAL = "workflowdefinitions";
public static final String COLLECTIONS_MAPPED_TO = "collections";
public static final String STEPS = "steps";
private String name;
private boolean isDefault;
private List<WorkflowStepRest> steps;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
@Override
@JsonIgnore
public String getId() {
return name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean getIsDefault() {
return isDefault;
}
public void setIsDefault(boolean isDefault) {
this.isDefault = isDefault;
}
@JsonIgnore
public List<WorkflowStepRest> getSteps() {
return steps;
}
public void setSteps(List<WorkflowStepRest> steps) {
this.steps = steps;
}
}

View File

@@ -0,0 +1,59 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.RestResourceController;
/**
* The rest resource used for workflow steps
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@LinksRest(links = {
@LinkRest(
name = WorkflowStepRest.ACTIONS,
method = "getActions"
),
})
public class WorkflowStepRest extends BaseObjectRest {
public static final String CATEGORY = "config";
public static final String NAME = "workflowstep";
public static final String NAME_PLURAL = "workflowsteps";
public static final String ACTIONS = "workflowactions";
private List<WorkflowActionRest> workflowactions;
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
@JsonIgnore
public List<WorkflowActionRest> getWorkflowactions() {
return workflowactions;
}
public void setWorkflowactions(List<WorkflowActionRest> actions) {
this.workflowactions = actions;
}
}

View File

@@ -0,0 +1,25 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* {@link WorkflowActionRest} HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@RelNameDSpaceResource(WorkflowActionRest.NAME)
public class WorkflowActionResource extends DSpaceResource<WorkflowActionRest> {
public WorkflowActionResource(WorkflowActionRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,24 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* WorkflowDefinition Rest HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@RelNameDSpaceResource(WorkflowDefinitionRest.NAME)
public class WorkflowDefinitionResource extends DSpaceResource<WorkflowDefinitionRest> {
public WorkflowDefinitionResource(WorkflowDefinitionRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,25 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* {@link WorkflowStepRest} HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links and embedded resources
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@RelNameDSpaceResource(WorkflowStepRest.NAME)
public class WorkflowStepResource extends DSpaceResource<WorkflowStepRest> {
public WorkflowStepResource(WorkflowStepRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -18,7 +18,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamFormatRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.BitstreamFormat;
import org.dspace.content.service.BitstreamFormatService;
@@ -89,7 +88,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
+ bitstreamFormatRest.getShortDescription(), e);
}
return converter.toRest(bitstreamFormat, Projection.DEFAULT);
return converter.toRest(bitstreamFormat, utils.obtainProjection());
}
@Override
@@ -116,7 +115,7 @@ public class BitstreamFormatRestRepository extends DSpaceRestRepository<Bitstrea
if (id.equals(bitstreamFormatRest.getId())) {
this.setAllValuesOfRest(context, bitstreamFormat, bitstreamFormatRest);
bitstreamFormatService.update(context, bitstreamFormat);
return converter.toRest(bitstreamFormat, Projection.DEFAULT);
return converter.toRest(bitstreamFormat, utils.obtainProjection());
} else {
throw new IllegalArgumentException("The id in the Json and the id in the url do not match: "
+ id + ", "

View File

@@ -23,7 +23,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Bitstream;
@@ -150,7 +149,7 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
throw new RuntimeException(message, e);
}
return converter.toRest(bitstream, Projection.DEFAULT);
return converter.toRest(bitstream, utils.obtainProjection());
}
/**

View File

@@ -0,0 +1,64 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CollectionRest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* LinkRepository for the ParentCommunity object for a Collection
*/
@Component(CollectionRest.CATEGORY + "." + CollectionRest.NAME + "." + CollectionRest.PARENT_COMMUNITY)
public class CollectionParentCommunityLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private CollectionService collectionService;
/**
* This method retrieves the ParentCommunity object for the Collection which is defined by the given collectionId
* It'll transform this Parent Community to a REST object and return this
* @param httpServletRequest The current request
* @param collectionId The given Collection UUID that will be used to find the Collection
* @param optionalPageable The pageable
* @param projection The current Projection
* @return The Parent Community REST object
*/
@PreAuthorize("hasPermission(#collectionId, 'COLLECTION', 'READ')")
public CommunityRest getParentCommunity(@Nullable HttpServletRequest httpServletRequest,
UUID collectionId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Collection collection = collectionService.find(context, collectionId);
if (collection == null) {
throw new ResourceNotFoundException("No such collection: " + collectionId);
}
Community parentCommunity = (Community) collectionService.getParentObject(context, collection);
return converter.toRest(parentCommunity, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -27,7 +27,6 @@ import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.model.TemplateItemRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.model.wrapper.TemplateItem;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.CollectionRestEqualityUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
@@ -181,7 +180,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
} catch (SQLException e) {
throw new RuntimeException("Unable to create new Collection under parent Community " + id, e);
}
return converter.toRest(collection, Projection.DEFAULT);
return converter.toRest(collection, utils.obtainProjection());
}
@@ -200,7 +199,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
if (collection == null) {
throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found");
}
CollectionRest originalCollectionRest = converter.toRest(collection, Projection.DEFAULT);
CollectionRest originalCollectionRest = converter.toRest(collection, utils.obtainProjection());
if (collectionRestEqualityUtils.isCollectionRestEqualWithoutMetadata(originalCollectionRest, collectionRest)) {
metadataConverter.setMetadata(context, collection, collectionRest.getMetadata());
} else {
@@ -208,7 +207,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
+ id + ", "
+ collectionRest.getId());
}
return converter.toRest(collection, Projection.DEFAULT);
return converter.toRest(collection, utils.obtainProjection());
}
@Override
@@ -250,7 +249,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
Bitstream bitstream = cs.setLogo(context, collection, uploadfile.getInputStream());
cs.update(context, collection);
bitstreamService.update(context, bitstream);
return converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT);
return converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
}
/**
@@ -277,7 +276,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
cs.update(context, collection);
itemService.update(context, item);
return converter.toRest(new TemplateItem(item), Projection.DEFAULT);
return converter.toRest(new TemplateItem(item), utils.obtainProjection());
}
/**
@@ -296,7 +295,7 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
}
try {
return converter.toRest(new TemplateItem(item), Projection.DEFAULT);
return converter.toRest(new TemplateItem(item), utils.obtainProjection());
} catch (IllegalArgumentException e) {
throw new UnprocessableEntityException("The item with id " + item.getID() + " is not a template item");
}

View File

@@ -0,0 +1,65 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Community;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* LinkRepository for the ParentCommunity object for a Community
*/
@Component(CommunityRest.CATEGORY + "." + CommunityRest.NAME + "." + CommunityRest.PARENT_COMMUNITY)
public class CommunityParentCommunityLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private CommunityService communityService;
/**
* This method retrieves the ParentCommunity object for the Community which is defined by the given communityId
* It'll transform this Parent Community to a REST object and return this
* @param httpServletRequest The current request
* @param communityId The given Community UUID that will be used to find the communityId
* @param optionalPageable The pageable
* @param projection The current Projection
* @return The Parent Community REST object
*/
@PreAuthorize("hasPermission(#communityId, 'COMMUNITY', 'READ')")
public CommunityRest getParentCommunity(@Nullable HttpServletRequest httpServletRequest,
UUID communityId,
@Nullable Pageable optionalPageable,
Projection projection) {
try {
Context context = obtainContext();
Community community = communityService.find(context, communityId);
if (community == null) {
throw new ResourceNotFoundException("No such community: " + community);
}
Community parentCommunity = (Community) communityService.getParentObject(context, community);
if (parentCommunity == null) {
return null;
}
return converter.toRest(parentCommunity, projection);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -25,7 +25,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.CommunityRestEqualityUtils;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
@@ -90,7 +89,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRest(community, Projection.DEFAULT);
return converter.toRest(community, utils.obtainProjection());
}
@Override
@@ -127,7 +126,7 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRest(community, Projection.DEFAULT);
return converter.toRest(community, utils.obtainProjection());
}
@Override
@@ -215,14 +214,14 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
if (community == null) {
throw new ResourceNotFoundException(apiCategory + "." + model + " with id: " + id + " not found");
}
CommunityRest originalCommunityRest = converter.toRest(community, Projection.DEFAULT);
CommunityRest originalCommunityRest = converter.toRest(community, utils.obtainProjection());
if (communityRestEqualityUtils.isCommunityRestEqualWithoutMetadata(originalCommunityRest, communityRest)) {
metadataConverter.setMetadata(context, community, communityRest.getMetadata());
} else {
throw new UnprocessableEntityException("The given JSON and the original Community differ more " +
"than just the metadata");
}
return converter.toRest(community, Projection.DEFAULT);
return converter.toRest(community, utils.obtainProjection());
}
@Override
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'DELETE')")
@@ -267,6 +266,6 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
Bitstream bitstream = cs.setLogo(context, community, uploadfile.getInputStream());
cs.update(context, community);
bitstreamService.update(context, bitstream);
return converter.toRest(context.reloadEntity(bitstream), Projection.DEFAULT);
return converter.toRest(context.reloadEntity(bitstream), utils.obtainProjection());
}
}

View File

@@ -20,7 +20,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.EPersonRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
@@ -84,7 +83,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository<EPerson, E
throw new RuntimeException(e.getMessage(), e);
}
return converter.toRest(eperson, Projection.DEFAULT);
return converter.toRest(eperson, utils.obtainProjection());
}
@Override

View File

@@ -13,7 +13,6 @@ import java.util.Optional;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.model.ExternalSourceEntryRest;
import org.dspace.app.rest.model.ExternalSourceRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context;
import org.dspace.external.model.ExternalDataObject;
import org.dspace.external.provider.ExternalDataProvider;
@@ -52,7 +51,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
entryId);
ExternalDataObject dataObject = externalDataObject.orElseThrow(() -> new ResourceNotFoundException(
"Couldn't find an ExternalSource for source: " + externalSourceName + " and ID: " + entryId));
return converter.toRest(dataObject, Projection.DEFAULT);
return converter.toRest(dataObject, utils.obtainProjection());
}
/**
@@ -84,7 +83,7 @@ public class ExternalSourceRestRepository extends DSpaceRestRepository<ExternalS
throw new ResourceNotFoundException("ExternalDataProvider for: " +
externalSourceName + " couldn't be found");
}
return converter.toRest(externalDataProvider, Projection.DEFAULT);
return converter.toRest(externalDataProvider, utils.obtainProjection());
}
@Override

View File

@@ -19,7 +19,6 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.GroupRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.eperson.Group;
@@ -74,7 +73,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository<Group, Group
throw new RuntimeException(excSQL.getMessage(), excSQL);
}
return converter.toRest(group, Projection.DEFAULT);
return converter.toRest(group, utils.obtainProjection());
}
@Override

View File

@@ -21,7 +21,6 @@ import org.dspace.app.rest.converter.HarvestedCollectionConverter;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.HarvestTypeEnum;
import org.dspace.app.rest.model.HarvestedCollectionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Collection;
import org.dspace.core.Context;
import org.dspace.harvest.HarvestedCollection;
@@ -91,7 +90,7 @@ public class HarvestedCollectionRestRepository extends AbstractDSpaceRestReposit
List<Map<String,String>> configs = OAIHarvester.getAvailableMetadataFormats();
return harvestedCollectionConverter.fromModel(harvestedCollection, collection, configs,
Projection.DEFAULT);
utils.obtainProjection());
} else {
throw new UnprocessableEntityException(
"Incorrect harvest settings in request. The following errors were found: " + errors.toString()

View File

@@ -28,7 +28,6 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.handler.service.UriListHandlerService;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bundle;
@@ -293,7 +292,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
Item itemToReturn = installItemService.installItem(context, workspaceItem);
return converter.toRest(itemToReturn, Projection.DEFAULT);
return converter.toRest(itemToReturn, utils.obtainProjection());
}
@Override
@@ -322,7 +321,7 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
+ uuid + ", "
+ itemRest.getId());
}
return converter.toRest(item, Projection.DEFAULT);
return converter.toRest(item, utils.obtainProjection());
}
/**
@@ -355,6 +354,6 @@ public class ItemRestRepository extends DSpaceObjectRestRepository<Item, ItemRes
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
Item item = uriListHandlerService.handle(context, req, stringList, Item.class);
return converter.toRest(item, Projection.DEFAULT);
return converter.toRest(item, utils.obtainProjection());
}
}

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataFieldRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataSchema;
@@ -147,7 +146,7 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
}
// return
return converter.toRest(metadataField, Projection.DEFAULT);
return converter.toRest(metadataField, utils.obtainProjection());
}
@Override
@@ -203,6 +202,6 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
throw new RuntimeException(e);
}
return converter.toRest(metadataField, Projection.DEFAULT);
return converter.toRest(metadataField, utils.obtainProjection());
}
}

View File

@@ -21,7 +21,6 @@ import com.google.gson.Gson;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.MetadataSchemaRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.MetadataSchema;
import org.dspace.content.NonUniqueMetadataException;
@@ -111,7 +110,7 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
}
// return
return converter.toRest(metadataSchema, Projection.DEFAULT);
return converter.toRest(metadataSchema, utils.obtainProjection());
}
@Override
@@ -167,6 +166,6 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
+ metadataSchemaRest.getPrefix() + "." + metadataSchemaRest.getNamespace() + " already exists");
}
return converter.toRest(metadataSchema, Projection.DEFAULT);
return converter.toRest(metadataSchema, utils.obtainProjection());
}
}

View File

@@ -22,7 +22,6 @@ import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.RelationshipRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.DSpaceObject;
@@ -127,7 +126,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
relationshipService.updateItem(context, relationship.getLeftItem());
relationshipService.updateItem(context, relationship.getRightItem());
context.restoreAuthSystemState();
return converter.toRest(relationship, Projection.DEFAULT);
return converter.toRest(relationship, utils.obtainProjection());
} else {
throw new AccessDeniedException("You do not have write rights on this relationship's items");
}
@@ -192,7 +191,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
throw new AccessDeniedException("You do not have write rights on this relationship's items");
}
return converter.toRest(relationship, Projection.DEFAULT);
return converter.toRest(relationship, utils.obtainProjection());
} else {
throw new AccessDeniedException("You do not have write rights on this relationship's items");
}
@@ -256,7 +255,7 @@ public class RelationshipRestRepository extends DSpaceRestRepository<Relationshi
context.commit();
context.reloadEntity(relationship);
return converter.toRest(relationship, Projection.DEFAULT);
return converter.toRest(relationship, utils.obtainProjection());
} catch (AuthorizeException e) {
throw new AccessDeniedException("You do not have write rights on this relationship's metadata");
}

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.ResourcePatch;
import org.dspace.app.rest.utils.DSpaceObjectUtils;
import org.dspace.app.rest.utils.Utils;
@@ -270,7 +269,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException excSQL) {
throw new RuntimeException(excSQL.getMessage(), excSQL);
}
return converter.toRest(resourcePolicy, Projection.DEFAULT);
return converter.toRest(resourcePolicy, utils.obtainProjection());
} else {
try {
UUID groupUuid = UUID.fromString(groupUuidStr);
@@ -283,7 +282,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
} catch (SQLException excSQL) {
throw new RuntimeException(excSQL.getMessage(), excSQL);
}
return converter.toRest(resourcePolicy, Projection.DEFAULT);
return converter.toRest(resourcePolicy, utils.obtainProjection());
}
}

View File

@@ -25,7 +25,6 @@ import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.ParameterValueRest;
import org.dspace.app.rest.model.ProcessRest;
import org.dspace.app.rest.model.ScriptRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.scripts.handler.impl.RestDSpaceRunnableHandler;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
@@ -103,7 +102,7 @@ public class ScriptRestRepository extends DSpaceRestRepository<ScriptRest, Strin
try {
runDSpaceScript(scriptToExecute, restDSpaceRunnableHandler, args);
context.complete();
return converter.toRest(restDSpaceRunnableHandler.getProcess(), Projection.DEFAULT);
return converter.toRest(restDSpaceRunnableHandler.getProcess(), utils.obtainProjection());
} catch (SQLException e) {
log.error("Failed to create a process with user: " + context.getCurrentUser() +
" scriptname: " + scriptName + " and parameters " + DSpaceCommandLineParameter

View File

@@ -17,7 +17,6 @@ import org.dspace.app.rest.converter.JsonPatchConverter;
import org.dspace.app.rest.model.TemplateItemRest;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.model.wrapper.TemplateItem;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.patch.ResourcePatch;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
@@ -62,7 +61,7 @@ public class TemplateItemRestRepository extends DSpaceRestRepository<TemplateIte
}
try {
return converter.toRest(new TemplateItem(item), Projection.DEFAULT);
return converter.toRest(new TemplateItem(item), utils.obtainProjection());
} catch (IllegalArgumentException e) {
throw new ResourceNotFoundException("The item with id " + item.getID() + " is not a template item");
}

View File

@@ -0,0 +1,55 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing {@link WorkflowActionRest} objects
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
@Component(WorkflowActionRest.CATEGORY + "." + WorkflowActionRest.NAME)
public class WorkflowActionRestRepository extends DSpaceRestRepository<WorkflowActionRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowActionRest findOne(Context context, String workflowActionName) {
WorkflowActionConfig actionConfig = this.xmlWorkflowFactory.getActionByName(workflowActionName);
if (actionConfig != null) {
return converter.toRest(actionConfig, utils.obtainProjection());
} else {
throw new ResourceNotFoundException("No workflow action with name " + workflowActionName
+ " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowActionRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException(WorkflowActionRest.NAME, "findAll");
}
@Override
public Class<WorkflowActionRest> getDomainClass() {
return WorkflowActionRest.class;
}
}

View File

@@ -0,0 +1,95 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import org.dspace.app.rest.Parameter;
import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.content.Collection;
import org.dspace.content.service.CollectionService;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing WorkflowDefinition Rest objects
*
* @author Maria Verdonck (Atmire) on 11/12/2019
*/
@Component(WorkflowDefinitionRest.CATEGORY + "." + WorkflowDefinitionRest.NAME)
public class WorkflowDefinitionRestRepository extends DSpaceRestRepository<WorkflowDefinitionRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Autowired
private CollectionService collectionService;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowDefinitionRest findOne(Context context, String workflowName) {
if (xmlWorkflowFactory.workflowByThisNameExists(workflowName)) {
try {
return converter.toRest(xmlWorkflowFactory.getWorkflowByName(workflowName), utils.obtainProjection());
} catch (WorkflowConfigurationException e) {
// Should never occur, since xmlWorkflowFactory.getWorkflowByName only throws a
// WorkflowConfigurationException if no workflow by that name is configured (tested earlier)
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
} else {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowDefinitionRest> findAll(Context context, Pageable pageable) {
List<Workflow> workflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
return converter.toRestPage(utils.getPage(workflows, pageable), utils.obtainProjection());
}
/**
* GET endpoint that returns the workflow definition that applies to a specific collection eventually fallback
* to the default configuration.
*
* @param collectionId Uuid of the collection
* @return the workflow definition for this collection
*/
@SearchRestMethod(name = "findByCollection")
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowDefinitionRest findByCollection(@Parameter(value = "uuid") UUID collectionId) throws SQLException {
Context context = obtainContext();
Collection collectionFromUuid = collectionService.find(context, collectionId);
if (collectionFromUuid != null) {
try {
return converter.toRest(xmlWorkflowFactory.getWorkflow(collectionFromUuid), utils.obtainProjection());
} catch (WorkflowConfigurationException e) {
throw new ResourceNotFoundException("No workflow for this collection fault and " +
"no defaultWorkflow found");
}
} else {
throw new ResourceNotFoundException("Collection with id " + collectionId + " not found");
}
}
@Override
public Class<WorkflowDefinitionRest> getDomainClass() {
return WorkflowDefinitionRest.class;
}
}

View File

@@ -24,7 +24,6 @@ import org.dspace.app.rest.model.ErrorRest;
import org.dspace.app.rest.model.WorkflowItemRest;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.SubmissionService;
import org.dspace.app.rest.submit.UploadableStep;
@@ -157,7 +156,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
if (source.getItem().isArchived()) {
return null;
}
return converter.toRest(source, Projection.DEFAULT);
return converter.toRest(source, utils.obtainProjection());
}
@Override
@@ -204,7 +203,7 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
}
}
wsi = converter.toRest(source, Projection.DEFAULT);
wsi = converter.toRest(source, utils.obtainProjection());
if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors);

View File

@@ -0,0 +1,55 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.core.Context;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Step;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This is the rest repository responsible for managing {@link WorkflowStepRest} objects
*
* @author Maria Verdonck (Atmire) on 10/01/2020
*/
@Component(WorkflowStepRest.CATEGORY + "." + WorkflowStepRest.NAME)
public class WorkflowStepRestRepository extends DSpaceRestRepository<WorkflowStepRest, String> {
@Autowired
protected XmlWorkflowFactory xmlWorkflowFactory;
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public WorkflowStepRest findOne(Context context, String workflowStepName) {
Step step = this.xmlWorkflowFactory.getStepByName(workflowStepName);
if (step != null) {
return converter.toRest(step, utils.obtainProjection());
} else {
throw new ResourceNotFoundException("No workflow step with name " + workflowStepName
+ " is configured");
}
}
@Override
@PreAuthorize("hasAuthority('AUTHENTICATED')")
public Page<WorkflowStepRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException(WorkflowStepRest.NAME, "findAll");
}
@Override
public Class<WorkflowStepRest> getDomainClass() {
return WorkflowStepRest.class;
}
}

View File

@@ -31,7 +31,6 @@ import org.dspace.app.rest.model.ErrorRest;
import org.dspace.app.rest.model.WorkspaceItemRest;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.handler.service.UriListHandlerService;
import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.SubmissionService;
@@ -167,7 +166,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
@Override
protected WorkspaceItemRest createAndReturn(Context context) throws SQLException, AuthorizeException {
WorkspaceItem source = submissionService.createWorkspaceItem(context, getRequestService().getCurrentRequest());
return converter.toRest(source, converter.getProjection("full"));
return converter.toRest(source, utils.obtainProjection());
}
@Override
@@ -254,7 +253,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
}
}
wsi = converter.toRest(source, Projection.DEFAULT);
wsi = converter.toRest(source, utils.obtainProjection());
if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors);
@@ -473,7 +472,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
}
}
}
WorkspaceItemRest wsi = converter.toRest(wi, Projection.DEFAULT);
WorkspaceItemRest wsi = converter.toRest(wi, utils.obtainProjection());
if (result.size() == 1) {
if (!errors.isEmpty()) {
wsi.getErrors().addAll(errors);
@@ -494,7 +493,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest();
WorkspaceItem workspaceItem = uriListHandlerService.handle(context, req, stringList, WorkspaceItem.class);
return converter.toRest(workspaceItem, Projection.DEFAULT);
return converter.toRest(workspaceItem, utils.obtainProjection());
}

View File

@@ -79,6 +79,8 @@ public class SubmissionService {
private RequestService requestService;
@Autowired
private ConverterService converter;
@Autowired
private org.dspace.app.rest.utils.Utils utils;
/**
* Create a workspaceitem using the information in the request
@@ -174,9 +176,9 @@ public class SubmissionService {
}
}
Projection projection = utils.obtainProjection();
HttpServletRequest request = requestService.getCurrentRequest().getHttpServletRequest();
data.setFormat(converter.toRest(source.getFormat(ContextUtil.obtainContext(request)), Projection.DEFAULT));
data.setFormat(converter.toRest(source.getFormat(ContextUtil.obtainContext(request)), projection));
for (ResourcePolicy rp : source.getResourcePolicies()) {
if (ResourcePolicy.TYPE_CUSTOM.equals(rp.getRpType())) {
@@ -231,7 +233,7 @@ public class SubmissionService {
if (wsi == null) {
throw new UnprocessableEntityException("Workspace item is not found");
}
WorkspaceItemRest wsiRest = converter.toRest(wsi, Projection.DEFAULT);
WorkspaceItemRest wsiRest = converter.toRest(wsi, utils.obtainProjection());
if (!wsiRest.getErrors().isEmpty()) {
throw new UnprocessableEntityException(
"Start workflow failed due to validation error on workspaceitem");

View File

@@ -29,6 +29,7 @@ import org.dspace.app.rest.builder.BitstreamFormatBuilder;
import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.matcher.BitstreamFormatMatcher;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.model.BitstreamFormatRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
@@ -134,6 +135,7 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati
public void createAdminAccess() throws Exception {
ObjectMapper mapper = new ObjectMapper();
BitstreamFormatRest bitstreamFormatRest = this.createRandomMockBitstreamRest(false);
//Create bitstream format
String token = getAuthToken(admin.getEmail(), password);
@@ -142,10 +144,10 @@ public class BitstreamFormatRestRepositoryIT extends AbstractControllerIntegrati
try {
MvcResult mvcResult = getClient(token).perform(post("/api/core/bitstreamformats/")
.content(mapper.writeValueAsBytes(
bitstreamFormatRest))
.content(mapper.writeValueAsBytes(bitstreamFormatRest))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andReturn();
String content = mvcResult.getResponse().getContentAsString();

View File

@@ -78,8 +78,10 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()),
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle()),
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)));
}
@@ -110,11 +112,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._embedded.collections", Matchers.not(
Matchers.contains(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)
)));
@@ -125,11 +129,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)))
.andExpect(jsonPath("$._embedded.collections", Matchers.not(
Matchers.contains(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)
)));
}
@@ -202,11 +208,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$", Matchers.not(
is(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)))
)
;
@@ -348,11 +356,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$", Matchers.not(
is(
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
))));
}
@@ -376,7 +386,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
;
@@ -403,7 +414,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry("Electronic theses and dissertations",
CollectionMatcher.matchCollectionEntryFullProjection("Electronic theses and dissertations",
col1.getID(), col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
@@ -445,10 +456,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ;
Matchers.containsString("/api/core/collections")));
getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isNoContent())
;
@@ -489,10 +501,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ;
Matchers.containsString("/api/core/collections")));
getClient().perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isUnauthorized())
;
@@ -532,9 +545,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
getClient(authToken).perform(post("/api/core/collections")
.content(mapper.writeValueAsBytes(collectionRest))
.param("parent", parentCommunity.getID().toString())
.contentType(contentType))
.contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", CollectionMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.id", not(empty())),
hasJsonPath("$.uuid", not(empty())),
@@ -554,6 +569,13 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
"Title Text")
)))));
getClient(authToken).perform(post("/api/core/collections")
.content(mapper.writeValueAsBytes(collectionRest))
.param("parent", parentCommunity.getID().toString())
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()));
}
@Test
@@ -701,10 +723,11 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/collections"))) ;
Matchers.containsString("/api/core/collections")));
getClient(token).perform(delete("/api/core/collections/" + col1.getID().toString()))
.andExpect(status().isNoContent())
;
@@ -737,7 +760,8 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
;
@@ -767,7 +791,7 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CollectionMatcher.matchCollectionEntry("Electronic theses and dissertations",
CollectionMatcher.matchCollectionEntryFullProjection("Electronic theses and dissertations",
col1.getID(), col1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
@@ -908,9 +932,12 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()),
CollectionMatcher.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
CollectionMatcher.matchCollectionEntryFullProjection(col1.getName(), col1.getID(),
col1.getHandle()),
CollectionMatcher.matchCollectionEntryFullProjection(col2.getName(), col2.getID(),
col2.getHandle())
)))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 2)));
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 20,
1, 2)));
}
}

View File

@@ -0,0 +1,374 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.sql.SQLException;
import java.util.UUID;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.matcher.CollectionMatcher;
import org.dspace.app.rest.matcher.CommunityMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class CommunityCollectionItemParentIT extends AbstractControllerIntegrationTest {
@Autowired
private CollectionService collectionService;
@Autowired
private CommunityService communityService;
@Autowired
private AuthorizeService authorizeService;
Community communityA;
Community communityB;
Community communityAA;
Community communityAB;
Collection colAA1;
Collection colAA2;
Collection colAB1;
Item itemAA1;
Item itemAA1MappedInAA2;
Item itemAA2;
@Before
public void setup() throws SQLException, AuthorizeException {
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
communityA = CommunityBuilder.createCommunity(context)
.withName("Parent CommunityA")
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("Parent CommunityB")
.build();
communityAA = CommunityBuilder.createSubCommunity(context, communityA)
.withName("Sub Community")
.build();
communityAB = CommunityBuilder.createSubCommunity(context, communityA)
.withName("Sub Community Two")
.build();
colAA1 = CollectionBuilder.createCollection(context, communityAA).withName("Collection 1").build();
colAA2 = CollectionBuilder.createCollection(context, communityAA).withName("Collection 2").build();
colAB1 = CollectionBuilder.createCollection(context, communityAB).withName("Collection 3").build();
communityService.addCollection(context, communityAB, colAA2);
itemAA1 = ItemBuilder.createItem(context, colAA1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
itemAA1MappedInAA2 = ItemBuilder.createItem(context, colAA1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
collectionService.addItem(context, colAA2, itemAA1MappedInAA2);
itemAA2 = ItemBuilder.createItem(context, colAA2)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
}
@Test
public void itemAA1OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA1.getName(),
colAA1.getID(),
colAA1.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA2.getName(), colAA2.getID(), colAA2.getHandle())))));
}
@Test
public void itemAA1MappedInAA2OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1MappedInAA2.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA1.getName(),
colAA1.getID(),
colAA1.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA2.getName(), colAA2.getID(), colAA2.getHandle())))));
}
@Test
public void itemAA2OwningCollectionTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA2.getID() + "/owningCollection"))
.andExpect(jsonPath("$", is(CollectionMatcher.matchCollectionEntry(colAA2.getName(),
colAA2.getID(),
colAA2.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(is(CollectionMatcher
.matchCollectionEntry(colAA1.getName(), colAA1.getID(), colAA1.getHandle())))));
}
@Test
public void colAA1ParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(jsonPath("$", is(CommunityMatcher
.matchCommunityEntry(communityAA.getName(), communityAA.getID(),
communityAA.getHandle()))))
.andExpect(jsonPath("$", not(is(CommunityMatcher.matchCommunityEntry(communityA.getName(),
communityA.getID(),
communityA.getHandle())))))
.andExpect(jsonPath("$", not(is(CommunityMatcher.matchCommunityEntry(communityAB.getName(),
communityAB.getID(),
communityAB
.getHandle())))));
}
@Test
public void comAAParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token)
.perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(jsonPath("$", Matchers
.is(CommunityMatcher.matchCommunityEntry(communityA.getID(), communityA.getHandle()))))
.andExpect(jsonPath("$", Matchers
.not(Matchers.is(CommunityMatcher.matchCommunityEntry(communityB.getID(), communityB.getHandle())))));
}
@Test
public void comAParentCommunityTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityA.getID() + "/parentCommunity"))
.andExpect(status().isNoContent());
}
@Test
public void parentCommunityWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + UUID.randomUUID() + "/parentCommunity"))
.andExpect(status().isNotFound());
}
@Test
public void parentCommunityPrivateCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityPrivateParentCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
@Test
public void parentCommunityPrivateCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityPrivateParentCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/communities/" + communityAA.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
@Test
public void parentCommunityForCollectionWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + UUID.randomUUID() + "/parentCommunity"))
.andExpect(status().isNotFound());
}
@Test
public void parentCommunityForCollectionPrivateCollectionUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityForCollectionPrivateParentCommunityUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isUnauthorized());
}
@Test
public void parentCommunityForCollectionPrivateCollectionForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void parentCommunityForCollectionPrivateParentCommunityForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, communityAA);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/collections/" + colAA1.getID() + "/parentCommunity"))
.andExpect(status().isForbidden());
}
@Test
public void owningCollectionForItemWrongUUIDTest() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + UUID.randomUUID() + "/owningCollection"))
.andExpect(status().isNotFound());
}
@Test
public void owningCollectionForItemPrivateItemUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, itemAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void owningCollectionForItemPrivateOwningCollectionUnAuthorizedTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
getClient().perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isUnauthorized());
}
//Enable this test when this security level has been supported
@Ignore
@Test
public void owningCollectionForItemPrivateOwningCollectionForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, colAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isForbidden());
}
@Test
public void owningCollectionForItemPrivateItemForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
authorizeService.removeAllPolicies(context, itemAA1);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/core/items/" + itemAA1.getID() + "/owningCollection"))
.andExpect(status().isForbidden());
}
}

View File

@@ -75,8 +75,10 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
public void createTest() throws Exception {
ObjectMapper mapper = new ObjectMapper();
CommunityRest comm = new CommunityRest();
CommunityRest commNoembeds = new CommunityRest();
// We send a name but the created community should set this to the title
comm.setName("Test Top-Level Community");
commNoembeds.setName("Test Top-Level Community Full");
MetadataRest metadataRest = new MetadataRest();
@@ -101,17 +103,22 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
metadataRest.put("dc.title", title);
comm.setMetadata(metadataRest);
commNoembeds.setMetadata(metadataRest);
String authToken = getAuthToken(admin.getEmail(), password);
// Capture the UUID of the created Community (see andDo() below)
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<UUID>();
try {
getClient(authToken).perform(post("/api/core/communities")
.content(mapper.writeValueAsBytes(comm))
.contentType(contentType))
.contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", CommunityMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.id", not(empty())),
hasJsonPath("$.uuid", not(empty())),
@@ -135,9 +142,19 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
// capture "id" returned in JSON response
.andDo(result -> idRef
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
getClient(authToken).perform(post("/api/core/communities")
.content(mapper.writeValueAsBytes(commNoembeds))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRefNoEmbeds
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
} finally {
// Delete the created community (cleanup after ourselves!)
CommunityBuilder.deleteCommunity(idRef.get());
CommunityBuilder.deleteCommunity(idRefNoEmbeds.get());
}
}
@@ -307,10 +324,11 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher
.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
.matchCommunityEntryFullProjection(child1.getName(), child1.getID(), child1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.size", is(20)))
@@ -334,13 +352,15 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.build();
getClient().perform(get("/api/core/communities").param("size", "2").param("projection", "full"))
getClient().perform(get("/api/core/communities").param("size", "2").param("projection",
"full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.totalElements", is(2)))
@@ -357,50 +377,60 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.withTitle(titles.get(2))
.withTitle(titles.get(3))
.build();
Community childCommunity = CommunityBuilder.createSubCommunity(context, parentCommunity).build();
Community childCommunity = CommunityBuilder.createSubCommunity(context, parentCommunity).withName("test")
.build();
Community secondParentCommunity = CommunityBuilder.createCommunity(context).withName("testing").build();
Community thirdParentCommunity = CommunityBuilder.createCommunity(context).withName("testingTitleTwo").build();
context.restoreAuthSystemState();
getClient().perform(get("/api/core/communities").param("size", "2").param("projection", "full"))
getClient().perform(get("/api/core/communities").param("size", "2").param("projection",
"full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntryMultipleTitles(titles, parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(childCommunity.getID(), childCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(childCommunity.getName(),
childCommunity.getID(),
childCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 2, 2, 4)));
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(0, 2,
2, 4)));
getClient().perform(get("/api/core/communities").param("size", "2").param("page", "1")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(secondParentCommunity.getID(),
secondParentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(thirdParentCommunity.getID(),
thirdParentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(secondParentCommunity.getName(),
secondParentCommunity.getID(),
secondParentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntryFullProjection(thirdParentCommunity.getName(),
thirdParentCommunity.getID(),
thirdParentCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(1, 2, 2, 4)));
.andExpect(jsonPath("$.page", PageMatcher.pageEntryWithTotalPagesAndElements(1, 2,
2, 4)));
}
@Test
public void findAllNoNameCommunityIsReturned() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context).build();
parentCommunity = CommunityBuilder.createCommunity(context).withName("test").build();
getClient().perform(get("/api/core/communities")
.param("projection", "full"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
.andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -462,12 +492,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$._embedded.communities", Matchers.not(
Matchers.contains(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -480,12 +512,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)))
.andExpect(jsonPath("$._embedded.communities", Matchers.not(
Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -553,12 +587,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers
@@ -633,14 +669,18 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(), parentCommunity2.getID(),
parentCommunity2.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(),
parentCommunity2.getHandle())
)))
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle()),
CommunityMatcher.matchCommunityEntry(child12.getName(), child12.getID(), child12.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle()),
CommunityMatcher.matchCommunityEntryFullProjection(child12.getName(), child12.getID(),
child12.getHandle())
))))
.andExpect(
jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities/search/top")))
@@ -697,25 +737,25 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(content().contentType(contentType))
//Checking that these communities are present
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchCommunityEntry(parentCommunityChild1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild1.getName(),
parentCommunityChild1.getID(),
parentCommunityChild1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2.getName(),
parentCommunityChild2.getID(),
parentCommunityChild2.getHandle())
)))
//Checking that these communities are not present
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(),
parentCommunity2.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2Child1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2Child1.getName(),
parentCommunity2Child1.getID(),
parentCommunity2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle())
))))
@@ -732,25 +772,25 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(content().contentType(contentType))
//Checking that these communities are present
.andExpect(jsonPath("$._embedded.communities", Matchers.contains(
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle())
)))
//Checking that these communities are not present
.andExpect(jsonPath("$._embedded.communities", Matchers.not(Matchers.anyOf(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2.getName(),
parentCommunity2.getID(),
parentCommunity2.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunity2Child1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity2Child1.getName(),
parentCommunity2Child1.getID(),
parentCommunity2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild2Child1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild2Child1.getName(),
parentCommunityChild2Child1.getID(),
parentCommunityChild2Child1.getHandle()),
CommunityMatcher.matchCommunityEntry(parentCommunityChild1.getName(),
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunityChild1.getName(),
parentCommunityChild1.getID(),
parentCommunityChild1.getHandle())
))))
@@ -824,12 +864,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -857,7 +899,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry("Electronic theses and dissertations",
CommunityMatcher.matchCommunityEntryFullProjection("Electronic theses and dissertations",
parentCommunity.getID(),
parentCommunity.getHandle())
)))
@@ -912,11 +954,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ;
Matchers.containsString("/api/core/communities")));
getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isNoContent())
;
@@ -974,11 +1017,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ;
Matchers.containsString("/api/core/communities")));
getClient().perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isUnauthorized())
;
@@ -1007,11 +1051,12 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("/api/core/communities"))) ;
Matchers.containsString("/api/core/communities")));
getClient(token).perform(delete("/api/core/communities/" + parentCommunity.getID().toString()))
.andExpect(status().isNoContent())
;
@@ -1041,12 +1086,14 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry(parentCommunity.getName(), parentCommunity.getID(),
parentCommunity.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(parentCommunity.getName(),
parentCommunity.getID(),
parentCommunity.getHandle())
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
CommunityMatcher.matchCommunityEntry(child1.getName(), child1.getID(), child1.getHandle())
CommunityMatcher.matchCommunityEntryFullProjection(child1.getName(), child1.getID(),
child1.getHandle())
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/communities")))
@@ -1077,7 +1124,7 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
CommunityMatcher.matchCommunityEntry("Electronic theses and dissertations",
CommunityMatcher.matchCommunityEntryFullProjection("Electronic theses and dissertations",
parentCommunity.getID(),
parentCommunity.getHandle())
)))

View File

@@ -56,6 +56,7 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
// we should check how to get it from Spring
ObjectMapper mapper = new ObjectMapper();
EPersonRest data = new EPersonRest();
EPersonRest dataFull = new EPersonRest();
MetadataRest metadataRest = new MetadataRest();
data.setEmail("createtest@fake-email.com");
data.setCanLogIn(true);
@@ -66,13 +67,18 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
firstname.setValue("John");
metadataRest.put("eperson.firstname", firstname);
data.setMetadata(metadataRest);
dataFull.setEmail("createtestFull@fake-email.com");
dataFull.setCanLogIn(true);
dataFull.setMetadata(metadataRest);
String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(post("/api/eperson/epersons")
.content(mapper.writeValueAsBytes(data))
.contentType(contentType))
.contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", EPersonMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.uuid", not(empty())),
// is it what you expect? EPerson.getName() returns the email...
@@ -86,6 +92,13 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
matchMetadata("eperson.firstname", "John"),
matchMetadata("eperson.lastname", "Doe")
)))));
getClient(authToken).perform(post("/api/eperson/epersons")
.content(mapper.writeValueAsBytes(dataFull))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()));
// TODO cleanup the context!!!
}

View File

@@ -44,17 +44,23 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
// hold the id of the created workflow item
AtomicReference<UUID> idRef = new AtomicReference<UUID>();
AtomicReference<UUID> idRefNoEmbeds = new AtomicReference<UUID>();
try {
ObjectMapper mapper = new ObjectMapper();
GroupRest groupRest = new GroupRest();
GroupRest groupRestNoEmbeds = new GroupRest();
String groupName = "testGroup1";
String groupNameNoEmbeds = "testGroup2";
groupRest.setName(groupName);
groupRestNoEmbeds.setName(groupNameNoEmbeds);
String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(post("/api/eperson/groups")
.content(mapper.writeValueAsBytes(groupRest)).contentType(contentType))
.content(mapper.writeValueAsBytes(groupRest)).contentType(contentType)
.param("projection", "full"))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", GroupMatcher.matchFullEmbeds()))
.andDo(result -> idRef
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
@@ -66,9 +72,17 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
GroupMatcher.matchGroupWithName(groupName),
GroupMatcher.matchGroupWithName("Administrator"),
GroupMatcher.matchGroupWithName("Anonymous"))));
getClient(authToken).perform(post("/api/eperson/groups")
.content(mapper.writeValueAsBytes(groupRestNoEmbeds)).contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRefNoEmbeds
.set(UUID.fromString(read(result.getResponse().getContentAsString(), "$.id"))));
} finally {
// remove the created group if any
GroupBuilder.deleteGroup(idRef.get());
GroupBuilder.deleteGroup(idRefNoEmbeds.get());
}
}

View File

@@ -98,8 +98,7 @@ public class ItemOwningCollectionUpdateRestControllerIT extends AbstractControll
//We expect a 401 Unauthorized status when performed by anonymous
.andExpect(status().isOk());
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection"))
.andExpect(jsonPath("$",
is(CollectionMatcher
.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())
@@ -152,8 +151,7 @@ public class ItemOwningCollectionUpdateRestControllerIT extends AbstractControll
//We expect a 401 Unauthorized status when performed by anonymous
.andExpect(status().isOk());
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection"))
.andExpect(jsonPath("$",
is(CollectionMatcher
.matchCollectionEntry(col2.getName(), col2.getID(), col2.getHandle())

View File

@@ -1441,6 +1441,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
ObjectMapper mapper = new ObjectMapper();
ItemRest itemRest = new ItemRest();
ItemRest itemRestFull = new ItemRest();
itemRest.setName("Practices of research data curation in institutional repositories:" +
" A qualitative view from repository staff");
itemRest.setInArchive(true);
@@ -1454,11 +1455,25 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.put("dc.rights", new MetadataValueRest("Custom Copyright Text"))
.put("dc.title", new MetadataValueRest("Title Text")));
itemRestFull.setName("Practices of research data curation in institutional repositories:" +
" A qualitative view from repository staff");
itemRestFull.setInArchive(true);
itemRestFull.setDiscoverable(true);
itemRestFull.setWithdrawn(false);
itemRestFull.setMetadata(new MetadataRest()
.put("dc.description", new MetadataValueRest("<p>Some cool HTML code here</p>"))
.put("dc.description.abstract", new MetadataValueRest("Sample item created via the REST API"))
.put("dc.description.tableofcontents", new MetadataValueRest("<p>HTML News</p>"))
.put("dc.rights", new MetadataValueRest("Custom Copyright Text"))
.put("dc.title", new MetadataValueRest("Title Text")));
String token = getAuthToken(admin.getEmail(), password);
MvcResult mvcResult = getClient(token).perform(post("/api/core/items?owningCollection=" +
col1.getID().toString())
.content(mapper.writeValueAsBytes(itemRest)).contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andReturn();
String content = mvcResult.getResponse().getContentAsString();
@@ -1487,6 +1502,13 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
MetadataMatcher.matchMetadata("dc.title",
"Title Text")
)))));
MvcResult mvcResultFull = getClient(token).perform(post("/api/core/items?owningCollection=" +
col1.getID().toString()).param("projection", "full")
.content(mapper.writeValueAsBytes(itemRestFull)).contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", ItemMatcher.matchFullEmbeds()))
.andReturn();
}
@Test

View File

@@ -62,12 +62,11 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build();
context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1);
// collectionService.update(context, col2);
// collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, colAA2);
// itemService.update(context, publicItem1);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()),
@@ -76,14 +75,12 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
@@ -124,8 +121,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)
);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle())
@@ -133,15 +129,13 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
@@ -184,8 +178,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)
);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -251,8 +244,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)
);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -307,8 +299,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)
);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle())
@@ -359,16 +350,14 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
)
);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()))
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
@@ -378,30 +367,26 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken)
.perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col2.getID()));
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle())
))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")));
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
@@ -411,8 +396,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken)
.perform(delete("/api/core/items/" + publicItem1.getID() + "/mappedCollections/" + col1.getID()));
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.containsInAnyOrder(
CollectionMatcher.matchCollectionEntry("Collection 2", col2.getID(), col2.getHandle()),
@@ -420,22 +404,19 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col1.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col2.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.not(Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
)))
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.hasSize(0)));;
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems")
.param("projection", "full"))
getClient().perform(get("/api/core/collections/" + col3.getID() + "/mappedItems"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedItems", Matchers.contains(
ItemMatcher.matchItemProperties(publicItem1))
@@ -626,14 +607,13 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build();
context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1);
// collectionService.update(context, col2);
// collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, colAA2);
// itemService.update(context, publicItem1);
context.restoreAuthSystemState();
context.setCurrentUser(null);
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections")
.param("projection", "full"))
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/mappedCollections"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.mappedCollections", Matchers.not(Matchers.contains(
CollectionMatcher.matchCollectionEntry("Collection 1", col1.getID(), col1.getHandle()),
@@ -667,8 +647,8 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build();
context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1);
// collectionService.update(context, col2);
// collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, colAA2);
// itemService.update(context, publicItem1);
getClient().perform(
@@ -704,8 +684,8 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
.build();
context.restoreAuthSystemState();
// collectionService.addItem(context, col2, publicItem1);
// collectionService.update(context, col2);
// collectionService.addItem(context, colAA2, publicItem1);
// collectionService.update(context, colAA2);
// itemService.update(context, publicItem1);

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.builder.MetadataSchemaBuilder;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.matcher.HalMatcher;
import org.dspace.app.rest.matcher.MetadataschemaMatcher;
import org.dspace.app.rest.model.MetadataSchemaRest;
import org.dspace.app.rest.projection.Projection;
@@ -102,6 +103,7 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio
.content(new ObjectMapper().writeValueAsBytes(metadataSchemaRest))
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", HalMatcher.matchNoEmbeds()))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
getClient().perform(get("/api/core/metadataschemas/" + idRef.get()))

View File

@@ -184,6 +184,7 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
getClient(authToken)
.perform(post("/api/core/metadatafields")
.param("schemaId", metadataSchema.getID() + "")
.param("projection", "full")
.content(new ObjectMapper().writeValueAsBytes(metadataFieldRest))
.contentType(contentType))
.andExpect(status().isCreated())

View File

@@ -514,6 +514,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.param("relationshipType",
isAuthorOfPublicationRelationshipType.getID()
.toString())
.param("projection", "full")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
@@ -523,6 +524,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
"https://localhost:8080/server/api/core/items/" + author1
.getID()))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", RelationshipMatcher.matchFullEmbeds()))
.andReturn();
ObjectMapper mapper = new ObjectMapper();

View File

@@ -38,7 +38,7 @@ import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.builder.GroupBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.builder.ResourcePolicyBuilder;
import org.dspace.app.rest.matcher.ResoucePolicyMatcher;
import org.dspace.app.rest.matcher.ResourcePolicyMatcher;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.patch.AddOperation;
import org.dspace.app.rest.model.patch.Operation;
@@ -122,7 +122,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", is(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy)
ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy)
)))
.andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID())));
@@ -236,8 +236,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", is(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy))));
.andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))));
}
@Test
@@ -272,7 +271,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String authToken = getAuthToken(eperson1.getEmail(), "qwerty01");
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy))));
.andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))));
String authTokenEperson2 = getAuthToken(eperson2.getEmail(), "qwerty02");
getClient(authTokenEperson2).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
@@ -315,9 +314,9 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson1))))
ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson1))))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson2)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString(
"api/authz/resourcepolicies/search/eperson")))
.andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -360,11 +359,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.param("resource", community.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfCommunity),
ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfCommunity)
ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfCommunity),
ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfCommunity)
)))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyOfCollection)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfCollection)))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/eperson")))
.andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -497,11 +496,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson1),
ResoucePolicyMatcher.matchResourcePolicy(resourcePolicyAnonymous)
ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson1),
ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyAnonymous)
)))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/resource")))
.andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -549,10 +548,10 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)
ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)
)))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson2)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson2)))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/resource")))
.andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -764,11 +763,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.containsInAnyOrder(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1),
ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1),
ResoucePolicyMatcher.matchResourcePolicy(collectionResourcePolicyOfGroup1))))
ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1),
ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1),
ResourcePolicyMatcher.matchResourcePolicy(collectionResourcePolicyOfGroup1))))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2)))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(3)));
@@ -780,7 +779,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2))))
ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup2))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -819,9 +818,9 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.param("resource", community.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.contains(ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1))))
Matchers.contains(ResourcePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfGroup1))))
.andExpect(jsonPath("$._embedded.resourcepolicies",
Matchers.not(is(ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1)))))
Matchers.not(is(ResourcePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfGroup1)))))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/group")))
.andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -971,9 +970,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.content(mapper.writeValueAsBytes(resourcePolicyRest))
.param("resource", community.getID().toString())
.param("eperson", eperson1.getID().toString())
.param("projections", "full")
.contentType(contentType))
.andExpect(status().isCreated())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", ResourcePolicyMatcher.matchFullEmbeds()))
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.name", is(resourcePolicyRest.getName())),
hasJsonPath("$.description", is(resourcePolicyRest.getDescription())),
@@ -1156,7 +1157,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", is(ResoucePolicyMatcher.matchResourcePolicy(resourcePolicy))))
.andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicy))))
.andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/authz/resourcepolicies/" + resourcePolicy.getID())));
}

View File

@@ -1439,7 +1439,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest {
.withName("Sub Community")
.build();
// the reviewer2 is a reviewer in a different step for the col1 and with the same role than reviewer1 for
// the reviewer2 is a reviewer in a different step for the colAA1 and with the same role than reviewer1 for
// another collection
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1")
.withWorkflowGroup(1, reviewer1)
@@ -1613,7 +1613,7 @@ public class TaskRestRepositoriesIT extends AbstractControllerIntegrationTest {
.withName("Sub Community")
.build();
// the reviewer2 is a reviewer in a different step for the col1 and with the same role than reviewer1 for
// the reviewer2 is a reviewer in a different step for the colAA1 and with the same role than reviewer1 for
// another collection
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1")
.withWorkflowGroup(1, reviewer1)

View File

@@ -0,0 +1,128 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.matcher.WorkflowActionMatcher;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.app.rest.repository.WorkflowActionRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowActionRestRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL;
@Test
public void getAllWorkflowActions_NonImplementedEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 405 Method not allowed status
.andExpect(status().isMethodNotAllowed());
}
@Test
public void getAllWorkflowActions_NonImplementedEndpoint_NonValidToken() throws Exception {
String token = "nonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowActions_NonImplementedEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowActionByName_NonExistentWorkflowAction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameNonExistentWorkflowActionName = "TestNameNonExistentWorkflowAction9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameNonExistentWorkflowActionName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_editaction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 200 is ok status
.andExpect(status().isOk())
// has options
.andExpect(jsonPath("$.options", not(empty())))
//Matches expected corresponding rest action values
.andExpect(jsonPath("$", Matchers.is(
WorkflowActionMatcher.matchWorkflowActionEntry(existentWorkflow)
)));
}
@Test
public void getWorkflowActionByName_ExistentWithoutOptions_claimaction() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameActionWithoutOptions = "claimaction";
WorkflowActionConfig existentWorkflowNoOptions = xmlWorkflowFactory.getActionByName(nameActionWithoutOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithoutOptions))
//We expect a 200 is ok status
.andExpect(status().isOk())
// has no options
.andExpect(jsonPath("$.options", empty()))
//Matches expected corresponding rest action values
.andExpect(jsonPath("$", Matchers.is(
WorkflowActionMatcher.matchWorkflowActionEntry(existentWorkflowNoOptions)
)));
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_NonValidToken() throws Exception {
String token = "nonValidToken";
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getWorkflowActionByName_ExistentWithOptions_NoToken() throws Exception {
String nameActionWithOptions = "editaction";
WorkflowActionConfig existentWorkflow = xmlWorkflowFactory.getActionByName(nameActionWithOptions);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameActionWithOptions))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
}

View File

@@ -0,0 +1,458 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalToIgnoringCase;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.matcher.WorkflowDefinitionMatcher;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.app.rest.repository.WorkflowDefinitionRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowDefinitionRestRepository}
* and {@link WorkflowDefinitionCollectionsLinkRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 17/12/2019
*/
public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_DEFINITIONS_ENDPOINT
= "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL;
@Test
public void getAllWorkflowDefinitionsEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_Pagination_Size1() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT)
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(0))
)))
//Doesn't contain the other workflows
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.not(
Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(1))
)
)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_Pagination_Size1_Page1() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT)
.param("size", "1")
.param("page", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allConfiguredWorkflows.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 2
.andExpect(jsonPath("$.page.number", is(1)))
//Contains only the second configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(1))
)))
//Doesn't contain 1st configured workflow
.andExpect(jsonPath("$._embedded.workflowdefinitions", Matchers.not(
Matchers.contains(
WorkflowDefinitionMatcher.matchWorkflowDefinitionEntry(allConfiguredWorkflows.get(0))
)
)));
}
@Test
public void getAllWorkflowDefinitionsEndpoint_NonValidToken() throws Exception {
String token = "NonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowDefinitionsEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 200 OK status
.andExpect(status().isOk())
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)))
// its name is default
.andExpect(jsonPath("$.name", equalToIgnoringCase(workflowName)))
// is default
.andExpect(jsonPath("$.isDefault", is(true)));
}
@Test
public void getWorkflowDefinitionByName_NonDefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
String firstNonDefaultWorkflowName = "";
for (Workflow workflow : allConfiguredWorkflows) {
if (!workflow.getID().equalsIgnoreCase(defaultWorkflow.getID())) {
firstNonDefaultWorkflowName = workflow.getID();
}
}
if (StringUtils.isNotBlank(firstNonDefaultWorkflowName)) {
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + firstNonDefaultWorkflowName))
//We expect a 200 OK status
.andExpect(status().isOk())
//There needs to be a self link to this endpoint
.andExpect(jsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT)))
// its name is name of non-default workflow
.andExpect(jsonPath("$.name", equalToIgnoringCase(firstNonDefaultWorkflowName)))
// is not default
.andExpect(jsonPath("$.isDefault", is(false)));
}
}
@Test
public void getWorkflowDefinitionByName_NonExistentWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String workflowName = "TestNameNonExistentWorkflow9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow_NonValidToken() throws Exception {
String token = "UnvalidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getWorkflowDefinitionByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
String workflowName = defaultWorkflow.getID();
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowDefinitionByCollectionId_ExistentCollection() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
context.restoreAuthSystemState();
Workflow workflowForThisCollection = xmlWorkflowFactory.getWorkflow(col1);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid=" + col1.getID()))
//We expect a 200 OK status
.andExpect(status().isOk())
// its name is name of corresponding workflow
.andExpect(jsonPath("$.name", equalToIgnoringCase(workflowForThisCollection.getID())));
}
@Test
public void getWorkflowDefinitionByCollectionId_nonValidUUID() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nonValidUUID = "TestNonValidUUID";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid=" + nonValidUUID))
//We expect a 400 Illegal Argument Exception (Bad Request) cannot convert UUID
.andExpect(status().isBadRequest())
.andExpect(status().reason(containsString("Failed to convert " + nonValidUUID)));
}
@Test
public void getWorkflowDefinitionByCollectionId_nonExistentCollection() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
UUID nonExistentCollectionUUID = UUID.randomUUID();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/search/findByCollection?uuid="
+ nonExistentCollectionUUID))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of non-mapped collections
.andExpect(jsonPath("$.page.totalElements", is(allNonMappedCollections.size())));
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections_Paginated_Size1()
throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 1")
.build();
Collection col2 = CollectionBuilder.createCollection(context, child1, "123456789/non-mapped-collection")
.withName("Collection 2")
.build();
context.restoreAuthSystemState();
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
if (allNonMappedCollections.size() > 0) {
Collection firstNonMappedCollection = allNonMappedCollections.get(0);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections")
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(allNonMappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first non-mapped collection
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstNonMappedCollection.getName(),
firstNonMappedCollection.getID(), firstNonMappedCollection.getHandle())
)));
}
}
@Test
public void getCollectionsOfWorkflowByName_NonDefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//We turn off the authorization system in order to create the structure as defined below
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and one collection.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
// Collection with handle used in workflow.xml!
Collection col1 = CollectionBuilder.createCollection(context, child1, "123456789/workflow-test-1")
.withName("Collection 1")
.build();
context.restoreAuthSystemState();
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Workflow> allConfiguredWorkflows = xmlWorkflowFactory.getAllConfiguredWorkflows();
String firstNonDefaultWorkflowName = "";
for (Workflow workflow : allConfiguredWorkflows) {
if (!workflow.getID().equalsIgnoreCase(defaultWorkflow.getID())) {
firstNonDefaultWorkflowName = workflow.getID();
}
}
if (StringUtils.isNotBlank(firstNonDefaultWorkflowName)) {
List<Collection> mappedCollections
= xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(context, firstNonDefaultWorkflowName);
//When we call this facets endpoint
if (mappedCollections.size() > 0) {
//returns array of collection jsons that are mapped to given workflow
//When we call this facets endpoint
Collection firstMappedCollection = mappedCollections.get(0);
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + firstNonDefaultWorkflowName
+ "/collections")
.param("size", "1"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of configured workflows
.andExpect(jsonPath("$.page.totalElements", is(mappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.page.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.page.number", is(0)))
//Contains only the first mapped collection
.andExpect(jsonPath("$._embedded.collections", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstMappedCollection.getName(),
firstMappedCollection.getID(), firstMappedCollection.getHandle())
)));
} else {
//no collections mapped to this workflow
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/"
+ firstNonDefaultWorkflowName + "/collections"))
//We expect a 200 OK status
.andExpect(status().isOk())
//results in empty list
.andExpect(jsonPath("$._embedded.collections", empty()));
}
}
}
@Test
public void getCollectionsOfWorkflowByName_NonExistentWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String workflowName = "TestNameNonExistentWorkflow9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + workflowName + "/collections"))
//We expect a 404 Not Found
.andExpect(status().isNotFound());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_NoValidToken() throws Exception {
String token = "NonValidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps")
.param("projection", "full"))
//We expect a 200 OK status
.andExpect(status().isOk())
//Number of total workflows is equals to number of non-mapped collections
.andExpect(jsonPath("$.page.totalElements", is(defaultWorkflow.getSteps().size())));
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow_NoValidToken() throws Exception {
String token = "NonValidToken";
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps"))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getStepsOfWorkflowByName_DefaultWorkflow_NoToken() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<Collection> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/steps"))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
}

View File

@@ -458,8 +458,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/collection")
.param("projection", "full"))
getClient(authToken).perform(get("/api/workflow/workflowitems/" + witem.getID() + "/collection"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers
.is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()))));
@@ -767,6 +766,7 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
// submit the workspaceitem to start the workflow
getClient(authToken)
.perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems")
.param("projection", "full")
.content("/api/submission/workspaceitems/" + wsitem.getID())
.contentType(textUriContentType))
.andExpect(status().isCreated())

View File

@@ -0,0 +1,87 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.matcher.WorkflowStepMatcher;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.app.rest.repository.WorkflowStepRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Step;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Integration tests for the {@link WorkflowStepRestRepository} controlled endpoints
*
* @author Maria Verdonck (Atmire) on 13/01/2020
*/
public class WorkflowStepRestRepositoryIT extends AbstractControllerIntegrationTest {
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL;
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 405 Method not allowed status
.andExpect(status().isMethodNotAllowed());
}
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint_NonValidToken() throws Exception {
String token = "NonValidToken";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 403 Forbidden status
.andExpect(status().isForbidden());
}
@Test
public void getAllWorkflowSteps_NonImplementedEndpoint_NoToken() throws Exception {
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_ACTIONS_ENDPOINT))
//We expect a 401 Unauthorized
.andExpect(status().isUnauthorized());
}
@Test
public void getWorkflowStepByName_NonExistentWorkflowStep() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameNonExistentWorkflowActionName = "TestNameNonExistentWorkflowStep9999";
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameNonExistentWorkflowActionName))
//We expect a 404 Not Found status
.andExpect(status().isNotFound());
}
@Test
public void getWorkflowStepByName_ExistentStep_reviewstep() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
String nameStep = "reviewstep";
Step existentStep = xmlWorkflowFactory.getStepByName(nameStep);
//When we call this facets endpoint
getClient(token).perform(get(WORKFLOW_ACTIONS_ENDPOINT + "/" + nameStep)
.param("projection", "full"))
//We expect a 200 is ok status
.andExpect(status().isOk())
//Matches expected step
.andExpect(jsonPath("$", Matchers.is(
WorkflowStepMatcher.matchWorkflowStepEntry(existentStep)
)));
}
}

View File

@@ -283,8 +283,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/collection")
.param("projection", "full"))
getClient(token).perform(get("/api/submission/workspaceitems/" + witem.getID() + "/collection"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers
.is(CollectionMatcher.matchCollectionEntry(col1.getName(), col1.getID(), col1.getHandle()))
@@ -492,14 +491,14 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
String authToken = getAuthToken(admin.getEmail(), password);
// create a workspaceitem explicitly in the col1
// create a workspaceitem explicitly in the colAA1
getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("owningCollection", col1.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString())));
// create a workspaceitem explicitly in the col2
// create a workspaceitem explicitly in the colAA2
getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("owningCollection", col2.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))
@@ -508,10 +507,11 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
// create a workspaceitem without an explicit collection, this will go in the first valid collection for the
// user: the col1
getClient(authToken).perform(post("/api/submission/workspaceitems")
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))
getClient(authToken).perform(post("/api/submission/workspaceitems").param("projection", "full")
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString())));
.andExpect(jsonPath("$._embedded.collection.id", is(col1.getID().toString())))
.andExpect(jsonPath("$", WorkspaceItemMatcher.matchFullEmbeds()));
// TODO cleanup the context!!!
}
@@ -542,7 +542,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
final MockMultipartFile bibtexFile = new MockMultipartFile("file", "bibtex-test.bib", "application/x-bibtex",
bibtex);
// bulk create workspaceitems in the default collection (col1)
// bulk create workspaceitems in the default collection (colAA1)
getClient(authToken).perform(fileUpload("/api/submission/workspaceitems")
.file(bibtexFile))
// bulk create should return 200, 201 (created) is better for single resource
@@ -563,7 +563,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
jsonPath("$._embedded.workspaceitems[*]._embedded.upload").doesNotExist())
;
// bulk create workspaceitems explicitly in the col2
// bulk create workspaceitems explicitly in the colAA2
getClient(authToken).perform(fileUpload("/api/submission/workspaceitems")
.file(bibtexFile)
.param("collection", col2.getID().toString()))
@@ -681,7 +681,7 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
)))))
;
// create an empty workspaceitem explicitly in the col1, check validation on creation
// create an empty workspaceitem explicitly in the colAA1, check validation on creation
getClient(authToken).perform(post("/api/submission/workspaceitems")
.param("collection", col1.getID().toString())
.contentType(org.springframework.http.MediaType.APPLICATION_JSON))

View File

@@ -42,6 +42,13 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder<Collection> {
return builder.create(parent);
}
public static CollectionBuilder createCollection(final Context context,
final Community parent,
final String handle) {
CollectionBuilder builder = new CollectionBuilder(context);
return builder.create(parent, handle);
}
private CollectionBuilder create(final Community parent) {
try {
this.collection = collectionService.create(context, parent);
@@ -51,6 +58,20 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder<Collection> {
return this;
}
private CollectionBuilder create(final Community parent, final String handle) {
try {
for (Collection collection : this.collectionService.findAll(context)) {
if (collection.getHandle().equalsIgnoreCase(handle)) {
this.collection = collection;
}
}
this.collection = this.collectionService.create(context, parent, handle);
} catch (Exception e) {
return handleException(e);
}
return this;
}
public CollectionBuilder withName(final String name) {
return setMetadataSingleValue(collection, MetadataSchemaEnum.DC.getName(), "title", null, name);
}

View File

@@ -74,6 +74,12 @@ public class CommunityBuilder extends AbstractDSpaceObjectBuilder<Community> {
return this;
}
public CommunityBuilder addParentCommunity(final Context context, final Community parent)
throws SQLException, AuthorizeException {
communityService.addSubcommunity(context, parent, community);
return this;
}
@Override
public Community build() {
try {

View File

@@ -75,5 +75,4 @@ public class BitstreamFormatMatcher {
hasJsonPath("$.type", is("bitstreamformat"))
);
}
}

View File

@@ -31,8 +31,22 @@ public class CollectionMatcher {
public static Matcher<? super Object> matchCollectionEntry(String name, UUID uuid, String handle, Bitstream logo) {
return allOf(
matchProperties(name, uuid, handle),
matchLinks(uuid),
matchLogo(logo)
matchLinks(uuid)
);
}
public static Matcher<? super Object> matchCollectionEntryFullProjection(String name, UUID uuid, String handle) {
return matchCollectionEntryFullProjection(name, uuid, handle, null);
}
public static Matcher<? super Object> matchCollectionEntryFullProjection(String name, UUID uuid, String handle,
Bitstream logo) {
return allOf(
matchProperties(name, uuid, handle),
matchLinks(uuid),
matchLogo(logo),
matchFullEmbeds()
);
}
@@ -54,6 +68,7 @@ public class CollectionMatcher {
return matchEmbeds(
"license",
"logo",
"parentCommunity",
"mappedItems[]"
);
}
@@ -68,6 +83,7 @@ public class CollectionMatcher {
"license",
"logo",
"mappedItems",
"parentCommunity",
"self"
);
}

View File

@@ -31,8 +31,6 @@ public class CommunityMatcher {
hasJsonPath("$.uuid", is(uuid.toString())),
hasJsonPath("$.handle", is(handle)),
hasJsonPath("$.type", is("community")),
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
hasJsonPath("$._embedded.logo", Matchers.not(Matchers.empty())),
matchLinks(uuid)
);
}
@@ -53,6 +51,13 @@ public class CommunityMatcher {
}
public static Matcher<? super Object> matchCommunityEntry(String name, UUID uuid, String handle) {
return allOf(
matchProperties(name, uuid, handle),
matchLinks(uuid)
);
}
public static Matcher<? super Object> matchCommunityEntryFullProjection(String name, UUID uuid, String handle) {
return allOf(
matchProperties(name, uuid, handle),
hasJsonPath("$._embedded.collections", Matchers.not(Matchers.empty())),
@@ -80,6 +85,7 @@ public class CommunityMatcher {
return matchEmbeds(
"collections[]",
"logo",
"parentCommunity",
"subcommunities[]"
);
}
@@ -92,6 +98,7 @@ public class CommunityMatcher {
"collections",
"logo",
"self",
"parentCommunity",
"subcommunities"
);
}

View File

@@ -8,6 +8,7 @@
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
@@ -48,4 +49,13 @@ public class RelationshipMatcher {
RelationshipTypeMatcher.matchRelationshipTypeEntry(relationshipType))
);
}
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"relationshipType"
);
}
}

View File

@@ -10,6 +10,7 @@ package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
@@ -24,9 +25,9 @@ import org.hamcrest.Matcher;
* @author Mykhaylo Boychuk (4science.it)
*
*/
public class ResoucePolicyMatcher {
public class ResourcePolicyMatcher {
private ResoucePolicyMatcher() {
private ResourcePolicyMatcher() {
}
public static Matcher<? super Object> matchResourcePolicy(ResourcePolicy resourcePolicy) {
@@ -52,4 +53,15 @@ public class ResoucePolicyMatcher {
);
}
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"eperson",
"group",
"resource"
);
}
}

View File

@@ -0,0 +1,38 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.dspace.xmlworkflow.state.actions.WorkflowActionConfig;
import org.hamcrest.Matcher;
/**
* @author Maria Verdonck (Atmire) on 06/01/2020
*/
public class WorkflowActionMatcher {
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowActionRest.CATEGORY + "/" + WorkflowActionRest.NAME_PLURAL + "/";
private WorkflowActionMatcher() {
}
public static Matcher<? super Object> matchWorkflowActionEntry(WorkflowActionConfig workflowAction) {
return allOf(
hasJsonPath("$.id", is(workflowAction.getId())),
hasJsonPath("$.options", is(workflowAction.getOptions())),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_ACTIONS_ENDPOINT + workflowAction.getId()))
);
}
}

View File

@@ -0,0 +1,65 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import java.util.UUID;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
/**
* @author Maria Verdonck (Atmire) on 03/01/2020
*/
public class WorkflowDefinitionMatcher {
private static XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private static final String WORKFLOW_DEFINITIONS_ENDPOINT
= "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL + "/";
private WorkflowDefinitionMatcher() {
}
public static Matcher<? super Object> matchWorkflowDefinitionEntry(Workflow workflow) {
return allOf(
hasJsonPath("$.name", is(workflow.getID())),
hasJsonPath("$.isDefault", is(xmlWorkflowFactory.isDefaultWorkflow(workflow.getID()))),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT + workflow.getID()))
);
}
public static Matcher<? super Object> matchWorkflowOnWorkflowName(String workflowName) {
return allOf(
hasJsonPath("$.name", is(workflowName)),
hasJsonPath("$.isDefault", is(xmlWorkflowFactory.isDefaultWorkflow(workflowName))),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_DEFINITIONS_ENDPOINT + workflowName))
);
}
public static Matcher<? super Object> matchCollectionEntry(String name, UUID uuid, String handle) {
return allOf(
hasJsonPath("$.uuid", is(uuid.toString())),
hasJsonPath("$.name", is(name)),
hasJsonPath("$.handle", is(handle)),
hasJsonPath("$.type", is("collection")),
hasJsonPath("$.metadata", Matchers.allOf(
MetadataMatcher.matchMetadata("dc.title", name)
))
);
}
}

View File

@@ -0,0 +1,46 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import java.util.stream.Collectors;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.dspace.xmlworkflow.state.Step;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
/**
* @author Maria Verdonck (Atmire) on 13/01/2020
*/
public class WorkflowStepMatcher {
private static final String WORKFLOW_ACTIONS_ENDPOINT
= "/api/" + WorkflowStepRest.CATEGORY + "/" + WorkflowStepRest.NAME_PLURAL + "/";;
private WorkflowStepMatcher() {}
public static Matcher<? super Object> matchWorkflowStepEntry(Step workflowStep) {
return allOf(
hasJsonPath("$.id", is(workflowStep.getId())),
hasJsonPath("$._links.self.href", containsString(WORKFLOW_ACTIONS_ENDPOINT + workflowStep.getId())),
hasJsonPath("$._embedded.workflowactions._embedded.workflowactions", Matchers.containsInAnyOrder(
workflowStep.getActions()
.stream()
.map(x -> WorkflowActionMatcher.matchWorkflowActionEntry(x))
.collect(Collectors.toList())
))
);
}
}

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static org.dspace.app.rest.matcher.HalMatcher.matchEmbeds;
import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
@@ -127,4 +128,16 @@ public class WorkspaceItemMatcher {
hasJsonPath("$._links.submissionDefinition.href", startsWith(REST_SERVER_URL)));
}
}
/**
* Gets a matcher for all expected embeds when the full projection is requested.
*/
public static Matcher<? super Object> matchFullEmbeds() {
return matchEmbeds(
"collection",
"item",
"submitter",
"submissionDefinition"
);
}
}