From eec52471d7a8f6329ad7db1f43d40af519393126 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 18 Jun 2013 14:03:30 +0200 Subject: [PATCH] DATAREST-93 - More cleanups, more fixes. --- .../mongodb/MongoDbRepositoryConfig.java | 20 ++--- .../mapping/ResourceMappingFactory.java | 4 +- .../domain/jpa/AnnotatedPersonRepository.java | 2 + .../repository/domain/jpa/PersonLoader.java | 3 +- .../ResourceMappingsIntegrationTest.java | 2 +- .../webmvc/AbstractWebIntegrationTests.java | 64 +++++++++++++++- .../data/rest/webmvc/jpa/JpaWebTests.java | 13 ++++ .../PersistentEntitySerializationTests.java | 4 +- .../mongodb/MongoDbRepositoryConfig.java | 18 ++++- .../rest/webmvc/mongodb/MongoWebTests.java | 74 +++++++++++++++++++ .../webmvc/mongodb/ProfileRepository.java | 4 +- 11 files changed, 187 insertions(+), 21 deletions(-) create mode 100644 spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoWebTests.java diff --git a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/MongoDbRepositoryConfig.java b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/MongoDbRepositoryConfig.java index 86a1516ce..c83989f29 100644 --- a/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/MongoDbRepositoryConfig.java +++ b/spring-data-rest-example/src/main/java/org/springframework/data/rest/example/mongodb/MongoDbRepositoryConfig.java @@ -2,7 +2,6 @@ package org.springframework.data.rest.example.mongodb; import java.net.UnknownHostException; -import com.mongodb.Mongo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -11,20 +10,23 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import com.mongodb.Mongo; + /** * @author Jon Brisbin */ @Configuration -@ComponentScan(basePackageClasses = MongoDbRepositoryConfig.class) +@ComponentScan @EnableMongoRepositories public class MongoDbRepositoryConfig { - @Bean public MongoDbFactory mongoDbFactory() throws UnknownHostException { - return new SimpleMongoDbFactory(new Mongo("localhost"), "spring-data-rest-example"); - } - - @Bean public MongoTemplate mongoTemplate() throws UnknownHostException { - return new MongoTemplate(mongoDbFactory()); - } + @Bean + public MongoDbFactory mongoDbFactory() throws UnknownHostException { + return new SimpleMongoDbFactory(new Mongo("localhost"), "spring-data-rest-example"); + } + @Bean + public MongoTemplate mongoTemplate() throws UnknownHostException { + return new MongoTemplate(mongoDbFactory()); + } } diff --git a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappingFactory.java b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappingFactory.java index 0eb26b9eb..e98cb59fa 100644 --- a/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappingFactory.java +++ b/spring-data-rest-repository/src/main/java/org/springframework/data/rest/repository/mapping/ResourceMappingFactory.java @@ -129,7 +129,9 @@ public class ResourceMappingFactory { */ @Override public String getSingleResourceRel() { - return null; + + String rel = getRel(); + return rel == null ? null : String.format("%s.%s", rel, rel); } /* diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java index c8746bdb3..f7000630c 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java +++ b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/AnnotatedPersonRepository.java @@ -1,6 +1,7 @@ package org.springframework.data.rest.repository.domain.jpa; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.rest.repository.annotation.RestResource; /** @@ -9,5 +10,6 @@ import org.springframework.data.rest.repository.annotation.RestResource; * @author Jon Brisbin */ @RestResource(rel = "people", exported = false) +@NoRepositoryBean public interface AnnotatedPersonRepository extends CrudRepository { } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java index d87ffc707..b34b6903b 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java +++ b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/domain/jpa/PersonLoader.java @@ -11,10 +11,9 @@ import org.springframework.stereotype.Component; public class PersonLoader implements InitializingBean { @Autowired - private AnnotatedPersonRepository people; + PersonRepository people; @Override public void afterPropertiesSet() throws Exception { people.save(new Person("John", "Doe")); } - } diff --git a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java index 1c555aa6b..2ac4a4e94 100644 --- a/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java +++ b/spring-data-rest-repository/src/test/java/org/springframework/data/rest/repository/mapping/ResourceMappingsIntegrationTest.java @@ -55,6 +55,6 @@ public class ResourceMappingsIntegrationTest { public void foo() { assertThat(mappings, is(Matchers. iterableWithSize(2))); - assertThat(mappings.getMappingFor(Person.class).isExported(), is(false)); + assertThat(mappings.getMappingFor(Person.class).isExported(), is(true)); } } 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 534a5f3b5..b9c1bc9fa 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 @@ -20,7 +20,10 @@ import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import java.util.List; + import org.junit.Before; +import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration; @@ -33,8 +36,10 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.ResultMatcher; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; /** @@ -42,7 +47,6 @@ import org.springframework.web.context.WebApplicationContext; */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@Transactional @ContextConfiguration(classes = RepositoryRestMvcConfiguration.class) public abstract class AbstractWebIntegrationTests { @@ -70,6 +74,39 @@ public abstract class AbstractWebIntegrationTests { protected MockHttpServletResponse request(String href) throws Exception { return request(href, MediaType.APPLICATION_JSON); } + + protected ResultActions follow(Link link) throws Exception { + return mvc.perform(get(link.getHref())); + } + + protected List discover(String rel) throws Exception { + return discover(new Link("/"), rel); + } + + protected Link discoverUnique(String rel) throws Exception { + + List discover = discover(rel); + assertThat(discover, hasSize(1)); + return discover.get(0); + } + + protected List discover(Link root, String rel) throws Exception { + String s = mvc + .perform(get(root.getHref())) + .andExpect(status().isOk()) + .andExpect(hasLinkWithRel(rel)) + .andReturn().getResponse().getContentAsString(); + return links.findLinksWithRel(rel, s); + } + + protected Link discoverUnique(Link root, String rel) throws Exception { + String s = mvc + .perform(get(root.getHref())) + .andExpect(status().isOk()) + .andExpect(hasLinkWithRel(rel)) + .andReturn().getResponse().getContentAsString(); + return links.findLinkWithRel(rel, s); + } protected Link assertHasLinkWithRel(String rel, MockHttpServletResponse response) throws Exception { @@ -89,4 +126,27 @@ public abstract class AbstractWebIntegrationTests { assertThat("Expected not to find link with rel " + rel + " but found " + link + "!", link, is(nullValue())); } + + protected ResultMatcher hasLinkWithRel(final String rel) { + + return new ResultMatcher() { + @Override + public void match(MvcResult result) throws Exception { + String s = result.getResponse().getContentAsString(); + assertThat(links.findLinkWithRel(rel, s), notNullValue()); + } + }; + } + + @Test + public void exposesRootResource() throws Exception { + + ResultActions actions = mvc.perform(get("/")).andExpect(status().isOk()); + + for (String rel : expectedRootLinkRels()) { + actions.andExpect(hasLinkWithRel(rel)); + } + } + + protected abstract Iterable expectedRootLinkRels(); } 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 10f64de2d..134eb49fa 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 @@ -15,11 +15,14 @@ */ package org.springframework.data.rest.webmvc.jpa; +import java.util.Arrays; + import org.junit.Test; import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests; import org.springframework.hateoas.Link; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.ContextConfiguration; +import org.springframework.transaction.annotation.Transactional; /** * Web integration tests specific to JPA. @@ -27,7 +30,17 @@ import org.springframework.test.context.ContextConfiguration; * @author Oliver Gierke */ @ContextConfiguration(classes = JpaRepositoryConfig.class) +@Transactional public class JpaWebTests extends AbstractWebIntegrationTests { + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#expectedRootLinkRels() + */ + @Override + protected Iterable expectedRootLinkRels() { + return Arrays.asList("people"); + } @Test public void accessPersons() throws Exception { diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java index 98c00715c..1009360ea 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntitySerializationTests.java @@ -68,10 +68,10 @@ public class PersistentEntitySerializationTests { String s = writer.toString(); - Link fatherLink = linkDiscoverer.findLinkWithRel("father", s); + Link fatherLink = linkDiscoverer.findLinkWithRel("people.people.father", s); assertThat(fatherLink.getHref(), endsWith(new UriTemplate("/{id}/father").expand(person.getId()).toString())); - Link siblingLink = linkDiscoverer.findLinkWithRel("siblings", s); + Link siblingLink = linkDiscoverer.findLinkWithRel("people.people.siblings", s); assertThat(siblingLink.getHref(), endsWith(new UriTemplate("/{id}/siblings").expand(person.getId()).toString())); } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java index ccb5b7d4f..76818aa11 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoDbRepositoryConfig.java @@ -1,3 +1,18 @@ +/* + * Copyright 2012-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.mongodb; import java.net.UnknownHostException; @@ -15,7 +30,7 @@ import org.springframework.data.mongodb.repository.config.EnableMongoRepositorie * @author Jon Brisbin */ @Configuration -@ComponentScan(basePackageClasses = MongoDbRepositoryConfig.class) +@ComponentScan @EnableMongoRepositories public class MongoDbRepositoryConfig { @@ -26,5 +41,4 @@ public class MongoDbRepositoryConfig { @Bean public MongoTemplate mongoTemplate() throws UnknownHostException { return new MongoTemplate(mongoDbFactory()); } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoWebTests.java new file mode 100644 index 000000000..dc8952e7a --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/MongoWebTests.java @@ -0,0 +1,74 @@ +/* + * 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.mongodb; + +import static org.hamcrest.Matchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.Arrays; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests; +import org.springframework.hateoas.Link; +import org.springframework.test.context.ContextConfiguration; + +/** + * + * @author Oliver Gierke + */ +@ContextConfiguration(classes = MongoDbRepositoryConfig.class) +public class MongoWebTests extends AbstractWebIntegrationTests { + + @Autowired ProfileRepository repository; + + @Before + public void populateProfiles() { + + Profile twitter = new Profile(); + twitter.setPerson(1L); + twitter.setType("Twitter"); + + Profile linkedIn = new Profile(); + linkedIn.setPerson(1L); + linkedIn.setType("LinkedIn"); + + repository.save(Arrays.asList(twitter, linkedIn)); + } + + @After + public void cleanUp() { + repository.deleteAll(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#expectedRootLinkRels() + */ + @Override + protected Iterable expectedRootLinkRels() { + return Arrays.asList("profile"); + } + + @Test + public void foo() throws Exception { + + Link profileLink = discoverUnique("profile"); + follow(profileLink).andExpect(jsonPath("$.content").value(hasSize(2))); + } +} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/ProfileRepository.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/ProfileRepository.java index c9f09e133..0d1fa7e31 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/ProfileRepository.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/mongodb/ProfileRepository.java @@ -1,9 +1,9 @@ package org.springframework.data.rest.webmvc.mongodb; -import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; /** * @author Jon Brisbin */ -public interface ProfileRepository extends CrudRepository { +public interface ProfileRepository extends PagingAndSortingRepository { }