Package org.springframework.data.rest.webmvc.jpa

Source Code of org.springframework.data.rest.webmvc.jpa.JpaWebTests

/*
* Copyright 2013-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.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.rest.webmvc.jpa;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.rest.webmvc.util.TestUtils.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
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 net.minidev.json.JSONArray;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.core.mapping.ResourceMappings;
import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.RelProvider;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
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.UriComponentsBuilder;
import org.springframework.web.util.UriTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;

/**
* Web integration tests specific to JPA.
*
* @author Oliver Gierke
* @author Greg Turnquist
*/
@Transactional
@ContextConfiguration(classes = JpaRepositoryConfig.class)
public class JpaWebTests extends AbstractWebIntegrationTests {

  private static final MediaType TEXT_URI_LIST = MediaType.valueOf("text/uri-list");
  static final String LINK_TO_SIBLINGS_OF = "$._embedded..[?(@.firstName == '%s')]._links.siblings.href[0]";

  @Autowired TestDataPopulator loader;
  @Autowired ResourceMappings mappings;
  @Autowired RelProvider relProvider;

  ObjectMapper mapper = new ObjectMapper();

  /*
   * (non-Javadoc)
   * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#setUp()
   */
  @Override
  @Before
  public void setUp() {
    loader.populateRepositories();
    super.setUp();
  }

  /*
   * (non-Javadoc)
   * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#expectedRootLinkRels()
   */
  @Override
  protected Iterable<String> expectedRootLinkRels() {
    return Arrays.asList("people", "authors", "books");
  }

  /*
   * (non-Javadoc)
   * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#getPayloadToPost()
   */
  @Override
  protected Map<String, String> getPayloadToPost() throws Exception {
    return Collections.singletonMap("people", readFileFromClasspath("person.json"));
  }

  /*
   * (non-Javadoc)
   * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#getRootAndLinkedResources()
   */
  @Override
  protected MultiValueMap<String, String> getRootAndLinkedResources() {

    MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
    map.add("authors", "books");
    map.add("books", "authors");

    return map;
  }

  /**
   * @see DATAREST-99
   */
  @Test
  public void doesNotExposeCreditCardRepository() throws Exception {

    mvc.perform(get("/")). //
        andExpect(status().isOk()). //
        andExpect(doesNotHaveLinkWithRel(mappings.getMappingFor(CreditCard.class).getRel()));
  }

  @Test
  public void accessPersons() throws Exception {

    MockHttpServletResponse response = request("/people?page=0&size=1");

    Link nextLink = assertHasLinkWithRel(Link.REL_NEXT, response);
    assertDoesNotHaveLinkWithRel(Link.REL_PREVIOUS, response);

    response = request(nextLink);
    assertHasLinkWithRel(Link.REL_PREVIOUS, response);
    nextLink = assertHasLinkWithRel(Link.REL_NEXT, response);

    response = request(nextLink);
    assertHasLinkWithRel(Link.REL_PREVIOUS, response);
    assertDoesNotHaveLinkWithRel(Link.REL_NEXT, response);
  }

  /**
   * @see DATAREST-169
   */
  @Test
  public void exposesLinkForRelatedResource() throws Exception {

    MockHttpServletResponse response = request("/");
    Link ordersLink = assertHasLinkWithRel("orders", response);

    MockHttpServletResponse orders = request(ordersLink);
    Link creatorLink = assertHasContentLinkWithRel("creator", orders);

    assertThat(request(creatorLink), is(notNullValue()));
  }

  /**
   * @see DATAREST-200
   */
  @Test
  public void exposesInlinedEntities() throws Exception {

    MockHttpServletResponse response = request("/");
    Link ordersLink = assertHasLinkWithRel("orders", response);

    MockHttpServletResponse orders = request(ordersLink);
    assertHasJsonPathValue("$..lineItems", orders);
  }

  /**
   * @see DATAREST-199
   */
  @Test
  public void createsOrderUsingPut() throws Exception {

    mvc.perform(//
        put("/orders/{id}", 4711).//
            content(readFileFromClasspath("order.json")).contentType(MediaType.APPLICATION_JSON)//
    ).andExpect(status().isCreated());
  }

  /**
   * @see DATAREST-117
   */
  @Test
  public void createPersonThenVerifyIgnoredAttributesDontExist() throws Exception {

    Link peopleLink = discoverUnique("people");
    ObjectMapper mapper = new ObjectMapper();
    Person frodo = new Person("Frodo", "Baggins");
    frodo.setAge(77);
    frodo.setHeight(42);
    frodo.setWeight(75);
    String frodoString = mapper.writeValueAsString(frodo);

    MockHttpServletResponse response = postAndGet(peopleLink, frodoString, MediaType.APPLICATION_JSON);

    assertJsonPathEquals("$.firstName", "Frodo", response);
    assertJsonPathEquals("$.lastName", "Baggins", response);
    assertJsonPathDoesntExist("$.age", response);
    assertJsonPathDoesntExist("$.height", response);
    assertJsonPathDoesntExist("$.weight", response);
  }

  /**
   * @see DATAREST-95
   */
  @Test
  public void createThenPatch() throws Exception {

    Link peopleLink = discoverUnique("people");

    MockHttpServletResponse bilbo = postAndGet(peopleLink, "{ \"firstName\" : \"Bilbo\", \"lastName\" : \"Baggins\" }",
        MediaType.APPLICATION_JSON);

    Link bilboLink = assertHasLinkWithRel("self", bilbo);

    assertThat((String) JsonPath.read(bilbo.getContentAsString(), "$.firstName"), is("Bilbo"));
    assertThat((String) JsonPath.read(bilbo.getContentAsString(), "$.lastName"), is("Baggins"));

    MockHttpServletResponse frodo = patchAndGet(bilboLink, "{ \"firstName\" : \"Frodo\" }", MediaType.APPLICATION_JSON);

    assertThat((String) JsonPath.read(frodo.getContentAsString(), "$.firstName"), is("Frodo"));
    assertThat((String) JsonPath.read(frodo.getContentAsString(), "$.lastName"), is("Baggins"));

    frodo = patchAndGet(bilboLink, "{ \"firstName\" : null }", MediaType.APPLICATION_JSON);

    assertThat((String) JsonPath.read(frodo.getContentAsString(), "$.firstName"), is(nullValue()));
    assertThat((String) JsonPath.read(frodo.getContentAsString(), "$.lastName"), is("Baggins"));
  }

  /**
   * @see DATAREST-150
   */
  @Test
  public void createThenPut() throws Exception {

    Link peopleLink = discoverUnique("people");

    MockHttpServletResponse bilbo = postAndGet(peopleLink,//
        "{ \"firstName\" : \"Bilbo\", \"lastName\" : \"Baggins\" }",//
        MediaType.APPLICATION_JSON);

    Link bilboLink = assertHasLinkWithRel("self", bilbo);

    assertThat((String) JsonPath.read(bilbo.getContentAsString(), "$.firstName"), equalTo("Bilbo"));
    assertThat((String) JsonPath.read(bilbo.getContentAsString(), "$.lastName"), equalTo("Baggins"));

    MockHttpServletResponse frodo = putAndGet(bilboLink,//
        "{ \"firstName\" : \"Frodo\" }",//
        MediaType.APPLICATION_JSON);

    assertThat((String) JsonPath.read(frodo.getContentAsString(), "$.firstName"), equalTo("Frodo"));
    assertNull(JsonPath.read(frodo.getContentAsString(), "$.lastName"));
  }

  @Test
  public void listsSiblingsWithContentCorrectly() throws Exception {
    assertPersonWithNameAndSiblingLink("John");
  }

  @Test
  public void listsEmptySiblingsCorrectly() throws Exception {
    assertPersonWithNameAndSiblingLink("Billy Bob");
  }

  /**
   * @see DATAREST-219
   */
  @Test
  public void manipulatePropertyCollectionRestfullyWithMultiplePosts() throws Exception {

    List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
        new Person("Bilbo", "Baggins"), //
        new Person("Merry", "Baggins"), //
        new Person("Pippin", "Baggins"));

    Link frodosSiblingLink = links.get(0);

    patchAndGet(frodosSiblingLink, links.get(1).getHref(), TEXT_URI_LIST);
    patchAndGet(frodosSiblingLink, links.get(2).getHref(), TEXT_URI_LIST);
    patchAndGet(frodosSiblingLink, links.get(3).getHref(), TEXT_URI_LIST);

    assertSiblingNames(frodosSiblingLink, "Bilbo", "Merry", "Pippin");
  }

  /**
   * @see DATAREST-219
   */
  @Test
  public void manipulatePropertyCollectionRestfullyWithSinglePost() throws Exception {

    List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
        new Person("Bilbo", "Baggins"), //
        new Person("Merry", "Baggins"), //
        new Person("Pippin", "Baggins"));

    Link frodosSiblingLink = links.get(0);

    patchAndGet(frodosSiblingLink, toUriList(links.get(1), links.get(2), links.get(3)), TEXT_URI_LIST);

    assertSiblingNames(frodosSiblingLink, "Bilbo", "Merry", "Pippin");
  }

  /**
   * @see DATAREST-219
   */
  @Test
  public void manipulatePropertyCollectionRestfullyWithMultiplePuts() throws Exception {

    List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
        new Person("Bilbo", "Baggins"), //
        new Person("Merry", "Baggins"), //
        new Person("Pippin", "Baggins"));

    Link frodosSiblingsLink = links.get(0);

    putAndGet(frodosSiblingsLink, links.get(1).expand().getHref(), TEXT_URI_LIST);
    putAndGet(frodosSiblingsLink, links.get(2).expand().getHref(), TEXT_URI_LIST);
    putAndGet(frodosSiblingsLink, links.get(3).expand().getHref(), TEXT_URI_LIST);
    assertSiblingNames(frodosSiblingsLink, "Pippin");

    patchAndGet(frodosSiblingsLink, links.get(2).getHref(), TEXT_URI_LIST);
    assertSiblingNames(frodosSiblingsLink, "Merry", "Pippin");
  }

  /**
   * @see DATAREST-219
   */
  @Test
  public void manipulatePropertyCollectionRestfullyWithSinglePut() throws Exception {

    List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
        new Person("Bilbo", "Baggins"), //
        new Person("Merry", "Baggins"), //
        new Person("Pippin", "Baggins"));

    Link frodoSiblingLink = links.get(0);

    putAndGet(frodoSiblingLink, toUriList(links.get(1), links.get(2), links.get(3)), TEXT_URI_LIST);
    assertSiblingNames(frodoSiblingLink, "Bilbo", "Merry", "Pippin");

    putAndGet(frodoSiblingLink, toUriList(links.get(3)), TEXT_URI_LIST);
    assertSiblingNames(frodoSiblingLink, "Pippin");

    patchAndGet(frodoSiblingLink, toUriList(links.get(2)), TEXT_URI_LIST);
    assertSiblingNames(frodoSiblingLink, "Merry", "Pippin");
  }

  /**
   * @see DATAREST-219
   */
  @Test
  public void manipulatePropertyCollectionRestfullyWithDelete() throws Exception {

    List<Link> links = preparePersonResources(new Person("Frodo", "Baggins"), //
        new Person("Bilbo", "Baggins"), //
        new Person("Merry", "Baggins"), //
        new Person("Pippin", "Baggins"));

    Link frodosSiblingsLink = links.get(0);

    patchAndGet(frodosSiblingsLink, links.get(1).getHref(), TEXT_URI_LIST);
    patchAndGet(frodosSiblingsLink, links.get(2).getHref(), TEXT_URI_LIST);
    patchAndGet(frodosSiblingsLink, links.get(3).getHref(), TEXT_URI_LIST);

    String pippinId = new UriTemplate("/people/{id}").match(links.get(3).getHref()).get("id");
    deleteAndVerify(new Link(frodosSiblingsLink.getHref() + "/" + pippinId));

    assertSiblingNames(frodosSiblingsLink, "Bilbo", "Merry");
  }

  /**
   * @see DATAREST-50
   */
  @Test
  public void propertiesCanHaveNulls() throws Exception {

    Link peopleLink = discoverUnique("people");

    Person frodo = new Person();
    frodo.setFirstName("Frodo");
    frodo.setLastName(null);

    MockHttpServletResponse response = postAndGet(peopleLink, mapper.writeValueAsString(frodo),
        MediaType.APPLICATION_JSON);
    String responseBody = response.getContentAsString();

    assertEquals(JsonPath.read(responseBody, "$.firstName"), "Frodo");
    assertNull(JsonPath.read(responseBody, "$.lastName"));
  }

  /**
   * @see DATAREST-238
   */
  @Test
  public void putShouldWorkDespiteExistingLinks() throws Exception {

    Link peopleLink = discoverUnique("people");

    Person frodo = new Person("Frodo", "Baggins");
    String frodoString = mapper.writeValueAsString(frodo);

    MockHttpServletResponse createdPerson = postAndGet(peopleLink, frodoString, MediaType.APPLICATION_JSON);

    Link frodoLink = assertHasLinkWithRel("self", createdPerson);
    assertJsonPathEquals("$.firstName", "Frodo", createdPerson);

    String bilboWithFrodosLinks = createdPerson.getContentAsString().replace("Frodo", "Bilbo");

    MockHttpServletResponse overwrittenResponse = putAndGet(frodoLink, bilboWithFrodosLinks, MediaType.APPLICATION_JSON);

    assertHasLinkWithRel("self", overwrittenResponse);
    assertJsonPathEquals("$.firstName", "Bilbo", overwrittenResponse);
  }

  private List<Link> preparePersonResources(Person primary, Person... persons) throws Exception {

    Link peopleLink = discoverUnique("people");
    List<Link> links = new ArrayList<Link>();

    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;
  }

  /**
   * @see DATAREST-217
   */
  @Test
  public void doesNotAllowGetToCollectionResourceIfFindAllIsNotExported() throws Exception {

    Link link = discoverUnique("addresses");

    mvc.perform(get(link.getHref())).//
        andExpect(status().isMethodNotAllowed());
  }

  /**
   * @see DATAREST-217
   */
  @Test
  public void doesNotAllowPostToCollectionResourceIfSaveIsNotExported() throws Exception {

    Link link = discoverUnique("addresses");

    mvc.perform(post(link.getHref()).content("{}").contentType(MediaType.APPLICATION_JSON)).//
        andExpect(status().isMethodNotAllowed());
  }

  /**
   * Checks, that the server only returns the properties contained in the projection requested.
   *
   * @see OrderSummary
   * @see DATAREST-221
   */
  @Test
  public void returnsProjectionIfRequested() throws Exception {

    Link orders = discoverUnique("orders");

    MockHttpServletResponse response = request(orders);
    Link orderLink = assertContentLinkWithRel("self", response, true).expand();

    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(orderLink.getHref());
    String uri = builder.queryParam("projection", "summary").build().toUriString();

    response = mvc.perform(get(uri)). //
        andExpect(status().isOk()). //
        andExpect(jsonPath("$.price", is(2.5))).//
        andReturn().getResponse();

    assertJsonPathDoesntExist("$.lineItems", response);
  }

  /**
   * @see DATAREST-261
   */
  @Test
  public void relProviderDetectsCustomizedMapping() {
    assertThat(relProvider.getCollectionResourceRelFor(Person.class), is("people"));
  }

  /**
   * @see DATAREST-311
   */
  @Test
  public void onlyLinksShouldAppearWhenExecuteSearchCompact() throws Exception {

    Link peopleLink = discoverUnique("people");
    Person daenerys = new Person("Daenerys", "Targaryen");
    String daenerysString = mapper.writeValueAsString(daenerys);

    MockHttpServletResponse createdPerson = postAndGet(peopleLink, daenerysString, MediaType.APPLICATION_JSON);
    Link daenerysLink = assertHasLinkWithRel("self", createdPerson);
    assertJsonPathEquals("$.firstName", "Daenerys", createdPerson);

    Link searchLink = discoverUnique(peopleLink, "search");
    Link byFirstNameLink = discoverUnique(searchLink, "findFirstPersonByFirstName");

    MockHttpServletResponse response = request(byFirstNameLink.expand("Daenerys"),
        MediaType.parseMediaType("application/x-spring-data-compact+json"));

    String responseBody = response.getContentAsString();

    JSONArray personLinks = JsonPath.<JSONArray> read(responseBody, "$.links[?(@.rel=='person')].href");

    assertThat(personLinks, hasSize(1));
    assertThat(personLinks.get(0), is((Object) daenerysLink.getHref()));
    assertThat(JsonPath.<JSONArray> read(responseBody, "$.content"), hasSize(0));
  }

  /**
   * @see DATAREST-317
   */
  @Test
  public void rendersExcerptProjectionsCorrectly() throws Exception {

    Link authorsLink = discoverUnique("authors");

    MockHttpServletResponse response = request(authorsLink);
    String firstAuthorPath = "$._embedded.authors[0]";

    // Has main content
    assertHasJsonPathValue(firstAuthorPath.concat(".name"), response);

    // Embeddes content of related entity but no link to it
    assertHasJsonPathValue(firstAuthorPath.concat("._embedded.books[0].title"), response);
    assertJsonPathDoesntExist(firstAuthorPath.concat("._links.books"), response);

    // Access item resource and expect link to related resource present
    String content = response.getContentAsString();
    String href = JsonPath.read(content, firstAuthorPath.concat("._links.self.href"));

    follow(new Link(href)).andExpect(hasLinkWithRel("books"));
  }

  /**
   * @see DATAREST-353
   */
  @Test
  public void returns404WhenTryingToDeleteANonExistingResource() throws Exception {

    Link authorsLink = discoverUnique("authors");

    mvc.perform(delete(authorsLink.getHref().concat("/{id}"), 4711)).//
        andExpect(status().isNotFound());
  }

  /**
   * @see DATAREST-384
   */
  @Test
  public void execturesSearchThatTakesASort() throws Exception {

    Link booksLink = discoverUnique("books");
    Link searchLink = discoverUnique(booksLink, "search");
    Link findBySortedLink = discoverUnique(searchLink, "find-by-sorted");

    // Assert sort options advertised
    assertThat(findBySortedLink.isTemplated(), is(true));
    assertThat(findBySortedLink.getVariableNames(), contains("sort"));

    // Assert results returned as specified
    follow(findBySortedLink.expand("title,desc")).//
        andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data (Second Edition)")).//
        andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data"));

    follow(findBySortedLink.expand("title,asc")).//
        andExpect(jsonPath("$._embedded.books[0].title").value("Spring Data")).//
        andExpect(jsonPath("$._embedded.books[1].title").value("Spring Data (Second Edition)"));
  }

  /**
   * 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.people[*].firstName");

    assertThat(persons, hasSize(siblingNames.length));
    assertThat(persons, hasItems(siblingNames));
  }

  private void assertPersonWithNameAndSiblingLink(String name) throws Exception {

    MockHttpServletResponse response = request(discoverUnique("people"));

    String jsonPath = String.format("$._embedded.people[?(@.firstName == '%s')][0]", name);

    // Assert content inlined
    Object john = JsonPath.read(response.getContentAsString(), jsonPath);
    assertThat(john, is(notNullValue()));
    assertThat(JsonPath.read(john, "$.firstName"), is(notNullValue()));

    // Assert sibling link exposed in resource pointed to
    Link selfLink = new Link(JsonPath.<String> read(john, "$._links.self.href"));
    follow(selfLink).//
        andExpect(status().isOk()).//
        andExpect(jsonPath("$._links.siblings", is(notNullValue())));
  }

  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");
  }
}
TOP

Related Classes of org.springframework.data.rest.webmvc.jpa.JpaWebTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.