68150: /workflowdefinitions/defaultWorkflow/collections now returns all non-mapped collections and now returns paginated result + tests

This commit is contained in:
Marie Verdonck
2020-01-06 12:50:52 +01:00
parent 7ed292e754
commit a254ae31e2
5 changed files with 141 additions and 26 deletions

View File

@@ -7,6 +7,7 @@
*/
package org.dspace.xmlworkflow;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -14,8 +15,11 @@ 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.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
/**
@@ -37,6 +41,9 @@ public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
private Map<String, Workflow> workflowMapping;
@Autowired(required = true)
protected CollectionService collectionService;
@Override
public Workflow getWorkflow(Collection collection) throws WorkflowConfigurationException {
// Attempt to retrieve our workflow object
@@ -90,6 +97,22 @@ public class XmlWorkflowFactoryImpl implements XmlWorkflowFactory {
return collectionsMapped;
}
@Override
public List<String> getAllNonMappedCollectionsHandles(Context context) {
List<String> nonMappedCollectionHandles = new ArrayList<>();
try {
for (Collection collection: this.collectionService.findAll(context)) {
if (workflowMapping.get(collection.getHandle()) == null) {
nonMappedCollectionHandles.add(collection.getHandle());
}
}
} catch (SQLException e) {
log.error("SQLException in XmlWorkflowFactoryImpl.getAllNonMappedCollectionsHandles trying to " +
"retrieve all collections");
}
return nonMappedCollectionHandles;
}
@Override
public boolean workflowByThisNameExists(String workflowName) {
for (Workflow workflow : this.workflowMapping.values()) {

View File

@@ -10,6 +10,7 @@ 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.Workflow;
@@ -64,8 +65,9 @@ public interface XmlWorkflowFactory {
/**
* 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
*
* @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);
@@ -82,4 +84,12 @@ public interface XmlWorkflowFactory {
* @return List of collection handles mapped to the requested workflow
*/
public List<String> getCollectionHandlesMappedToWorklow(String workflowName);
/**
* Returns list of collection handles that are not mapped to any configured workflow, and thus use the default
* workflow
*
* @return List of collection handles not mapped to any workflow
*/
public List<String> getAllNonMappedCollectionsHandles(Context context);
}

View File

@@ -25,6 +25,8 @@ import org.dspace.handle.service.HandleService;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@@ -61,20 +63,25 @@ public class WorkflowDefinitionController {
* @throws SQLException if db error
*/
@GetMapping("{workflowName}/collections")
public List<CollectionRest> get(HttpServletRequest request, HttpServletResponse response,
@PathVariable String workflowName) throws SQLException {
public Page<CollectionRest> get(HttpServletRequest request, HttpServletResponse response,
@PathVariable String workflowName, Pageable pageable) throws SQLException {
if (xmlWorkflowFactory.workflowByThisNameExists(workflowName)) {
List<String> collectionsHandlesMappedToWorkflow
= xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(workflowName);
List<CollectionRest> collectionResourcesFromHandles = new ArrayList<>();
Context context = ContextUtil.obtainContext(request);
List<String> collectionsHandlesMappedToWorkflow;
if (xmlWorkflowFactory.isDefaultWorkflow(workflowName)) {
collectionsHandlesMappedToWorkflow = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
} else {
collectionsHandlesMappedToWorkflow
= xmlWorkflowFactory.getCollectionHandlesMappedToWorklow(workflowName);
}
List<Collection> collectionsFromHandles = new ArrayList<>();
for (String handle : collectionsHandlesMappedToWorkflow) {
Context context = ContextUtil.obtainContext(request);
Collection collection = (Collection) handleService.resolveToObject(context, handle);
if (collection != null) {
collectionResourcesFromHandles.add(converter.toRest(collection, utils.obtainProjection()));
collectionsFromHandles.add(collection);
}
}
return collectionResourcesFromHandles;
return converter.toRestPage(utils.getPage(collectionsFromHandles, pageable), utils.obtainProjection(true));
} else {
throw new ResourceNotFoundException("No workflow with name " + workflowName + " is configured");
}

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.rest;
import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalToIgnoringCase;
@@ -20,23 +19,21 @@ import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.matcher.EPersonMatcher;
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.handle.factory.HandleServiceFactory;
import org.dspace.handle.service.HandleService;
import org.dspace.xmlworkflow.factory.XmlWorkflowFactory;
import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory;
import org.dspace.xmlworkflow.state.Workflow;
import org.hamcrest.Matchers;
import org.json.JSONArray;
import org.junit.Test;
import org.springframework.test.web.servlet.MvcResult;
/**
* Integration tests for the {@link WorkflowDefinitionRestRepository} and {@link WorkflowDefinitionController} controlled endpoints
@@ -45,10 +42,8 @@ import org.springframework.test.web.servlet.MvcResult;
*/
public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegrationTest {
private static final Logger log
= org.apache.logging.log4j.LogManager.getLogger(WorkflowDefinitionRestRepositoryIT.class);
private XmlWorkflowFactory xmlWorkflowFactory = XmlWorkflowServiceFactory.getInstance().getWorkflowFactory();
private HandleService handleService = HandleServiceFactory.getInstance().getHandleService();
private static final String WORKFLOW_DEFINITIONS_ENDPOINT
= "/api/" + WorkflowDefinitionRest.CATEGORY + "/" + WorkflowDefinitionRest.NAME_PLURAL;
@@ -215,15 +210,65 @@ public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegr
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_EmptyList() throws Exception {
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections() throws Exception {
Workflow defaultWorkflow = xmlWorkflowFactory.getDefaultWorkflow();
List<String> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
//When we call this facets endpoint
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/" + defaultWorkflow.getID()
+ "/collections"))
//We expect a 200 OK status
.andExpect(status().isOk())
.andExpect(jsonPath("$", empty()));
//Number of total workflows is equals to number of non-mapped collections
.andExpect(jsonPath("$.totalElements", is(allNonMappedCollections.size())));
}
@Test
public void getCollectionsOfWorkflowByName_DefaultWorkflow_AllNonMappedCollections_Paginated_Size1()
throws Exception {
//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<String> allNonMappedCollections = xmlWorkflowFactory.getAllNonMappedCollectionsHandles(context);
if (allNonMappedCollections.size() > 0) {
Collection firstNonMappedCollection =
(Collection) handleService.resolveToObject(context, allNonMappedCollections.get(0));
//When we call this facets endpoint
getClient().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("$.totalElements", is(allNonMappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.number", is(0)))
//Contains only the first non-mapped collection
.andExpect(jsonPath("$.content", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstNonMappedCollection.getName(),
firstNonMappedCollection.getID(), firstNonMappedCollection.getHandle())
)));
}
}
@Test
@@ -259,11 +304,25 @@ public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegr
//When we call this facets endpoint
if (handlesOfMappedCollections.size() > 0) {
//returns array of collection jsons that are mapped to given workflow
MvcResult result = getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/"
+ firstNonDefaultWorkflowName + "/collections")).andReturn();
String response = result.getResponse().getContentAsString();
JSONArray collectionsResult = new JSONArray(response);
assertEquals(collectionsResult.length(), handlesOfMappedCollections.size());
//When we call this facets endpoint
Collection firstMappedCollection =
(Collection) handleService.resolveToObject(context, handlesOfMappedCollections.get(0));
getClient().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("$.totalElements", is(handlesOfMappedCollections.size())))
//Page size is 1
.andExpect(jsonPath("$.size", is(1)))
//Page nr is 1
.andExpect(jsonPath("$.number", is(0)))
//Contains only the first mapped collection
.andExpect(jsonPath("$.content", Matchers.contains(
WorkflowDefinitionMatcher.matchCollectionEntry(firstMappedCollection.getName(),
firstMappedCollection.getID(), firstMappedCollection.getHandle())
)));
} else {
//no collections mapped to this workflow
getClient().perform(get(WORKFLOW_DEFINITIONS_ENDPOINT + "/"
@@ -271,7 +330,7 @@ public class WorkflowDefinitionRestRepositoryIT extends AbstractControllerIntegr
//We expect a 200 OK status
.andExpect(status().isOk())
//results in empty list
.andExpect(jsonPath("$", empty()));
.andExpect(jsonPath("$.content", empty()));
}
}
}

View File

@@ -16,7 +16,11 @@ 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;
import java.util.UUID;
/**
* @author Maria Verdonck (Atmire) on 03/01/2020
@@ -46,4 +50,16 @@ public class WorkflowDefinitionMatcher {
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)
))
);
}
}