Commit ab7c47d3 authored by Roman Zaynetdinov's avatar Roman Zaynetdinov Committed by Andy Wilkinson

Add auto-configuration for using REST Docs with WebTestClient

See gh-10969
parent 16c52bce
......@@ -70,7 +70,7 @@
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck" />
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck">
<property name="excludes"
value="io.restassured.RestAssured.*, org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.ArgumentMatchers.*, org.mockito.Matchers.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.payload.PayloadDocumentation.*, org.springframework.restdocs.request.RequestDocumentation.*, org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*, org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.ExpectedCount.*, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*" />
value="io.restassured.RestAssured.*, org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.ArgumentMatchers.*, org.mockito.Matchers.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.payload.PayloadDocumentation.*, org.springframework.restdocs.request.RequestDocumentation.*, org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*, org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*, org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.ExpectedCount.*, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*" />
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck" >
<property name="illegalPkgs" value="sun, org.apache.commons.(?!codec|compress|dbcp2|lang|lang3|logging|pool2).*, com.google.common, org.flywaydb.core.internal"/>
......
......@@ -152,6 +152,11 @@
<artifactId>spring-restdocs-restassured</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-webtestclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
......
......@@ -35,12 +35,15 @@ import org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentation;
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer;
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation;
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring REST Docs.
*
* @author Andy Wilkinson
* @author Eddú Meléndez
* @author Roman Zaynetdinov
* @since 1.4.0
*/
@Configuration
......@@ -108,4 +111,33 @@ public class RestDocsAutoConfiguration {
}
@Configuration
@ConditionalOnClass(WebTestClientRestDocumentation.class)
@ConditionalOnWebApplication(type = Type.REACTIVE)
static class RestDocsWebTestClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean(WebTestClientRestDocumentationConfigurer.class)
public WebTestClientRestDocumentationConfigurer restDocsWebTestClientConfigurer(
ObjectProvider<RestDocsWebTestClientConfigurationCustomizer> configurationCustomizerProvider,
RestDocumentationContextProvider contextProvider) {
WebTestClientRestDocumentationConfigurer configurer = WebTestClientRestDocumentation
.documentationConfiguration(contextProvider);
RestDocsWebTestClientConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider
.getIfAvailable();
if (configurationCustomizer != null) {
configurationCustomizer.customize(configurer);
}
return configurer;
}
@Bean
@ConfigurationProperties(prefix = "spring.test.restdocs")
public RestDocsWebTestClientBuilderCustomizer restDocumentationConfigurer(
WebTestClientRestDocumentationConfigurer configurer) {
return new RestDocsWebTestClientBuilderCustomizer(configurer);
}
}
}
/*
* Copyright 2012-2017 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.boot.test.autoconfigure.restdocs;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientBuilderCustomizer;
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.StringUtils;
/**
* A customizer that configures Spring REST Docs with WebTestClient.
*
* @author Eddú Meléndez
* @author Roman Zaynetdinov
*/
class RestDocsWebTestClientBuilderCustomizer implements InitializingBean, WebTestClientBuilderCustomizer {
private final WebTestClientRestDocumentationConfigurer delegate;
private String uriScheme;
private String uriHost;
private Integer uriPort;
RestDocsWebTestClientBuilderCustomizer(WebTestClientRestDocumentationConfigurer delegate) {
this.delegate = delegate;
}
public String getUriScheme() {
return this.uriScheme;
}
public void setUriScheme(String uriScheme) {
this.uriScheme = uriScheme;
}
public String getUriHost() {
return this.uriHost;
}
public void setUriHost(String uriHost) {
this.uriHost = uriHost;
}
public Integer getUriPort() {
return this.uriPort;
}
public void setUriPort(Integer uriPort) {
this.uriPort = uriPort;
}
@Override
public void afterPropertiesSet() throws Exception {
}
@Override
public void customize(WebTestClient.Builder builder) {
if (StringUtils.hasText(this.uriScheme) && StringUtils.hasText(this.uriHost)) {
String baseUrl = this.uriScheme + "://" + this.uriHost;
if (this.uriPort == 80 && this.uriScheme.equals("http")) {
// Don't add default port
} else if (this.uriPort == 443 && this.uriScheme.equals("https")) {
// Don't add default port
} else if (this.uriPort != null) {
baseUrl += ":" + this.uriPort;
}
builder.baseUrl(baseUrl);
}
builder.filter(this.delegate);
}
}
/*
* Copyright 2012-2017 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.boot.test.autoconfigure.restdocs;
import org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer;
/**
* A customizer for {@link WebTestClientRestDocumentationConfigurer}. If a
* {@code RestDocsWebTestClientConfigurationCustomizer} bean is found in the application context
* it will be {@link #customize called} to customize the
* {@code WebTestClientRestDocumentationConfigurer} before it is applied. Intended for use only
* when the attributes on {@link AutoConfigureRestDocs} do not provide sufficient
* customization.
*
* @author Andy Wilkinson
* @author Roman Zaynetdinov
* @since 2.0.0
*/
@FunctionalInterface
public interface RestDocsWebTestClientConfigurationCustomizer {
/**
* Customize the given {@code configurer}.
* @param configurer the configurer
*/
void customize(WebTestClientRestDocumentationConfigurer configurer);
}
/*
* Copyright 2012-2017 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.boot.test.autoconfigure.restdocs;
import java.io.File;
import org.assertj.core.api.Condition;
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.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.document;
/**
* Integration tests for {@link RestDocsAutoConfiguration} with WebClientTest.
*
* @author Andy Wilkinson
* @author Roman Zaynetdinov
*/
@RunWith(SpringRunner.class)
@WebFluxTest
@AutoConfigureRestDocs(uriScheme = "https", uriHost = "api.example.com", uriPort = 443)
public class WebTestClientRestDocsAutoConfigurationIntegrationTests {
@Before
public void deleteSnippets() {
FileSystemUtils.deleteRecursively(new File("target/generated-snippets"));
}
@Autowired
private WebTestClient webTestClient;
@Test
public void defaultSnippetsAreWritten() throws Exception {
this.webTestClient.get().uri("/").exchange()
.expectBody().consumeWith(document("default-snippets"));
File defaultSnippetsDir = new File("target/generated-snippets/default-snippets");
assertThat(defaultSnippetsDir).exists();
assertThat(new File(defaultSnippetsDir, "curl-request.adoc"))
.has(contentContaining("'https://api.example.com/'"));
assertThat(new File(defaultSnippetsDir, "http-request.adoc"))
.has(contentContaining("api.example.com"));
assertThat(new File(defaultSnippetsDir, "http-response.adoc")).isFile();
}
private Condition<File> contentContaining(String toContain) {
return new ContentContainingCondition(toContain);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment