Add support for configuring default request and response preprocessors

See gh-424
This commit is contained in:
Filip Hrisafov
2017-09-02 10:35:11 +02:00
committed by Andy Wilkinson
parent 22cf08a9ad
commit 4f8b173836
20 changed files with 699 additions and 52 deletions

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2014-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.restdocs.mockmvc;
import org.springframework.restdocs.config.OperationPreprocessorsConfigurer;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.web.context.WebApplicationContext;
/**
* A configurer that can be used to configure the operation preprocessors.
*
* @author Filip Hrisafov
* @since 2.0.0
*/
public final class MockMvcOperationPreprocessorsConfigurer extends
OperationPreprocessorsConfigurer<MockMvcRestDocumentationConfigurer, MockMvcOperationPreprocessorsConfigurer>
implements MockMvcConfigurer {
MockMvcOperationPreprocessorsConfigurer(MockMvcRestDocumentationConfigurer parent) {
super(parent);
}
@Override
public void afterConfigurerAdded(ConfigurableMockMvcBuilder<?> builder) {
and().afterConfigurerAdded(builder);
}
@Override
public RequestPostProcessor beforeMockMvcCreated(
ConfigurableMockMvcBuilder<?> builder, WebApplicationContext context) {
return and().beforeMockMvcCreated(builder, context);
}
}

View File

@@ -33,10 +33,12 @@ import org.springframework.web.context.WebApplicationContext;
* A MockMvc-specific {@link RestDocumentationConfigurer}.
*
* @author Andy Wilkinson
* @author Filip Hrisafov
* @since 1.1.0
*/
public final class MockMvcRestDocumentationConfigurer extends
RestDocumentationConfigurer<MockMvcSnippetConfigurer, MockMvcRestDocumentationConfigurer>
RestDocumentationConfigurer<MockMvcSnippetConfigurer, MockMvcOperationPreprocessorsConfigurer,
MockMvcRestDocumentationConfigurer>
implements MockMvcConfigurer {
private final MockMvcSnippetConfigurer snippetConfigurer = new MockMvcSnippetConfigurer(
@@ -44,6 +46,9 @@ public final class MockMvcRestDocumentationConfigurer extends
private final UriConfigurer uriConfigurer = new UriConfigurer(this);
private final MockMvcOperationPreprocessorsConfigurer operationPreprocessorsConfigurer =
new MockMvcOperationPreprocessorsConfigurer(this);
private final RestDocumentationContextProvider contextManager;
MockMvcRestDocumentationConfigurer(RestDocumentationContextProvider contextManager) {
@@ -76,6 +81,11 @@ public final class MockMvcRestDocumentationConfigurer extends
return this.snippetConfigurer;
}
@Override
public MockMvcOperationPreprocessorsConfigurer operationPreprocessors() {
return this.operationPreprocessorsConfigurer;
}
private final class ConfigurerApplyingRequestPostProcessor
implements RequestPostProcessor {

View File

@@ -82,6 +82,9 @@ public class RestDocumentationResultHandler implements ResultHandler {
.getAttribute(ATTRIBUTE_NAME_CONFIGURATION));
configuration.remove(
RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
// TODO Do we need to remove the preprocessors here as well?
// I think that there is no test that evaluates this here. And the Javadoc does not reflect the
// behaviour
getDelegate().handle(result.getRequest(), result.getResponse(),
configuration);
}

View File

@@ -103,6 +103,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Andy Wilkinson
* @author Dewet Diener
* @author Tomasz Kopczynski
* @author Filip Hrisafov
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@@ -493,6 +494,44 @@ public class MockMvcRestDocumentationIntegrationTests {
.withContents(preprocessedRequest.content(prettyPrinted))));
}
@Test
public void defaultPreprocessedRequest() throws Exception {
Pattern pattern = Pattern.compile("(\"alpha\")");
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)
.operationPreprocessors()
.withDefaultRequestPreprocessors(prettyPrint(),
removeHeaders("a", HttpHeaders.HOST,
HttpHeaders.CONTENT_LENGTH),
replacePattern(pattern, "\"<<beta>>\"")))
.build();
MvcResult result = mockMvc
.perform(get("/").header("a", "alpha").header("b", "bravo")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON).content("{\"a\":\"alpha\"}"))
.andDo(document("default-preprocessed-request"))
.andReturn();
HttpRequestMatcher preprocessedRequest = httpRequest(asciidoctor(),
RequestMethod.GET, "/");
List<String> removedHeaders = Arrays.asList("a", HttpHeaders.HOST,
HttpHeaders.CONTENT_LENGTH);
for (String headerName : iterable(result.getRequest().getHeaderNames())) {
if (!removedHeaders.contains(headerName)) {
preprocessedRequest.header(headerName,
result.getRequest().getHeader(headerName));
}
}
String prettyPrinted = String.format("{%n \"a\" : \"<<beta>>\"%n}");
assertThat(
new File(
"build/generated-snippets/default-preprocessed-request/http-request.adoc"),
is(snippet(asciidoctor())
.withContents(preprocessedRequest.content(prettyPrinted))));
}
@Test
public void preprocessedResponse() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
@@ -529,6 +568,34 @@ public class MockMvcRestDocumentationIntegrationTests {
.content(prettyPrinted))));
}
@Test
public void defaultPreprocessedResponse() throws Exception {
Pattern pattern = Pattern.compile("(\"alpha\")");
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)
.operationPreprocessors()
.withDefaultResponsePreprocessors(prettyPrint(), maskLinks(), removeHeaders("a"),
replacePattern(pattern, "\"<<beta>>\"")))
.build();
mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("default-preprocessed-response"));
String prettyPrinted = String.format("{%n \"a\" : \"<<beta>>\",%n \"links\" : "
+ "[ {%n \"rel\" : \"rel\",%n \"href\" : \"...\"%n } ]%n}");
assertThat(
new File(
"build/generated-snippets/default-preprocessed-response/http-response.adoc"),
is(snippet(asciidoctor())
.withContents(httpResponse(asciidoctor(), HttpStatus.OK)
.header("Content-Type", "application/json;charset=UTF-8")
.header(HttpHeaders.CONTENT_LENGTH,
prettyPrinted.getBytes().length)
.content(prettyPrinted))));
}
@Test
public void customSnippetTemplate() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)