From 87dd11502a64608f59c3b540c93933cc87eba52a Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Tue, 7 Jan 2020 14:16:38 -0800 Subject: [PATCH 1/2] Refactor HypermediaAutoConfigurationTests --- .../HypermediaAutoConfigurationTests.java | 87 ++++++++----------- 1 file changed, 34 insertions(+), 53 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java index 229eaf7c28..198e6c263e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java @@ -18,7 +18,6 @@ package org.springframework.boot.autoconfigure.hateoas; import java.util.Optional; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; @@ -26,8 +25,7 @@ import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguratio import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.MediaTypes; import org.springframework.hateoas.client.LinkDiscoverer; @@ -39,7 +37,6 @@ import org.springframework.hateoas.server.EntityLinks; import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2HttpMessageConverter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.mock.web.MockServletContext; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import static org.assertj.core.api.Assertions.assertThat; @@ -50,78 +47,62 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Roy Clarkson * @author Oliver Gierke * @author Andy Wilkinson + * @author Madhura Bhave */ class HypermediaAutoConfigurationTests { - private AnnotationConfigServletWebApplicationContext context; - - @AfterEach - void close() { - if (this.context != null) { - this.context.close(); - } - } + private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withUserConfiguration(BaseConfig.class); @Test void linkDiscoverersCreated() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(BaseConfig.class); - this.context.refresh(); - LinkDiscoverers discoverers = this.context.getBean(LinkDiscoverers.class); - assertThat(discoverers).isNotNull(); - Optional discoverer = discoverers.getLinkDiscovererFor(MediaTypes.HAL_JSON); - assertThat(discoverer).containsInstanceOf(HalLinkDiscoverer.class); + this.contextRunner.run((context) -> { + LinkDiscoverers discoverers = context.getBean(LinkDiscoverers.class); + assertThat(discoverers).isNotNull(); + Optional discoverer = discoverers.getLinkDiscovererFor(MediaTypes.HAL_JSON); + assertThat(discoverer).containsInstanceOf(HalLinkDiscoverer.class); + }); } @Test void entityLinksCreated() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(BaseConfig.class); - this.context.refresh(); - EntityLinks discoverers = this.context.getBean(EntityLinks.class); - assertThat(discoverers).isNotNull(); + this.contextRunner.run((context) -> { + EntityLinks discoverers = context.getBean(EntityLinks.class); + assertThat(discoverers).isNotNull(); + }); } @Test void doesBackOffIfEnableHypermediaSupportIsDeclaredManually() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(EnableHypermediaSupportConfig.class, BaseConfig.class); - TestPropertyValues.of("spring.jackson.serialization.INDENT_OUTPUT:true").applyTo(this.context); - this.context.refresh(); - assertThat(this.context.getBeansOfType(HypermediaConfiguration.class)).isEmpty(); + this.contextRunner.withUserConfiguration(EnableHypermediaSupportConfig.class) + .withPropertyValues("spring.jackson.serialization.INDENT_OUTPUT:true") + .run((context) -> assertThat(context.getBeansOfType(HypermediaConfiguration.class)).isEmpty()); } @Test void supportedMediaTypesOfTypeConstrainedConvertersIsCustomized() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(BaseConfig.class); - this.context.refresh(); - RequestMappingHandlerAdapter handlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class); - for (HttpMessageConverter converter : handlerAdapter.getMessageConverters()) { - if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) { - assertThat(converter.getSupportedMediaTypes()).contains(MediaType.APPLICATION_JSON, - MediaTypes.HAL_JSON); + this.contextRunner.run((context) -> { + RequestMappingHandlerAdapter handlerAdapter = context.getBean(RequestMappingHandlerAdapter.class); + for (HttpMessageConverter converter : handlerAdapter.getMessageConverters()) { + if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) { + assertThat(converter.getSupportedMediaTypes()).contains(MediaType.APPLICATION_JSON, + MediaTypes.HAL_JSON); + } } - } + }); } @Test void customizationOfSupportedMediaTypesCanBeDisabled() { - this.context = new AnnotationConfigServletWebApplicationContext(); - this.context.setServletContext(new MockServletContext()); - this.context.register(BaseConfig.class); - TestPropertyValues.of("spring.hateoas.use-hal-as-default-json-media-type:false").applyTo(this.context); - this.context.refresh(); - RequestMappingHandlerAdapter handlerAdapter = this.context.getBean(RequestMappingHandlerAdapter.class); - for (HttpMessageConverter converter : handlerAdapter.getMessageConverters()) { - if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) { - assertThat(converter.getSupportedMediaTypes()).containsExactly(MediaTypes.HAL_JSON); - } - } + this.contextRunner.withPropertyValues("spring.hateoas.use-hal-as-default-json-media-type:false") + .run((context) -> { + RequestMappingHandlerAdapter handlerAdapter = context.getBean(RequestMappingHandlerAdapter.class); + for (HttpMessageConverter converter : handlerAdapter.getMessageConverters()) { + if (converter instanceof TypeConstrainedMappingJackson2HttpMessageConverter) { + assertThat(converter.getSupportedMediaTypes()).containsExactly(MediaTypes.HAL_JSON); + } + } + }); } @ImportAutoConfiguration({ HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class, From 82dc7bcc908b31643b22df6a61e4375c8e143e97 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Tue, 7 Jan 2020 14:28:58 -0800 Subject: [PATCH 2/2] HypermediaAutoConfiguration should back off when Spring MVC absent Fixes gh-19392 --- .../autoconfigure/hateoas/HypermediaAutoConfiguration.java | 3 ++- .../hateoas/HypermediaAutoConfigurationTests.java | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java index 27f1bc188d..857407e027 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfiguration.java @@ -36,6 +36,7 @@ import org.springframework.hateoas.config.EnableHypermediaSupport; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import org.springframework.plugin.core.Plugin; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; /** * {@link EnableAutoConfiguration Auto-configuration} for Spring HATEOAS's @@ -47,7 +48,7 @@ import org.springframework.web.bind.annotation.RequestMapping; * @since 1.1.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ EntityModel.class, RequestMapping.class, Plugin.class }) +@ConditionalOnClass({ EntityModel.class, RequestMapping.class, RequestMappingHandlerAdapter.class, Plugin.class }) @ConditionalOnWebApplication @AutoConfigureAfter({ WebMvcAutoConfiguration.class, JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java index 198e6c263e..c9045e22b0 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/hateoas/HypermediaAutoConfigurationTests.java @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguratio import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Configuration; import org.springframework.hateoas.MediaTypes; @@ -54,6 +55,12 @@ class HypermediaAutoConfigurationTests { private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withUserConfiguration(BaseConfig.class); + @Test + void autoConfigurationWhenSpringMvcNotOnClasspathShouldBackOff() { + this.contextRunner.withClassLoader(new FilteredClassLoader(RequestMappingHandlerAdapter.class)) + .run((context) -> assertThat(context.getBeansOfType(HypermediaConfiguration.class)).isEmpty()); + } + @Test void linkDiscoverersCreated() { this.contextRunner.run((context) -> {