From 581a897577450ab7a3bc3c45ffe421bbe0e4f3b2 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sun, 9 May 2021 23:49:27 +0200 Subject: [PATCH 1/7] BAEL-3682 remove empty test --- .../java/com/baeldung/SpringContextTest.java | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 spring-boot-rest/src/test/java/com/baeldung/SpringContextTest.java diff --git a/spring-boot-rest/src/test/java/com/baeldung/SpringContextTest.java b/spring-boot-rest/src/test/java/com/baeldung/SpringContextTest.java deleted file mode 100644 index 9cba7f8fc1..0000000000 --- a/spring-boot-rest/src/test/java/com/baeldung/SpringContextTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = {SpringBootRestApplication.class}) -public class SpringContextTest { - - @Test - public void contextLoads() { - } - -} From 525abe9831eff4fdc3cdd12fff2375ca17c29965 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sun, 9 May 2021 23:49:51 +0200 Subject: [PATCH 2/7] BAEL-3682 reuse url --- .../test/java/com/baeldung/web/FooPageableLiveTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java index 6a365f3bd5..dc60c0e422 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java @@ -43,12 +43,12 @@ public class FooPageableLiveTest extends AbstractBasicLiveTest { public final String createAsUri() { return createAsUri(new Foo(randomAlphabetic(6))); } - + @Override @Test public void whenResourcesAreRetrievedPaged_then200IsReceived() { this.create(); - + final Response response = RestAssured.get(getPageableURL() + "?page=0&size=10"); assertThat(response.getStatusCode(), is(200)); @@ -74,7 +74,7 @@ public class FooPageableLiveTest extends AbstractBasicLiveTest { } protected String getPageableURL() { - return "http://localhost:" + APPLICATION_PORT + "/spring-boot-rest/foos/pageable"; + return getURL() + "/pageable"; } - + } From 099b9d514fc0bf09ffd04b5c9bfdc1341d6d5274 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sun, 9 May 2021 23:51:40 +0200 Subject: [PATCH 3/7] BAEL-3682 isolate test by cleaning the foo records to fix bulk test run --- .../web/FooControllerAppIntegrationTest.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java index 3300b91fde..5e8a190fb0 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java @@ -1,5 +1,11 @@ package com.baeldung.web; +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.status; + +import com.baeldung.persistence.dao.IFooDao; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -8,12 +14,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; - /** - * + * * We'll start the whole context, but not the server. We'll mock the REST calls instead. * */ @@ -25,6 +27,14 @@ public class FooControllerAppIntegrationTest { @Autowired private MockMvc mockMvc; + @Autowired + private IFooDao fooDao; + + @Before + public void setup(){ + this.fooDao.deleteAll(); + } + @Test public void whenFindPaginatedRequest_thenEmptyResponse() throws Exception { this.mockMvc.perform(get("/foos").param("page", "0") From e5c3f48f866cf792cadf4c5a4cce3cb909707e63 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Mon, 10 May 2021 02:01:25 +0200 Subject: [PATCH 4/7] BAEL-3682 specify accept header to fix ambiguity of message converters in case XML converter added --- .../java/com/baeldung/spring/WebConfig.java | 54 ++++++++----------- .../common/web/AbstractBasicLiveTest.java | 12 +++-- .../web/FooControllerAppIntegrationTest.java | 17 +++--- ...ooControllerCustomEtagIntegrationTest.java | 5 +- .../FooControllerWebLayerIntegrationTest.java | 19 ++++--- .../com/baeldung/web/FooPageableLiveTest.java | 5 +- 6 files changed, 56 insertions(+), 56 deletions(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java b/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java index 13a9933fa6..4fce72a75f 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java +++ b/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java @@ -5,7 +5,6 @@ import java.util.List; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; @@ -16,35 +15,25 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { - // @Override - // public void configureMessageConverters(final List> messageConverters) { - // messageConverters.add(new MappingJackson2HttpMessageConverter()); - // messageConverters.add(createXmlHttpMessageConverter()); - // } - // - // private HttpMessageConverter createXmlHttpMessageConverter() { - // final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); - // - // final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); - // xstreamMarshaller.setAutodetectAnnotations(true); - // xmlConverter.setMarshaller(xstreamMarshaller); - // xmlConverter.setUnmarshaller(xstreamMarshaller); - // - // return xmlConverter; - // } + @Override + public void configureMessageConverters(final List> messageConverters) { + messageConverters.add(new MappingJackson2HttpMessageConverter()); + messageConverters.add(createXmlHttpMessageConverter()); + } - // Another possibility is to create a bean which will be automatically added to the Spring Boot Autoconfigurations - // @Bean - // public HttpMessageConverter createXmlHttpMessageConverter() { - // final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); - // - // final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); - // xstreamMarshaller.setAutodetectAnnotations(true); - // xmlConverter.setMarshaller(xstreamMarshaller); - // xmlConverter.setUnmarshaller(xstreamMarshaller); - // - // return xmlConverter; - // } + /** + * There is another possibility to add a message converter, see {@link ConverterExtensionsConfig} + */ + private HttpMessageConverter createXmlHttpMessageConverter() { + final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); + + final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); + xstreamMarshaller.setAutodetectAnnotations(true); + xmlConverter.setMarshaller(xstreamMarshaller); + xmlConverter.setUnmarshaller(xstreamMarshaller); + + return xmlConverter; + } // Etags @@ -52,16 +41,17 @@ public class WebConfig implements WebMvcConfigurer { // AbstractAnnotationConfigDispatcherServletInitializer#getServletFilters @Bean public FilterRegistrationBean shallowEtagHeaderFilter() { - FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>( new ShallowEtagHeaderFilter()); + FilterRegistrationBean filterRegistrationBean = + new FilterRegistrationBean<>(new ShallowEtagHeaderFilter()); filterRegistrationBean.addUrlPatterns("/foos/*"); filterRegistrationBean.setName("etagFilter"); return filterRegistrationBean; } - + // We can also just declare the filter directly // @Bean // public ShallowEtagHeaderFilter shallowEtagHeaderFilter() { // return new ShallowEtagHeaderFilter(); // } -} \ No newline at end of file +} diff --git a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java index ecf938be50..6e50f828de 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/common/web/AbstractBasicLiveTest.java @@ -24,6 +24,7 @@ import com.google.common.net.HttpHeaders; import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.Response; +import org.springframework.http.MediaType; public abstract class AbstractBasicLiveTest extends AbstractLiveTest { @@ -36,7 +37,7 @@ public abstract class AbstractBasicLiveTest extends Abst @Test public void whenResourcesAreRetrievedPaged_then200IsReceived() { create(); - + final Response response = RestAssured.get(getURL() + "?page=0&size=10"); assertThat(response.getStatusCode(), is(200)); @@ -54,7 +55,8 @@ public abstract class AbstractBasicLiveTest extends Abst public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() { create(); - final Response response = RestAssured.get(getURL() + "?page=0&size=10"); + final Response response = RestAssured.given() + .accept(MediaType.APPLICATION_JSON_VALUE).get(getURL() + "?page=0&size=10"); assertFalse(response.body().as(List.class).isEmpty()); } @@ -64,7 +66,7 @@ public abstract class AbstractBasicLiveTest extends Abst create(); create(); create(); - + final Response response = RestAssured.get(getURL() + "?page=0&size=2"); final String uriToNextPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "next"); @@ -95,7 +97,7 @@ public abstract class AbstractBasicLiveTest extends Abst create(); create(); create(); - + final Response first = RestAssured.get(getURL() + "?page=0&size=2"); final String uriToLastPage = extractURIByRel(first.getHeader(HttpHeaders.LINK), "last"); @@ -104,7 +106,7 @@ public abstract class AbstractBasicLiveTest extends Abst final String uriToNextPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "next"); assertNull(uriToNextPage); } - + // etags @Test diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java index 5e8a190fb0..b1a84b47a7 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerAppIntegrationTest.java @@ -11,13 +11,12 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; /** - * - * We'll start the whole context, but not the server. We'll mock the REST calls instead. - * + * We'll start the whole context, but not the server. We'll mock the REST calls instead. */ @RunWith(SpringRunner.class) @SpringBootTest @@ -31,16 +30,18 @@ public class FooControllerAppIntegrationTest { private IFooDao fooDao; @Before - public void setup(){ + public void setup() { this.fooDao.deleteAll(); } @Test public void whenFindPaginatedRequest_thenEmptyResponse() throws Exception { - this.mockMvc.perform(get("/foos").param("page", "0") - .param("size", "2")) - .andExpect(status().isOk()) - .andExpect(content().json("[]")); + this.mockMvc.perform(get("/foos") + .param("page", "0") + .param("size", "2") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json("[]")); } } diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java index 9e7b60ed8c..e472d308e8 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerCustomEtagIntegrationTest.java @@ -40,7 +40,7 @@ public class FooControllerCustomEtagIntegrationTest { private static String createFooJson() throws Exception { return serializeFoo(new Foo(randomAlphabetic(6))); } - + private static Foo deserializeFoo(String fooJson) throws Exception { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(fooJson, Foo.class); @@ -97,7 +97,8 @@ public class FooControllerCustomEtagIntegrationTest { .getResponse() .getHeader(HttpHeaders.LOCATION); ResultActions findOneResponse = this.mvc - .perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON)); + .perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)); String etag = findOneResponse.andReturn().getResponse().getHeader(HttpHeaders.ETAG); Foo createdFoo = deserializeFoo(findOneResponse.andReturn().getResponse().getContentAsString()); createdFoo.setName("updated name"); diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerWebLayerIntegrationTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerWebLayerIntegrationTest.java index 4d4a274b1a..070625b7d4 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerWebLayerIntegrationTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooControllerWebLayerIntegrationTest.java @@ -20,6 +20,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; +import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; @@ -30,7 +31,7 @@ import com.baeldung.web.exception.CustomException1; import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent; /** - * + * * We'll start only the web layer. * */ @@ -54,20 +55,22 @@ public class FooControllerWebLayerIntegrationTest { doNothing().when(publisher) .publishEvent(any(PaginatedResultsRetrievedEvent.class)); - this.mockMvc.perform(get("/foos").param("page", "0") - .param("size", "2")) - .andExpect(status().isOk()) - .andExpect(jsonPath("$",Matchers.hasSize(1))); + this.mockMvc.perform(get("/foos") + .param("page", "0") + .param("size", "2") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", Matchers.hasSize(1))); } - + @Test public void delete_forException_fromService() throws Exception { Mockito.when(service.findAll()).thenThrow(new CustomException1()); this.mockMvc.perform(get("/foos")).andDo(h -> { final Exception expectedException = h.getResolvedException(); Assert.assertTrue(expectedException instanceof CustomException1); - + }); } - + } diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java index dc60c0e422..242fbb609e 100644 --- a/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooPageableLiveTest.java @@ -11,6 +11,7 @@ import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -68,7 +69,9 @@ public class FooPageableLiveTest extends AbstractBasicLiveTest { public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() { create(); - final Response response = RestAssured.get(getPageableURL() + "?page=0&size=10"); + final Response response = RestAssured.given() + .accept(MediaType.APPLICATION_JSON_VALUE) + .get(getPageableURL() + "?page=0&size=10"); assertFalse(response.body().as(List.class).isEmpty()); } From af009149dc7e624b2809069ba56dc967bd871820 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Mon, 10 May 2021 02:03:01 +0200 Subject: [PATCH 5/7] BAEL-3682 add sample of http message converter beans autoconfiguration --- .../spring/ConverterExtensionsConfig.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java diff --git a/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java b/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java new file mode 100644 index 0000000000..df673b3f03 --- /dev/null +++ b/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java @@ -0,0 +1,30 @@ +package com.baeldung.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; +import org.springframework.oxm.xstream.XStreamMarshaller; + +/** + * Another possibility is to create a bean which will be automatically added to the Spring Boot Autoconfigurations. + * + * ATTENTION: Multiple converter registration of the same type most likely causes problem (serialize twice, etc.) + * Therefore, be sure to remove manually added XML message converter first then uncomment + * this @{@link org.springframework.context.annotation.Configuration} to use + */ +//@Configuration +public class ConverterExtensionsConfig { + + @Bean + public HttpMessageConverter createXmlHttpMessageConverter() { + final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); + + final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); + xstreamMarshaller.setAutodetectAnnotations(true); + xmlConverter.setMarshaller(xstreamMarshaller); + xmlConverter.setUnmarshaller(xstreamMarshaller); + + return xmlConverter; + } + +} From 039416f0eb392976093a2b74a7f0c7fb7c14062c Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sun, 20 Jun 2021 04:42:31 +0200 Subject: [PATCH 6/7] BAEL-3682 remove setAutodetectAnnotations in favor of aligning with the article's code samples --- .../main/java/com/baeldung/spring/ConverterExtensionsConfig.java | 1 - .../src/main/java/com/baeldung/spring/WebConfig.java | 1 - 2 files changed, 2 deletions(-) diff --git a/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java b/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java index df673b3f03..42bf50ac5f 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java +++ b/spring-boot-rest/src/main/java/com/baeldung/spring/ConverterExtensionsConfig.java @@ -20,7 +20,6 @@ public class ConverterExtensionsConfig { final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); - xstreamMarshaller.setAutodetectAnnotations(true); xmlConverter.setMarshaller(xstreamMarshaller); xmlConverter.setUnmarshaller(xstreamMarshaller); diff --git a/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java b/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java index 4fce72a75f..69724fda29 100644 --- a/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java +++ b/spring-boot-rest/src/main/java/com/baeldung/spring/WebConfig.java @@ -28,7 +28,6 @@ public class WebConfig implements WebMvcConfigurer { final MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter(); final XStreamMarshaller xstreamMarshaller = new XStreamMarshaller(); - xstreamMarshaller.setAutodetectAnnotations(true); xmlConverter.setMarshaller(xstreamMarshaller); xmlConverter.setUnmarshaller(xstreamMarshaller); From 5b59b7f6524b431bd693b6e82a8741cdbee4b1b1 Mon Sep 17 00:00:00 2001 From: Yavuz Tas Date: Sun, 20 Jun 2021 04:46:14 +0200 Subject: [PATCH 7/7] BAEL-3682 integrate missing http message converters test from spring-web-modules/spring-rest-simple module --- .../web/FooMessageConvertersLiveTest.java | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java diff --git a/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java b/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java new file mode 100644 index 0000000000..9b1a9e9733 --- /dev/null +++ b/spring-boot-rest/src/test/java/com/baeldung/web/FooMessageConvertersLiveTest.java @@ -0,0 +1,149 @@ +package com.baeldung.web; + +import static com.baeldung.Consts.APPLICATION_PORT; +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import com.baeldung.common.web.AbstractLiveTest; +import com.baeldung.persistence.model.Foo; +import com.baeldung.spring.ConfigIntegrationTest; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; +import org.springframework.oxm.xstream.XStreamMarshaller; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.web.client.RestTemplate; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { ConfigIntegrationTest.class }, loader = AnnotationConfigContextLoader.class) +@ActiveProfiles("test") +public class FooMessageConvertersLiveTest extends AbstractLiveTest { + + private static final String BASE_URI = "http://localhost:" + APPLICATION_PORT + "/spring-boot-rest/"; + + public FooMessageConvertersLiveTest() { + super(Foo.class); + } + + @Override + public final void create() { + create(new Foo(randomAlphabetic(6))); + } + + @Override + public final String createAsUri() { + return createAsUri(new Foo(randomAlphabetic(6))); + } + + @Before + public void setup(){ + create(); + } + + /** + * Without specifying Accept Header, uses the default response from the + * server (in this case json) + */ + @Test + public void whenRetrievingAFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + final Foo resource = restTemplate.getForObject(URI, Foo.class, "1"); + + assertThat(resource, notNullValue()); + } + + @Test + public void givenConsumingXml_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(getXmlMessageConverters()); + + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_XML)); + final HttpEntity entity = new HttpEntity<>(headers); + + final ResponseEntity + response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + private List> getXmlMessageConverters() { + final XStreamMarshaller marshaller = new XStreamMarshaller(); + marshaller.setAnnotatedClasses(Foo.class); + final MarshallingHttpMessageConverter marshallingConverter = new MarshallingHttpMessageConverter(marshaller); + + final List> converters = new ArrayList<>(); + converters.add(marshallingConverter); + return converters; + } + + @Test + public void givenConsumingJson_whenReadingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos/{id}"; + + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(getJsonMessageConverters()); + + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + final HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.GET, entity, Foo.class, "1"); + final Foo resource = response.getBody(); + + assertThat(resource, notNullValue()); + } + + private List> getJsonMessageConverters() { + final List> converters = new ArrayList<>(); + converters.add(new MappingJackson2HttpMessageConverter()); + return converters; + } + + @Test + public void givenConsumingXml_whenWritingTheFoo_thenCorrect() { + final String URI = BASE_URI + "foos"; + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setMessageConverters(getJsonAndXmlMessageConverters()); + + final Foo resource = new Foo("jason"); + final HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + headers.setContentType((MediaType.APPLICATION_XML)); + final HttpEntity entity = new HttpEntity<>(resource, headers); + + final ResponseEntity response = restTemplate.exchange(URI, HttpMethod.POST, entity, Foo.class); + final Foo fooResponse = response.getBody(); + + assertThat(fooResponse, notNullValue()); + assertEquals(resource.getName(), fooResponse.getName()); + } + + private List> getJsonAndXmlMessageConverters() { + final List> converters = getJsonMessageConverters(); + converters.addAll(getXmlMessageConverters()); + return converters; + } + +}