[DS-3909] Corrects UUID bug in RestResourceController.

This commit is contained in:
Michael W Spalti
2018-05-15 12:11:46 -07:00
parent 211a9e215f
commit 416fc80010
3 changed files with 303 additions and 156 deletions

View File

@@ -542,17 +542,17 @@ public class RestResourceController implements InitializingBean {
* @param request
* @param apiCategory
* @param model
* @param id
* @param uuid
* @param jsonNode
* @return
* @throws HttpRequestMethodNotSupportedException
*/
@RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_UUID)
public ResponseEntity<ResourceSupport> patch(HttpServletRequest request, @PathVariable String apiCategory,
@PathVariable String model, @PathVariable UUID id,
@PathVariable String model, @PathVariable UUID uuid,
@RequestBody(required = true) JsonNode jsonNode)
throws HttpRequestMethodNotSupportedException {
return patchInternal(request, apiCategory, model, id, jsonNode);
return patchInternal(request, apiCategory, model, uuid, jsonNode);
}
/**

View File

@@ -12,10 +12,17 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.dspace.app.rest.converter.ItemConverter;
import org.dspace.app.rest.exception.PatchBadRequestException;
import org.dspace.app.rest.exception.PatchUnprocessableEntityException;
import org.dspace.app.rest.model.ItemRest;
import org.dspace.app.rest.model.hateoas.ItemResource;
import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.Patch;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
@@ -34,13 +41,20 @@ import org.springframework.stereotype.Component;
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME)
public class ItemRestRepository extends DSpaceRestRepository<ItemRest, UUID> {
private static final String OPERATION_PATH_WITHDRAW = "withdraw";
private static final String OPERATION_PATH_REINSTATE = "reinstate";
private static final String OPERATION_PATH_DISCOVERABLE = "discoverable";
private static final Logger log = Logger.getLogger(ItemRestRepository.class);
@Autowired
ItemService is;
@Autowired
ItemConverter converter;
public ItemRestRepository() {
System.out.println("Repository initialized by Spring");
}
@@ -78,6 +92,77 @@ public class ItemRestRepository extends DSpaceRestRepository<ItemRest, UUID> {
return page;
}
@Override
public void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID id, Patch
patch)
throws PatchUnprocessableEntityException, PatchBadRequestException, SQLException, AuthorizeException {
Item item;
try {
item = is.find(context, id);
} catch (SQLException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
// temporarily turn off authorization
context.turnOffAuthorisationSystem();
List<Operation> operations = patch.getOperations();
for (Operation op : operations) {
if ("replace".equals(op.getOp())) {
String path = op.getPath();
switch (path) {
case OPERATION_PATH_WITHDRAW:
withdraw(context, item);
break;
case OPERATION_PATH_REINSTATE:
reinstate(context, item);
break;
case OPERATION_PATH_DISCOVERABLE:
item.setDiscoverable((boolean) op.getValue());
break;
default:
break;
}
}
}
// restore authorization
context.restoreAuthSystemState();
// Do we want to return the updated item json? Something else?
findOne(context, id);
}
private void withdraw(Context context, Item item) throws PatchUnprocessableEntityException,
SQLException, AuthorizeException {
try {
if (!item.isArchived()) {
throw new PatchUnprocessableEntityException("Item is not in the archive. Cannot be withdrawn.");
}
is.withdraw(context, item);
} catch (SQLException | AuthorizeException e) {
log.error(e.getMessage(), e);
throw e;
}
}
private void reinstate(Context context, Item item) throws PatchUnprocessableEntityException,
SQLException, AuthorizeException {
try {
is.reinstate(context, item);
} catch (SQLException | AuthorizeException e) {
log.error(e.getMessage(), e);
throw e;
}
}
@Override
public Class<ItemRest> getDomainClass() {
return ItemRest.class;

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -16,6 +17,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.io.InputStream;
import java.util.UUID;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.dspace.app.rest.builder.BitstreamBuilder;
@@ -40,48 +43,48 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
getClient().perform(get("/api/core/items"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(3)))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(3)))
;
}
@@ -92,68 +95,68 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
getClient().perform(get("/api/core/items")
.param("size", "2"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)))
.andExpect(jsonPath("$._embedded.items", Matchers.not(
Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.param("size", "2"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)))
.andExpect(jsonPath("$._embedded.items", Matchers.not(
Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/items")
.param("size", "2")
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)))
.andExpect(jsonPath("$._embedded.items", Matchers.not(
Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", is(3)))
.param("size", "2")
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.items", Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem3, "Public item 3", "2016-02-13")
)))
.andExpect(jsonPath("$._embedded.items", Matchers.not(
Matchers.contains(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalElements", is(3)))
;
}
@@ -164,49 +167,49 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
getClient().perform(get("/api/core/items/" + publicItem1.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17")
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17")
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
}
@@ -217,72 +220,72 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
.withTitle("Public item 2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
.withTitle("Public item 3")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
//Add a bitstream to an item
String bitstreamContent = "ThisIsSomeDummyText";
Bitstream bitstream1 = null;
try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) {
bitstream1 = BitstreamBuilder.
createBitstream(context, publicItem1, is)
.withName("Bitstream1")
.withMimeType("text/plain")
.build();
createBitstream(context, publicItem1, is)
.withName("Bitstream1")
.withMimeType("text/plain")
.build();
}
getClient().perform(get("/api/core/items/" + publicItem1.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17")
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17")
)))
.andExpect(jsonPath("$", Matchers.not(
Matchers.is(
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem2, "Public item 2", "2016-02-13")
)
)))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
;
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/bitstreams"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/core/items/" + publicItem1.getID() + "/bitstreams")))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._links.self.href", Matchers
.containsString("/api/core/items/" + publicItem1.getID() + "/bitstreams")))
;
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/owningCollection"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/collections")))
;
getClient().perform(get("/api/core/items/" + publicItem1.getID() + "/templateItemOf"))
@@ -298,17 +301,76 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
//** GIVEN **
//1. A community-collection structure with one parent community with sub-community and two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
.withName("Parent Community")
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.build();
.withName("Sub Community")
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
getClient().perform(get("/api/core/items/" + UUID.randomUUID()))
.andExpect(status().isNotFound());
.andExpect(status().isNotFound());
;
}
@Test
public void patchTest() throws Exception {
String token = getAuthToken(eperson.getEmail(), password);
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();
//2. One public item
Item item = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
// withdraw item
getClient(token).perform(patch("/api/core/items/" + item.getID())
.content("[{\"op\":\"replace\",\"path\":\"withdraw\"}]")
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.uuid", Matchers.is(item.getID().toString())))
.andExpect(jsonPath("$.withdrawn", Matchers.is(true)))
.andExpect(jsonPath("$.inArchive", Matchers.is(false)));
// should return 422 because item is not in archive
getClient(token).perform(patch("/api/core/items/" + item.getID())
.content("[{\"op\":\"replace\",\"path\":\"withdraw\"}]")
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isUnprocessableEntity());
// reinstate item
getClient(token).perform(patch("/api/core/items/" + item.getID())
.content("[{\"op\":\"replace\",\"path\":\"reinstate\"}]")
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.uuid", Matchers.is(item.getID().toString())))
.andExpect(jsonPath("$.withdrawn", Matchers.is(false)))
.andExpect(jsonPath("$.inArchive", Matchers.is(true)));
// make private
getClient(token).perform(patch("/api/core/items/" + item.getID())
.content("[{\"op\":\"replace\",\"path\":\"discoverable\",\"value\":false}]")
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.uuid", Matchers.is(item.getID().toString())))
.andExpect(jsonPath("$.discoverable", Matchers.is(false)));
}
}