From b3a03ea8326b4bca4f0655bcf4f64784d4a7f594 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Sun, 29 Dec 2013 20:03:09 +0100 Subject: [PATCH] DATAREST-198 - Added test case accessing linked resources. Added Author and Book domain types to JPA tests to show that following the referenced properties works. --- ...RepositoryPropertyReferenceController.java | 1 + .../webmvc/AbstractWebIntegrationTests.java | 51 +++++++++++++++++-- .../data/rest/webmvc/jpa/Author.java | 41 +++++++++++++++ .../rest/webmvc/jpa/AuthorRepository.java | 25 +++++++++ .../data/rest/webmvc/jpa/Book.java | 50 ++++++++++++++++++ .../data/rest/webmvc/jpa/BookRepository.java | 25 +++++++++ .../data/rest/webmvc/jpa/JpaWebTests.java | 18 ++++++- .../rest/webmvc/jpa/TestDataPopulator.java | 29 ++++++++++- .../src/test/resources/logback.xml | 2 +- 9 files changed, 236 insertions(+), 6 deletions(-) create mode 100644 spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Author.java create mode 100644 spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/AuthorRepository.java create mode 100644 spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Book.java create mode 100644 spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/BookRepository.java diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java index 70c155e09..88381f3ac 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryPropertyReferenceController.java @@ -179,6 +179,7 @@ public class RepositoryPropertyReferenceController extends AbstractRepositoryRes return null; } }; + try { doWithReferencedProperty(repoRequest, id, property, handler); } catch (IllegalArgumentException iae) { diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java index fbd590f52..cb2018589 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/AbstractWebIntegrationTests.java @@ -24,6 +24,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Map.Entry; + +import net.minidev.json.JSONArray; import org.junit.Before; import org.junit.Test; @@ -45,6 +48,8 @@ import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.context.WebApplicationContext; import com.jayway.jsonpath.JsonPath; @@ -87,7 +92,11 @@ public abstract class AbstractWebIntegrationTests { } protected ResultActions follow(Link link) throws Exception { - return mvc.perform(get(link.getHref())); + return follow(link.getHref()); + } + + protected ResultActions follow(String href) throws Exception { + return mvc.perform(get(href)); } protected List discover(String rel) throws Exception { @@ -270,9 +279,12 @@ public abstract class AbstractWebIntegrationTests { for (String rel : expectedRootLinkRels()) { Link link = assertHasLinkWithRel(rel, response); - Link searchLink = assertHasLinkWithRel("search", request(link)); + String rootResourceRepresentation = request(link).getContentAsString(); + Link searchLink = getDiscoverer(response).findLinkWithRel("search", rootResourceRepresentation); - request(searchLink); + if (searchLink != null) { + request(searchLink); + } } } @@ -301,9 +313,42 @@ public abstract class AbstractWebIntegrationTests { } } + /** + * @see DATAREST-198 + */ + @Test + public void accessLinkedResources() throws Exception { + + MockHttpServletResponse rootResource = request("/"); + + for (Entry> linked : getRootAndLinkedResources().entrySet()) { + + Link resourceLink = assertHasLinkWithRel(linked.getKey(), rootResource); + MockHttpServletResponse resource = request(resourceLink); + + for (String linkedRel : linked.getValue()) { + + // Find URIs pointing to linked resources + String jsonPath = String.format("$..%s._links.%s.href", linked.getKey(), linkedRel); + String representation = resource.getContentAsString(); + JSONArray uris = JsonPath.read(representation, jsonPath); + + for (Object href : uris) { + + follow(href.toString()). // + andExpect(status().isOk()); + } + } + } + } + protected abstract Iterable expectedRootLinkRels(); protected Map getPayloadToPost() throws Exception { return Collections.emptyMap(); } + + protected MultiValueMap getRootAndLinkedResources() { + return new LinkedMultiValueMap(0); + } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Author.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Author.java new file mode 100644 index 000000000..017539610 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Author.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 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 java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToMany; + +@Entity +public class Author { + + @Id @GeneratedValue// + Long id; + String name; + + @ManyToMany(mappedBy = "authors")// + Set books = new HashSet(); + + protected Author() {} + + public Author(String name) { + this.name = name; + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/AuthorRepository.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/AuthorRepository.java new file mode 100644 index 000000000..e30d94de1 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/AuthorRepository.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 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 org.springframework.data.repository.CrudRepository; + +/** + * @author Oliver Gierke + */ +public interface AuthorRepository extends CrudRepository { + +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Book.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Book.java new file mode 100644 index 000000000..ae6885c19 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/Book.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 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 java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToMany; + +@Entity +public class Book { + + @Id String isbn; + + @ManyToMany(cascade = { CascadeType.MERGE })// + Set authors; + + String title; + + protected Book() {} + + public Book(String isbn, String title, Iterable authors) { + + this.isbn = isbn; + this.title = title; + + this.authors = new HashSet(); + + for (Author author : authors) { + author.books.add(this); + this.authors.add(author); + } + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/BookRepository.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/BookRepository.java new file mode 100644 index 000000000..2647cf7b8 --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/BookRepository.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 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 org.springframework.data.repository.CrudRepository; + +/** + * @author Oliver Gierke + */ +public interface BookRepository extends CrudRepository { + +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java index 989742070..0b92bd9c6 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/JpaWebTests.java @@ -38,6 +38,8 @@ 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; /** @@ -71,7 +73,7 @@ public class JpaWebTests extends AbstractWebIntegrationTests { */ @Override protected Iterable expectedRootLinkRels() { - return Arrays.asList("people"); + return Arrays.asList("people", "authors", "books"); } /* @@ -83,6 +85,20 @@ public class JpaWebTests extends AbstractWebIntegrationTests { return Collections.singletonMap("people", readFile("person.json")); } + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#getRootAndLinkedResources() + */ + @Override + protected MultiValueMap getRootAndLinkedResources() { + + MultiValueMap map = new LinkedMultiValueMap(); + map.add("authors", "books"); + map.add("books", "authors"); + + return map; + } + /** * @see DATAREST-99 */ diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/TestDataPopulator.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/TestDataPopulator.java index bea692ccb..c35fa2b23 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/TestDataPopulator.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/jpa/TestDataPopulator.java @@ -13,17 +13,43 @@ public class TestDataPopulator { private final PersonRepository people; private final OrderRepository orders; + private final AuthorRepository authorRepository; + private final BookRepository books; @Autowired - public TestDataPopulator(PersonRepository people, OrderRepository orders) { + public TestDataPopulator(PersonRepository people, OrderRepository orders, AuthorRepository authors, + BookRepository books) { + this.people = people; this.orders = orders; + this.authorRepository = authors; + this.books = books; } public void populateRepositories() { populatePeople(); populateOrders(); + populateAuthorsAndBooks(); + } + + private void populateAuthorsAndBooks() { + + if (authorRepository.count() != 0 || books.count() != 0) { + return; + } + + Author ollie = new Author("Ollie"); + Author mark = new Author("Mark"); + Author michael = new Author("Michael"); + Author david = new Author("David"); + Author john = new Author("John"); + Author thomas = new Author("Thomas"); + + Iterable authors = authorRepository.save(Arrays.asList(ollie, mark, michael, david, john, thomas)); + + books.save(new Book("1449323952", "Spring Data", authors)); + books.save(new Book("1449323953", "Spring Data (SecondEdition)", authors)); } private void populateOrders() { @@ -56,4 +82,5 @@ public class TestDataPopulator { people.save(Arrays.asList(john, jane)); } + } diff --git a/spring-data-rest-webmvc/src/test/resources/logback.xml b/spring-data-rest-webmvc/src/test/resources/logback.xml index a02b71a9a..7a648be10 100644 --- a/spring-data-rest-webmvc/src/test/resources/logback.xml +++ b/spring-data-rest-webmvc/src/test/resources/logback.xml @@ -7,7 +7,7 @@ - +