diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/SampleDataRestApplication.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/SampleDataRestApplication.java new file mode 100644 index 0000000000..8844a3901b --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/SampleDataRestApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 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 sample.data.rest; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleDataRestApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleDataRestApplication.class, args); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/City.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/City.java new file mode 100644 index 0000000000..0de9f3d724 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/City.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.domain; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class City implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String state; + + @Column(nullable = false) + private String country; + + @Column(nullable = false) + private String map; + + protected City() { + } + + public City(String name, String country) { + super(); + this.name = name; + this.country = country; + } + + public String getName() { + return this.name; + } + + public String getState() { + return this.state; + } + + public String getCountry() { + return this.country; + } + + public String getMap() { + return this.map; + } + + @Override + public String toString() { + return getName() + "," + getState() + "," + getCountry(); + } +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/Hotel.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/Hotel.java new file mode 100644 index 0000000000..f3c81a7371 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/domain/Hotel.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.domain; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +import org.hibernate.annotations.NaturalId; + +@Entity +public class Hotel implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + @ManyToOne(optional = false) + @NaturalId + private City city; + + @Column(nullable = false) + @NaturalId + private String name; + + @Column(nullable = false) + private String address; + + @Column(nullable = false) + private String zip; + + protected Hotel() { + } + + public Hotel(City city, String name) { + this.city = city; + this.name = name; + } + + public City getCity() { + return this.city; + } + + public String getName() { + return this.name; + } + + public String getAddress() { + return this.address; + } + + public String getZip() { + return this.zip; + } +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CityRepository.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CityRepository.java new file mode 100644 index 0000000000..ec691c1971 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CityRepository.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.service; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +import sample.data.rest.domain.City; + +@RepositoryRestResource(collectionResourceRel = "citys", path = "cities") +interface CityRepository extends PagingAndSortingRepository { + + Page findByNameContainingAndCountryContainingAllIgnoringCase( + @Param("name") String name, @Param("country") String country, + Pageable pageable); + + City findByNameAndCountryAllIgnoringCase(@Param("name") String name, + @Param("country") String country); + +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CitySearchCriteria.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CitySearchCriteria.java new file mode 100644 index 0000000000..f237100c89 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/CitySearchCriteria.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.service; + +import java.io.Serializable; + +import org.springframework.util.Assert; + +public class CitySearchCriteria implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + + public CitySearchCriteria() { + } + + public CitySearchCriteria(String name) { + Assert.notNull(name, "Name must not be null"); + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/HotelRepository.java b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/HotelRepository.java new file mode 100644 index 0000000000..738c6710c7 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/main/java/sample/data/rest/service/HotelRepository.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.service; + +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +import sample.data.rest.domain.City; +import sample.data.rest.domain.Hotel; + +@RepositoryRestResource(collectionResourceRel = "hotels", path = "hotels") +interface HotelRepository extends PagingAndSortingRepository { + + Hotel findByCityAndName(City city, String name); + +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/SampleDataRestApplicationTests.java b/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/SampleDataRestApplicationTests.java new file mode 100644 index 0000000000..804f59624d --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/SampleDataRestApplicationTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2012-2015 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 sample.data.rest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +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.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import sample.data.rest.SampleDataRestApplication; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Integration test to run the application. + * + * @author Oliver Gierke + * @author Andy Wilkinson + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SampleDataRestApplication.class) +@WebAppConfiguration +@ActiveProfiles("scratch") +// Separate profile for web tests to avoid clashing databases +public class SampleDataRestApplicationTests { + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @Before + public void setUp() { + this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + } + + @Test + public void testHome() throws Exception { + + this.mvc.perform(get("/api")).andExpect(status().isOk()) + .andExpect(content().string(containsString("hotels"))); + } + + @Test + public void findByNameAndCountry() throws Exception { + + this.mvc.perform( + get("/api/cities/search/findByNameAndCountryAllIgnoringCase?name=Melbourne&country=Australia")) + .andExpect(status().isOk()) + .andExpect(jsonPath("state", equalTo("Victoria"))) + .andExpect(jsonPath("name", equalTo("Melbourne"))); + } + + @Test + public void findByContaining() throws Exception { + + this.mvc.perform( + get("/api/cities/search/findByNameContainingAndCountryContainingAllIgnoringCase?name=&country=UK")) + .andExpect(status().isOk()) + .andExpect(jsonPath("_embedded.citys", hasSize(3))); + } +} diff --git a/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/service/CityRepositoryIntegrationTests.java b/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/service/CityRepositoryIntegrationTests.java new file mode 100644 index 0000000000..8272b15b15 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-data-rest/src/test/java/sample/data/rest/service/CityRepositoryIntegrationTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2015 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 sample.data.rest.service; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import sample.data.rest.SampleDataRestApplication; +import sample.data.rest.domain.City; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +/** + * Integration tests for {@link CityRepository}. + * + * @author Oliver Gierke + * @author Andy Wilkinson + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SampleDataRestApplication.class) +public class CityRepositoryIntegrationTests { + + @Autowired + CityRepository repository; + + @Test + public void findsFirstPageOfCities() { + + Page cities = this.repository.findAll(new PageRequest(0, 10)); + assertThat(cities.getTotalElements(), is(greaterThan(20L))); + } + + @Test + public void findByNameAndCountry() { + City city = this.repository.findByNameAndCountryAllIgnoringCase("Melbourne", + "Australia"); + assertThat(city, notNullValue()); + assertThat(city.getName(), is(equalTo("Melbourne"))); + } + + @Test + public void findContaining() { + Page cities = this.repository + .findByNameContainingAndCountryContainingAllIgnoringCase("", "UK", + new PageRequest(0, 10)); + assertThat(cities.getTotalElements(), is(equalTo(3L))); + } +}