DATAREST-219 - Polishing.
Generally polished implementation and test cases for Greg's contribution. Re-ordered parameters in ControllerUtils' helper methods for consistency. Use Spring's CollectionFactory to create a suitable collection for the handled properties in the first place to avoid unnecessary conversion later on. Removed duplication in test cases. Polished JavaDoc in UriListHttpMessageConverter and moved to a Scanner based implementation to read the request body. Adapted to latest changes in Spring HATEOAS. Reactivated ResourceStringUtilsTests. Related pull requests: #128, #86.
This commit is contained in:
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.mapping;
|
||||
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
|
||||
/**
|
||||
*
|
||||
* Adapter class for the {@link MessageSourceResolvable} part of a {@link ResourceDescription}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class ResolvableResourceDescriptionSupport implements ResourceDescription {
|
||||
@@ -29,7 +32,7 @@ public abstract class ResolvableResourceDescriptionSupport implements ResourceDe
|
||||
public String[] getCodes() {
|
||||
return new String[] { getMessage() };
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.MessageSourceResolvable#getArguments()
|
||||
@@ -38,7 +41,7 @@ public abstract class ResolvableResourceDescriptionSupport implements ResourceDe
|
||||
public Object[] getArguments() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.MessageSourceResolvable#getDefaultMessage()
|
||||
|
||||
@@ -106,7 +106,7 @@ class TypeBasedCollectionResourceMapping implements CollectionResourceMapping {
|
||||
*/
|
||||
@Override
|
||||
public String getItemResourceRel() {
|
||||
return relProvider.getSingleResourceRelFor(type);
|
||||
return relProvider.getItemResourceRelFor(type);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -50,10 +50,10 @@ public class RepositoryRelProvider implements RelProvider {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.RelProvider#getSingleResourceRelFor(java.lang.Class)
|
||||
* @see org.springframework.hateoas.RelProvider#getItemResourceRelFor(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public String getSingleResourceRelFor(Class<?> type) {
|
||||
public String getItemResourceRelFor(Class<?> type) {
|
||||
return mappings.getMappingFor(type).getItemResourceRel();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,13 @@ public class SimpleRelProvider implements RelProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.RelProvider#getSingleResourceRelFor(java.lang.Class)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.hateoas.RelProvider#getItemResourceRelFor(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public String getSingleResourceRelFor(Class<?> type) {
|
||||
public String getItemResourceRelFor(Class<?> type) {
|
||||
|
||||
String collectionRel = getCollectionResourceRelFor(type);
|
||||
return String.format("%s.%s", collectionRel, collectionRel);
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import static org.junit.runners.Parameterized.Parameters;
|
||||
* @author Florent Biville
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class ResourceStringUtilsTest {
|
||||
public class ResourceStringUtilsTests {
|
||||
|
||||
final String actual;
|
||||
final String expected;
|
||||
final boolean hasText;
|
||||
|
||||
public ResourceStringUtilsTest(String testDescription, String actual, String expected, boolean hasText) {
|
||||
public ResourceStringUtilsTests(String testDescription, String actual, String expected, boolean hasText) {
|
||||
|
||||
this.actual = actual;
|
||||
this.expected = expected;
|
||||
@@ -38,14 +38,15 @@ public class ControllerUtils {
|
||||
|
||||
/**
|
||||
* Wrap a resource as a {@link ResourceEntity} and attach given headers and status.
|
||||
*
|
||||
* @param status
|
||||
* @param headers
|
||||
* @param resource
|
||||
* @param status
|
||||
* @param <R>
|
||||
* @return
|
||||
*/
|
||||
public static <R extends ResourceSupport> ResponseEntity<ResourceSupport> toResponseEntity(HttpHeaders headers,
|
||||
R resource, HttpStatus status) {
|
||||
public static <R extends ResourceSupport> ResponseEntity<ResourceSupport> toResponseEntity(HttpStatus status,
|
||||
HttpHeaders headers, R resource) {
|
||||
|
||||
HttpHeaders hdrs = new HttpHeaders();
|
||||
if (null != headers) {
|
||||
@@ -57,20 +58,22 @@ public class ControllerUtils {
|
||||
|
||||
/**
|
||||
* Return an empty response that is only comprised of a status
|
||||
*
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
public static ResponseEntity<ResourceSupport> toEmptyResponse(HttpStatus status) {
|
||||
return toResponseEntity(null, EMPTY_RESOURCES, status);
|
||||
return toResponseEntity(status, null, EMPTY_RESOURCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an empty response that is only comprised of headers and a status
|
||||
* @param headers
|
||||
*
|
||||
* @param status
|
||||
* @param headers
|
||||
* @return
|
||||
*/
|
||||
public static ResponseEntity<ResourceSupport> toEmptyResponse(HttpHeaders headers, HttpStatus status) {
|
||||
return toResponseEntity(headers, EMPTY_RESOURCES, status);
|
||||
public static ResponseEntity<ResourceSupport> toEmptyResponse(HttpStatus status, HttpHeaders headers) {
|
||||
return toResponseEntity(status, headers, EMPTY_RESOURCES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
headers.setLocation(URI.create(selfLink.getHref()));
|
||||
|
||||
PersistentEntityResource<Object> resource = config.isReturnBodyOnCreate() ? perAssembler.toResource(obj) : null;
|
||||
return ControllerUtils.toResponseEntity(headers, resource, HttpStatus.CREATED);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.CREATED, headers, resource);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,9 +238,9 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
publisher.publishEvent(new AfterSaveEvent(obj));
|
||||
|
||||
if (config.isReturnBodyOnUpdate()) {
|
||||
return ControllerUtils.toResponseEntity(null, perAssembler.toResource(obj), HttpStatus.OK);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.OK, null, perAssembler.toResource(obj));
|
||||
} else {
|
||||
return ControllerUtils.toResponseEntity(null, null, HttpStatus.NO_CONTENT);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.NO_CONTENT, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.rest.webmvc;
|
||||
import static org.springframework.data.rest.webmvc.ControllerUtils.*;
|
||||
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -30,6 +29,7 @@ import java.util.Map.Entry;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
@@ -60,7 +60,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* @author Jon Brisbin
|
||||
@@ -145,7 +145,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
};
|
||||
|
||||
ResourceSupport responseResource = doWithReferencedProperty(repoRequest, id, property, handler);
|
||||
return ControllerUtils.toResponseEntity(headers, responseResource, HttpStatus.OK);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.OK, headers, responseResource);
|
||||
}
|
||||
|
||||
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.DELETE)
|
||||
@@ -244,7 +244,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
};
|
||||
|
||||
ResourceSupport responseResource = doWithReferencedProperty(repoRequest, id, property, handler);
|
||||
return ControllerUtils.toResponseEntity(headers, responseResource, HttpStatus.OK);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.OK, headers, responseResource);
|
||||
}
|
||||
|
||||
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET, produces = {
|
||||
@@ -292,7 +292,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
links.add(linkBuilder.withRel(propertyMapping.getRel()));
|
||||
}
|
||||
|
||||
return ControllerUtils.toResponseEntity(null, new Resource<Object>(EMPTY_RESOURCE_LIST, links), HttpStatus.OK);
|
||||
return ControllerUtils.toResponseEntity(HttpStatus.OK, null, new Resource<Object>(EMPTY_RESOURCE_LIST, links));
|
||||
}
|
||||
|
||||
@RequestMapping(value = BASE_MAPPING, //
|
||||
@@ -301,28 +301,28 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
@ResponseBody
|
||||
public ResponseEntity<? extends ResourceSupport> createPropertyReference(final RepositoryRestRequest repoRequest,
|
||||
final @RequestBody Resources<Object> incoming, @PathVariable String id, @PathVariable String property,
|
||||
final HttpServletRequest request)
|
||||
throws NoSuchMethodException {
|
||||
final UriComponentsBuilder builder) throws NoSuchMethodException {
|
||||
|
||||
final RepositoryInvoker invoker = repoRequest.getRepositoryInvoker();
|
||||
|
||||
if (!invoker.exposesSave()) {
|
||||
return new ResponseEntity<Resource<?>>(HttpStatus.METHOD_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
Function<ReferencedProperty, ResourceSupport> handler = new Function<ReferencedProperty, ResourceSupport>() {
|
||||
|
||||
@Override
|
||||
public ResourceSupport apply(ReferencedProperty prop) {
|
||||
|
||||
Class<?> propertyType = prop.property.getType();
|
||||
|
||||
if (prop.property.isCollectionLike()) {
|
||||
|
||||
Collection<Object> coll;
|
||||
Collection<Object> coll = CollectionFactory.createCollection(propertyType, 0);
|
||||
|
||||
// Either load the exist collection to add to it (POST)
|
||||
if (HttpMethod.POST.equals(repoRequest.getRequestMethod())) {
|
||||
coll = (Collection<Object>) prop.propertyValue;
|
||||
} else { // Or start from an empty collection to replace it (PUT)
|
||||
coll = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
// Add to the existing collection
|
||||
@@ -335,13 +335,11 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
|
||||
} else if (prop.property.isMap()) {
|
||||
|
||||
Map<String, Object> m;
|
||||
Map<String, Object> m = CollectionFactory.createMap(propertyType, 0);
|
||||
|
||||
// Either load the exist collection to add to it (POST)
|
||||
if (HttpMethod.POST.equals(repoRequest.getRequestMethod())) {
|
||||
m = (Map<String, Object>) prop.propertyValue;
|
||||
} else { // Or start from an empty collection to replace it (PUT)
|
||||
m = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
// Add to the existing collection
|
||||
@@ -378,10 +376,10 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes
|
||||
|
||||
doWithReferencedProperty(repoRequest, id, property, handler);
|
||||
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Location", String.valueOf(request.getRequestURL()));
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Location", builder.build().toUriString());
|
||||
|
||||
return ControllerUtils.toEmptyResponse(headers, HttpStatus.CREATED);
|
||||
return ControllerUtils.toEmptyResponse(HttpStatus.CREATED, headers);
|
||||
}
|
||||
|
||||
@RequestMapping(value = BASE_MAPPING + "/{propertyId}", method = RequestMethod.DELETE)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,15 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.convert;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.Resources;
|
||||
@@ -33,10 +33,15 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link Converter} to render all {@link Link}s contained in a {@link ResourceSupport} as {@code text/uri-list} and
|
||||
* parse a request of that media type back into a {@link ResourceSupport} instance.
|
||||
*
|
||||
* @author Jon Brisbin
|
||||
* @author Greg Turnquist
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class UriListHttpMessageConverter implements HttpMessageConverter<ResourceSupport> {
|
||||
|
||||
@@ -46,6 +51,10 @@ public class UriListHttpMessageConverter implements HttpMessageConverter<Resourc
|
||||
MEDIA_TYPES.add(MediaType.parseMediaType("text/uri-list"));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.HttpMessageConverter#canRead(java.lang.Class, org.springframework.http.MediaType)
|
||||
*/
|
||||
@Override
|
||||
public boolean canRead(Class<?> clazz, MediaType mediaType) {
|
||||
if (null == mediaType) {
|
||||
@@ -54,37 +63,68 @@ public class UriListHttpMessageConverter implements HttpMessageConverter<Resourc
|
||||
return ResourceSupport.class.isAssignableFrom(clazz) && mediaType.getSubtype().contains("uri-list");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.HttpMessageConverter#canWrite(java.lang.Class, org.springframework.http.MediaType)
|
||||
*/
|
||||
@Override
|
||||
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
|
||||
return canRead(clazz, mediaType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.HttpMessageConverter#getSupportedMediaTypes()
|
||||
*/
|
||||
@Override
|
||||
public List<MediaType> getSupportedMediaTypes() {
|
||||
return MEDIA_TYPES;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.HttpMessageConverter#read(java.lang.Class, org.springframework.http.HttpInputMessage)
|
||||
*/
|
||||
@Override
|
||||
public ResourceSupport read(Class<? extends ResourceSupport> clazz, HttpInputMessage inputMessage) throws IOException,
|
||||
HttpMessageNotReadableException {
|
||||
public ResourceSupport read(Class<? extends ResourceSupport> clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputMessage.getBody()));
|
||||
String line;
|
||||
while (null != (line = reader.readLine())) {
|
||||
links.add(new Link(line));
|
||||
|
||||
Scanner scanner = new Scanner(inputMessage.getBody());
|
||||
|
||||
try {
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
|
||||
String line = scanner.nextLine();
|
||||
if (StringUtils.hasText(line)) {
|
||||
links.add(new Link(line));
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
return new Resources<Object>(Collections.emptyList(), links);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.HttpMessageConverter#write(java.lang.Object, org.springframework.http.MediaType, org.springframework.http.HttpOutputMessage)
|
||||
*/
|
||||
@Override
|
||||
public void write(ResourceSupport resource, MediaType contentType, HttpOutputMessage outputMessage) throws IOException,
|
||||
HttpMessageNotWritableException {
|
||||
public void write(ResourceSupport resource, MediaType contentType, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputMessage.getBody()));
|
||||
|
||||
for (Link link : resource.getLinks()) {
|
||||
writer.write(link.getHref());
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -138,12 +138,7 @@ public abstract class AbstractWebIntegrationTests {
|
||||
|
||||
protected MockHttpServletResponse postAndGet(Link link, Object payload, MediaType mediaType) throws Exception {
|
||||
|
||||
String href;
|
||||
if (link.isTemplated()) {
|
||||
href = link.expand().getHref();
|
||||
} else {
|
||||
href = link.getHref();
|
||||
}
|
||||
String href = link.isTemplated() ? link.expand().getHref() : link.getHref();
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(post(href).content(payload.toString()).contentType(mediaType)).//
|
||||
andExpect(status().isCreated()).//
|
||||
@@ -161,12 +156,7 @@ public abstract class AbstractWebIntegrationTests {
|
||||
|
||||
protected MockHttpServletResponse putAndGet(Link link, Object payload, MediaType mediaType) throws Exception {
|
||||
|
||||
String href;
|
||||
if (link.isTemplated()) {
|
||||
href = link.expand().getHref();
|
||||
} else {
|
||||
href = link.getHref();
|
||||
}
|
||||
String href = link.isTemplated() ? link.expand().getHref() : link.getHref();
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(put(href).content(payload.toString()).contentType(mediaType)).//
|
||||
andExpect(status().isCreated()).//
|
||||
@@ -184,12 +174,7 @@ public abstract class AbstractWebIntegrationTests {
|
||||
|
||||
protected MockHttpServletResponse deleteAndGet(Link link, MediaType mediaType) throws Exception {
|
||||
|
||||
String href;
|
||||
if (link.isTemplated()) {
|
||||
href = link.expand().getHref();
|
||||
} else {
|
||||
href = link.getHref();
|
||||
}
|
||||
String href = link.isTemplated() ? link.expand().getHref() : link.getHref();
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(delete(href).contentType(mediaType)).//
|
||||
andExpect(status().isNoContent()).//
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.rest.webmvc.jpa;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
@@ -23,11 +23,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import net.minidev.json.JSONArray;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -41,12 +40,11 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriTemplate;
|
||||
|
||||
/**
|
||||
* Web integration tests specific to JPA.
|
||||
@@ -194,40 +192,24 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
mvc.perform(get(href)).andExpect(status().isOk());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see DATAREST-219
|
||||
*/
|
||||
@Test
|
||||
public void manipulatePropertyCollectionRestfullyWithMultiplePosts() throws Exception {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
|
||||
new Person("Bilbo", "Baggins"), //
|
||||
new Person("Merry", "Baggins"), //
|
||||
new Person("Pippin", "Baggins"));
|
||||
|
||||
String bilbo = mapper.writeValueAsString(new Person("Bilbo", "Baggins"));
|
||||
String frodo = mapper.writeValueAsString(new Person("Frodo", "Baggins"));
|
||||
String merry = mapper.writeValueAsString(new Person("Merry", "Baggins"));
|
||||
String pippin = mapper.writeValueAsString(new Person("Pippin", "Baggins"));
|
||||
Link frodosSiblingLink = links.get(0);
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
postAndGet(frodosSiblingLink, links.get(1).getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingLink, links.get(2).getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingLink, links.get(3).getHref(), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse bilboResponse = postAndGet(peopleLink, bilbo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse frodoResponse = postAndGet(peopleLink, frodo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse merryResponse = postAndGet(peopleLink, merry, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse pippinResponse = postAndGet(peopleLink, pippin, MediaType.APPLICATION_JSON);
|
||||
|
||||
Link bilboSelfLink = assertHasLinkWithRel(Link.REL_SELF, bilboResponse);
|
||||
Link merrySelfLink = assertHasLinkWithRel(Link.REL_SELF, merryResponse);
|
||||
Link pippinSelfLink = assertHasLinkWithRel(Link.REL_SELF, pippinResponse);
|
||||
Link frodosSiblingsLink = assertHasLinkWithRel("siblings", frodoResponse);
|
||||
|
||||
postAndGet(frodosSiblingsLink, bilboSelfLink.getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, merrySelfLink.getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, pippinSelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String[] persons = ((JSONArray) JsonPath.read(frodosLatestSiblings.getContentAsString(), "$._embedded.persons[*].firstName")).toArray(new String[]{});
|
||||
assertThat(persons.length, equalTo(3));
|
||||
assertThat(Arrays.asList(persons), hasItems("Bilbo", "Merry", "Pippin"));
|
||||
assertSiblingNames(frodosSiblingLink, "Bilbo", "Merry", "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,34 +218,16 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
@Test
|
||||
public void manipulatePropertyCollectionRestfullyWithSinglePost() throws Exception {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
|
||||
new Person("Bilbo", "Baggins"), //
|
||||
new Person("Merry", "Baggins"), //
|
||||
new Person("Pippin", "Baggins"));
|
||||
|
||||
String bilbo = mapper.writeValueAsString(new Person("Bilbo", "Baggins"));
|
||||
String frodo = mapper.writeValueAsString(new Person("Frodo", "Baggins"));
|
||||
String merry = mapper.writeValueAsString(new Person("Merry", "Baggins"));
|
||||
String pippin = mapper.writeValueAsString(new Person("Pippin", "Baggins"));
|
||||
Link frodosSiblingLink = links.get(0);
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
postAndGet(frodosSiblingLink, toUriList(links.get(1), links.get(2), links.get(3)), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse bilboResponse = postAndGet(peopleLink, bilbo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse frodoResponse = postAndGet(peopleLink, frodo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse merryResponse = postAndGet(peopleLink, merry, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse pippinResponse = postAndGet(peopleLink, pippin, MediaType.APPLICATION_JSON);
|
||||
|
||||
final Link bilboSelfLink = assertHasLinkWithRel(Link.REL_SELF, bilboResponse);
|
||||
final Link merrySelfLink = assertHasLinkWithRel(Link.REL_SELF, merryResponse);
|
||||
final Link pippinSelfLink = assertHasLinkWithRel(Link.REL_SELF, pippinResponse);
|
||||
Link frodosSiblingsLink = assertHasLinkWithRel("siblings", frodoResponse);
|
||||
|
||||
postAndGet(frodosSiblingsLink,
|
||||
StringUtils.arrayToDelimitedString(new Object[]{bilboSelfLink.getHref(),
|
||||
merrySelfLink.getHref(), pippinSelfLink.getHref()}, "\n"),
|
||||
TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String[] persons = ((JSONArray) JsonPath.read(frodosLatestSiblings.getContentAsString(), "$._embedded.persons[*].firstName")).toArray(new String[]{});
|
||||
assertThat(persons.length, equalTo(3));
|
||||
assertThat(Arrays.asList(persons), hasItems("Bilbo", "Merry", "Pippin"));
|
||||
assertSiblingNames(frodosSiblingLink, "Bilbo", "Merry", "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,40 +236,20 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
@Test
|
||||
public void manipulatePropertyCollectionRestfullyWithMultiplePuts() throws Exception {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
|
||||
new Person("Bilbo", "Baggins"), //
|
||||
new Person("Merry", "Baggins"), //
|
||||
new Person("Pippin", "Baggins"));
|
||||
|
||||
String bilbo = mapper.writeValueAsString(new Person("Bilbo", "Baggins"));
|
||||
String frodo = mapper.writeValueAsString(new Person("Frodo", "Baggins"));
|
||||
String merry = mapper.writeValueAsString(new Person("Merry", "Baggins"));
|
||||
String pippin = mapper.writeValueAsString(new Person("Pippin", "Baggins"));
|
||||
Link frodosSiblingsLink = links.get(0);
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
putAndGet(frodosSiblingsLink, links.get(1).getHref(), TEXT_URI_LIST);
|
||||
putAndGet(frodosSiblingsLink, links.get(2).getHref(), TEXT_URI_LIST);
|
||||
putAndGet(frodosSiblingsLink, links.get(3).getHref(), TEXT_URI_LIST);
|
||||
assertSiblingNames(frodosSiblingsLink, "Pippin");
|
||||
|
||||
MockHttpServletResponse bilboResponse = postAndGet(peopleLink, bilbo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse frodoResponse = postAndGet(peopleLink, frodo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse merryResponse = postAndGet(peopleLink, merry, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse pippinResponse = postAndGet(peopleLink, pippin, MediaType.APPLICATION_JSON);
|
||||
|
||||
Link bilboSelfLink = assertHasLinkWithRel(Link.REL_SELF, bilboResponse);
|
||||
Link merrySelfLink = assertHasLinkWithRel(Link.REL_SELF, merryResponse);
|
||||
Link pippinSelfLink = assertHasLinkWithRel(Link.REL_SELF, pippinResponse);
|
||||
Link frodosSiblingsLink = assertHasLinkWithRel("siblings", frodoResponse);
|
||||
|
||||
putAndGet(frodosSiblingsLink, bilboSelfLink.getHref(), TEXT_URI_LIST);
|
||||
putAndGet(frodosSiblingsLink, merrySelfLink.getHref(), TEXT_URI_LIST);
|
||||
putAndGet(frodosSiblingsLink, pippinSelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String firstName = JsonPath.read(frodosLatestSiblings.getContentAsString(), "$._embedded.person.firstName");
|
||||
assertThat(firstName, equalTo("Pippin"));
|
||||
|
||||
postAndGet(frodosSiblingsLink, merrySelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String[] persons = ((JSONArray) JsonPath.read(frodosLatestSiblings.getContentAsString(),
|
||||
"$._embedded.persons[*].firstName")).toArray(new String[]{});
|
||||
assertThat(persons.length, equalTo(2));
|
||||
assertThat(Arrays.asList(persons), hasItems("Merry", "Pippin"));
|
||||
postAndGet(frodosSiblingsLink, links.get(2).getHref(), TEXT_URI_LIST);
|
||||
assertSiblingNames(frodosSiblingsLink, "Merry", "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,42 +258,21 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
@Test
|
||||
public void manipulatePropertyCollectionRestfullyWithSinglePut() throws Exception {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
|
||||
new Person("Bilbo", "Baggins"), //
|
||||
new Person("Merry", "Baggins"), //
|
||||
new Person("Pippin", "Baggins"));
|
||||
|
||||
String bilbo = mapper.writeValueAsString(new Person("Bilbo", "Baggins"));
|
||||
String frodo = mapper.writeValueAsString(new Person("Frodo", "Baggins"));
|
||||
String merry = mapper.writeValueAsString(new Person("Merry", "Baggins"));
|
||||
String pippin = mapper.writeValueAsString(new Person("Pippin", "Baggins"));
|
||||
Link frodoSiblingLink = links.get(0);
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
putAndGet(frodoSiblingLink, toUriList(links.get(1), links.get(2), (links.get(3))), TEXT_URI_LIST);
|
||||
assertSiblingNames(frodoSiblingLink, "Bilbo", "Merry", "Pippin");
|
||||
|
||||
MockHttpServletResponse bilboResponse = postAndGet(peopleLink, bilbo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse frodoResponse = postAndGet(peopleLink, frodo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse merryResponse = postAndGet(peopleLink, merry, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse pippinResponse = postAndGet(peopleLink, pippin, MediaType.APPLICATION_JSON);
|
||||
putAndGet(frodoSiblingLink, toUriList(links.get(3)), TEXT_URI_LIST);
|
||||
assertSiblingNames(frodoSiblingLink, "Pippin");
|
||||
|
||||
Link bilboSelfLink = assertHasLinkWithRel(Link.REL_SELF, bilboResponse);
|
||||
Link merrySelfLink = assertHasLinkWithRel(Link.REL_SELF, merryResponse);
|
||||
Link pippinSelfLink = assertHasLinkWithRel(Link.REL_SELF, pippinResponse);
|
||||
Link frodosSiblingsLink = assertHasLinkWithRel("siblings", frodoResponse);
|
||||
|
||||
putAndGet(frodosSiblingsLink,
|
||||
StringUtils.arrayToDelimitedString(new Object[]{bilboSelfLink.getHref(),
|
||||
merrySelfLink.getHref()}, "\n"),
|
||||
TEXT_URI_LIST);
|
||||
putAndGet(frodosSiblingsLink, pippinSelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String firstName = JsonPath.read(frodosLatestSiblings.getContentAsString(), "$._embedded.person.firstName");
|
||||
assertThat(firstName, equalTo("Pippin"));
|
||||
|
||||
postAndGet(frodosSiblingsLink, merrySelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String[] persons = ((JSONArray) JsonPath.read(frodosLatestSiblings.getContentAsString(),
|
||||
"$._embedded.persons[*].firstName")).toArray(new String[]{});
|
||||
assertThat(persons.length, equalTo(2));
|
||||
assertThat(Arrays.asList(persons), hasItems("Merry", "Pippin"));
|
||||
postAndGet(frodoSiblingLink, toUriList(links.get(2)), TEXT_URI_LIST);
|
||||
assertSiblingNames(frodoSiblingLink, "Merry", "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,49 +281,88 @@ public class JpaWebTests extends AbstractWebIntegrationTests {
|
||||
@Test
|
||||
public void manipulatePropertyCollectionRestfullyWithDelete() throws Exception {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
|
||||
new Person("Bilbo", "Baggins"), //
|
||||
new Person("Merry", "Baggins"), //
|
||||
new Person("Pippin", "Baggins"));
|
||||
|
||||
String bilbo = mapper.writeValueAsString(new Person("Bilbo", "Baggins"));
|
||||
String frodo = mapper.writeValueAsString(new Person("Frodo", "Baggins"));
|
||||
String merry = mapper.writeValueAsString(new Person("Merry", "Baggins"));
|
||||
String pippin = mapper.writeValueAsString(new Person("Pippin", "Baggins"));
|
||||
Link frodosSiblingsLink = links.get(0);
|
||||
|
||||
Link peopleLink = discoverUnique("people");
|
||||
postAndGet(frodosSiblingsLink, links.get(1).getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, links.get(2).getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, links.get(3).getHref(), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse bilboResponse = postAndGet(peopleLink, bilbo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse frodoResponse = postAndGet(peopleLink, frodo, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse merryResponse = postAndGet(peopleLink, merry, MediaType.APPLICATION_JSON);
|
||||
MockHttpServletResponse pippinResponse = postAndGet(peopleLink, pippin, MediaType.APPLICATION_JSON);
|
||||
|
||||
Link bilboSelfLink = assertHasLinkWithRel(Link.REL_SELF, bilboResponse);
|
||||
Link merrySelfLink = assertHasLinkWithRel(Link.REL_SELF, merryResponse);
|
||||
Link pippinSelfLink = assertHasLinkWithRel(Link.REL_SELF, pippinResponse);
|
||||
Link frodosSiblingsLink = assertHasLinkWithRel("siblings", frodoResponse);
|
||||
|
||||
postAndGet(frodosSiblingsLink, bilboSelfLink.getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, merrySelfLink.getHref(), TEXT_URI_LIST);
|
||||
postAndGet(frodosSiblingsLink, pippinSelfLink.getHref(), TEXT_URI_LIST);
|
||||
|
||||
String pippinId = new UriTemplate("/people/{id}").match(pippinSelfLink.getHref()).get("id");
|
||||
String pippinId = new UriTemplate("/people/{id}").match(links.get(3).getHref()).get("id");
|
||||
deleteAndGet(new Link(frodosSiblingsLink.getHref() + "/" + pippinId), TEXT_URI_LIST);
|
||||
|
||||
MockHttpServletResponse frodosLatestSiblings = request(frodosSiblingsLink);
|
||||
String[] persons = ((JSONArray) JsonPath.read(frodosLatestSiblings.getContentAsString(), "$._embedded.persons[*].firstName")).toArray(new String[]{});
|
||||
assertThat(persons.length, equalTo(2));
|
||||
assertThat(Arrays.asList(persons), hasItems("Bilbo", "Merry"));
|
||||
assertSiblingNames(frodosSiblingsLink, "Bilbo", "Merry");
|
||||
}
|
||||
|
||||
private List<Link> preparePersonResources(Person primary, Person... persons) throws Exception {
|
||||
|
||||
private String readFile(String name) throws Exception {
|
||||
Link peopleLink = discoverUnique("people");
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
List<Link> links = new ArrayList<Link>();
|
||||
|
||||
ClassPathResource file = new ClassPathResource(name, getClass());
|
||||
MockHttpServletResponse primaryResponse = postAndGet(peopleLink, mapper.writeValueAsString(primary),
|
||||
MediaType.APPLICATION_JSON);
|
||||
links.add(assertHasLinkWithRel("siblings", primaryResponse));
|
||||
|
||||
for (Person person : persons) {
|
||||
|
||||
String payload = mapper.writeValueAsString(person);
|
||||
MockHttpServletResponse response = postAndGet(peopleLink, payload, MediaType.APPLICATION_JSON);
|
||||
|
||||
links.add(assertHasLinkWithRel(Link.REL_SELF, response));
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the {@link Person} resource the given link points to contains siblings with the given names.
|
||||
*
|
||||
* @param link
|
||||
* @param siblingNames
|
||||
* @throws Exception
|
||||
*/
|
||||
private void assertSiblingNames(Link link, String... siblingNames) throws Exception {
|
||||
|
||||
String responseBody = request(link).getContentAsString();
|
||||
List<String> persons = JsonPath.read(responseBody, "$._embedded.persons[*].firstName");
|
||||
|
||||
assertThat(persons, hasSize(siblingNames.length));
|
||||
assertThat(persons, hasItems(siblingNames));
|
||||
}
|
||||
|
||||
private static String readFile(String name) throws Exception {
|
||||
|
||||
ClassPathResource file = new ClassPathResource(name, JpaWebTests.class);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
Scanner scanner = new Scanner(file.getFile(), "UTF-8");
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
builder.append(scanner.nextLine());
|
||||
try {
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
builder.append(scanner.nextLine());
|
||||
}
|
||||
|
||||
} finally {
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String toUriList(Link... links) {
|
||||
|
||||
List<String> uris = new ArrayList<String>(links.length);
|
||||
|
||||
for (Link link : links) {
|
||||
uris.add(link.expand().getHref());
|
||||
}
|
||||
|
||||
return StringUtils.collectionToDelimitedString(uris, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user