DATAREST-1356 - Fix updating single associations.
Correct a regression regarding association links. Introduce several test cases to prove this situation is fixed regarding PUTs for association links.
Source of the bug: 554d6cb27b (diff-1d7c16fe1992fef13a47fa8ab8599718L317) flips the criteria from "not single" to "single" without checking for related impacts.
This commit is contained in:
committed by
Greg Turnquist
parent
1e588b5c5a
commit
87f9904e3a
@@ -28,7 +28,6 @@ import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
|
||||
import org.springframework.hateoas.Link;
|
||||
@@ -61,6 +60,7 @@ import com.jayway.jsonpath.JsonPath;
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
* @author Ľubomír Varga
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebAppConfiguration
|
||||
@@ -115,6 +115,17 @@ public abstract class AbstractWebIntegrationTests {
|
||||
return StringUtils.hasText(response.getContentAsString()) ? response : client.request(link);
|
||||
}
|
||||
|
||||
protected MockHttpServletResponse putOnlyExpect5XXStatus(Link link, Object payload, MediaType mediaType)
|
||||
throws Exception {
|
||||
|
||||
String href = link.isTemplated() ? link.expand().getHref() : link.getHref();
|
||||
|
||||
MockHttpServletResponse response = mvc.perform(put(href).content(payload.toString()).contentType(mediaType))//
|
||||
.andExpect(status().is5xxServerError()).andReturn().getResponse();
|
||||
|
||||
return StringUtils.hasText(response.getContentAsString()) ? response : client.request(link);
|
||||
}
|
||||
|
||||
protected MockHttpServletResponse patchAndGet(Link link, Object payload, MediaType mediaType) throws Exception {
|
||||
|
||||
String href = link.isTemplated() ? link.expand().getHref() : link.getHref();
|
||||
|
||||
@@ -61,6 +61,7 @@ import com.jayway.jsonpath.JsonPath;
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
* @author Mark Paluch
|
||||
* @author Ľubomír Varga
|
||||
*/
|
||||
@Transactional
|
||||
@ContextConfiguration(classes = JpaRepositoryConfig.class)
|
||||
@@ -321,6 +322,40 @@ public class JpaWebTests extends CommonWebTests {
|
||||
assertSiblingNames(frodoSiblingLink, "Merry", "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test does simulate changing creator association from Order to Person. First it sets Frodo Baggins as creator and
|
||||
* checks for its first name. Than it sets Pippin Baggins as creator of the Order. Check for first name is done again.
|
||||
*/
|
||||
@Test // DATAREST-1356
|
||||
public void associateCreatorToOrderWithSinglePut() throws Exception {
|
||||
|
||||
Link firstCreatorLink = preparePersonResource(new Person("Frodo", "Baggins"));
|
||||
Link secondCreatorLink = preparePersonResource(new Person("Pippin", "Baggins"));
|
||||
Link orderLinkToItsCreator = prepareOrderResource(new Order());
|
||||
|
||||
putAndGet(orderLinkToItsCreator, toUriList(firstCreatorLink), TEXT_URI_LIST);
|
||||
assertCreatorName(orderLinkToItsCreator, "Frodo");
|
||||
|
||||
putAndGet(orderLinkToItsCreator, toUriList(secondCreatorLink), TEXT_URI_LIST);
|
||||
assertCreatorName(orderLinkToItsCreator, "Pippin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative test scenario, which does try to put two persons at once as the creator of Order. We expect that result
|
||||
* will contain "send only 1 link" substring.
|
||||
*/
|
||||
@Test // DATAREST-1356
|
||||
public void associateTwoCreatorsToOrderWithSinglePut() throws Exception {
|
||||
|
||||
Link firstCreatorLink = preparePersonResource(new Person("Frodo", "Baggins"));
|
||||
Link secondCreatorLink = preparePersonResource(new Person("Pippin", "Baggins"));
|
||||
Link orderLinkToItsCreator = prepareOrderResource(new Order());
|
||||
|
||||
MockHttpServletResponse response = putOnlyExpect5XXStatus(orderLinkToItsCreator,
|
||||
toUriList(firstCreatorLink, secondCreatorLink), TEXT_URI_LIST);
|
||||
assertThat(response.getContentAsString()).contains("send only 1 link");
|
||||
}
|
||||
|
||||
@Test // DATAREST-219
|
||||
public void manipulatePropertyCollectionRestfullyWithDelete() throws Exception {
|
||||
|
||||
@@ -673,6 +708,28 @@ public class JpaWebTests extends CommonWebTests {
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return link to creator of order (associative link for given order instance)
|
||||
*/
|
||||
private Link prepareOrderResource(Order order) throws Exception {
|
||||
Link orderLink = client.discoverUnique(LinkRelation.of("orders"));
|
||||
|
||||
MockHttpServletResponse primaryResponse = postAndGet(orderLink, mapper.writeValueAsString(order),
|
||||
MediaType.APPLICATION_JSON);
|
||||
return client.assertHasLinkWithRel("creator", primaryResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return link to given person (canonical, self, link)
|
||||
*/
|
||||
private Link preparePersonResource(Person person) throws Exception {
|
||||
Link orderLink = client.discoverUnique(LinkRelation.of("people"));
|
||||
|
||||
MockHttpServletResponse primaryResponse = postAndGet(orderLink, mapper.writeValueAsString(person),
|
||||
MediaType.APPLICATION_JSON);
|
||||
return client.assertHasLinkWithRel("self", primaryResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts the {@link Person} resource the given link points to contains siblings with the given names.
|
||||
*
|
||||
@@ -689,6 +746,13 @@ public class JpaWebTests extends CommonWebTests {
|
||||
assertThat(persons).contains(siblingNames);
|
||||
}
|
||||
|
||||
private void assertCreatorName(Link orderLinkToItsCreator, String creatorName) throws Exception {
|
||||
String responseBody = client.request(orderLinkToItsCreator).getContentAsString();
|
||||
String personFirstName = JsonPath.read(responseBody, "$.firstName");
|
||||
|
||||
assertThat(personFirstName).isEqualTo(creatorName);
|
||||
}
|
||||
|
||||
private void assertPersonWithNameAndSiblingLink(String name) throws Exception {
|
||||
|
||||
MockHttpServletResponse response = client.request(client.discoverUnique(LinkRelation.of("people")));
|
||||
|
||||
@@ -77,6 +77,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Greg Turnquist
|
||||
* @author Ľubomír Varga
|
||||
*/
|
||||
@RepositoryRestController
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@@ -318,7 +319,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
"Cannot PATCH a reference to this singular property since the property type is not a List or a Map.");
|
||||
}
|
||||
|
||||
if (source.getLinks().hasSingleLink()) {
|
||||
if (!source.getLinks().hasSingleLink()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must send only 1 link to update a property reference that isn't a List or a Map.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user