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

@@ -35,8 +35,10 @@ import org.springframework.restdocs.operation.OperationResponse;
import org.springframework.restdocs.operation.OperationResponseFactory;
import org.springframework.restdocs.operation.RequestConverter;
import org.springframework.restdocs.operation.ResponseConverter;
import org.springframework.restdocs.operation.preprocess.OperationPreprocessor;
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor;
import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor;
import org.springframework.restdocs.operation.preprocess.Preprocessors;
import org.springframework.restdocs.snippet.Snippet;
import static org.hamcrest.CoreMatchers.equalTo;
@@ -51,6 +53,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
* Tests for {@link RestDocumentationGenerator}.
*
* @author Andy Wilkinson
* @author Filip Hrisafov
*/
public class RestDocumentationGeneratorTests {
@@ -75,6 +78,9 @@ public class RestDocumentationGeneratorTests {
private final Snippet snippet = mock(Snippet.class);
private final OperationPreprocessor requestPreprocessor = mock(OperationPreprocessor.class);
private final OperationPreprocessor responsePreprocessor = mock(OperationPreprocessor.class);
@Test
public void basicHandling() throws IOException {
given(this.requestConverter.convert(this.request))
@@ -107,6 +113,84 @@ public class RestDocumentationGeneratorTests {
verifySnippetInvocation(defaultSnippet2, configuration);
}
@Test
public void defaultOperationRequestPreprocessorsAreCalled() throws IOException {
given(this.requestConverter.convert(this.request))
.willReturn(this.operationRequest);
given(this.responseConverter.convert(this.response))
.willReturn(this.operationResponse);
HashMap<String, Object> configuration = new HashMap<>();
OperationPreprocessor defaultPreprocessor1 = mock(OperationPreprocessor.class);
OperationPreprocessor defaultPreprocessor2 = mock(OperationPreprocessor.class);
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR,
Preprocessors.preprocessRequest(defaultPreprocessor1, defaultPreprocessor2));
OperationRequest first = createRequest();
OperationRequest second = createRequest();
OperationRequest third = createRequest();
given(this.requestPreprocessor.preprocess(this.operationRequest)).willReturn(first);
given(defaultPreprocessor1.preprocess(first)).willReturn(second);
given(defaultPreprocessor2.preprocess(second)).willReturn(third);
new RestDocumentationGenerator<>("id", this.requestConverter,
this.responseConverter, Preprocessors.preprocessRequest(this.requestPreprocessor), this.snippet)
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, third, this.operationResponse, configuration, 1);
}
@Test
public void defaultOperationResponsePreprocessorsAreCalled() throws IOException {
given(this.requestConverter.convert(this.request))
.willReturn(this.operationRequest);
given(this.responseConverter.convert(this.response))
.willReturn(this.operationResponse);
HashMap<String, Object> configuration = new HashMap<>();
OperationPreprocessor defaultPreprocessor1 = mock(OperationPreprocessor.class);
OperationPreprocessor defaultPreprocessor2 = mock(OperationPreprocessor.class);
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR,
Preprocessors.preprocessResponse(defaultPreprocessor1, defaultPreprocessor2));
OperationResponse first = createResponse();
OperationResponse second = createResponse();
OperationResponse third = new OperationResponseFactory().createFrom(this.operationResponse, new HttpHeaders());
given(this.responsePreprocessor.preprocess(this.operationResponse)).willReturn(first);
given(defaultPreprocessor1.preprocess(first)).willReturn(second);
given(defaultPreprocessor2.preprocess(second)).willReturn(third);
new RestDocumentationGenerator<>("id", this.requestConverter,
this.responseConverter, Preprocessors.preprocessResponse(this.responsePreprocessor), this.snippet)
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, this.operationRequest, third, configuration, 1);
}
@Test
public void defaultOperationPreprocessorsAreCalled() throws IOException {
given(this.requestConverter.convert(this.request))
.willReturn(this.operationRequest);
given(this.responseConverter.convert(this.response))
.willReturn(this.operationResponse);
HashMap<String, Object> configuration = new HashMap<>();
OperationPreprocessor requestPreprocessor1 = mock(OperationPreprocessor.class);
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR,
Preprocessors.preprocessRequest(requestPreprocessor1));
OperationRequest firstRequest = createRequest();
OperationRequest secondRequest = createRequest();
given(this.requestPreprocessor.preprocess(this.operationRequest)).willReturn(firstRequest);
given(requestPreprocessor1.preprocess(firstRequest)).willReturn(secondRequest);
OperationPreprocessor responsePreprocessor1 = mock(OperationPreprocessor.class);
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR,
Preprocessors.preprocessResponse(responsePreprocessor1));
OperationResponse firstResponse = createResponse();
OperationResponse secondResponse = createResponse();
given(this.responsePreprocessor.preprocess(this.operationResponse)).willReturn(firstResponse);
given(responsePreprocessor1.preprocess(firstResponse)).willReturn(secondResponse);
new RestDocumentationGenerator<>("id", this.requestConverter,
this.responseConverter, Preprocessors.preprocessRequest(this.requestPreprocessor),
Preprocessors.preprocessResponse(this.responsePreprocessor), this.snippet)
.handle(this.request, this.response, configuration);
verifySnippetInvocation(this.snippet, secondRequest, secondResponse, configuration, 1);
}
@Test
public void newGeneratorOnlyCallsItsSnippets() throws IOException {
OperationRequestPreprocessor requestPreprocessor = mock(
@@ -141,12 +225,27 @@ public class RestDocumentationGeneratorTests {
private void verifySnippetInvocation(Snippet snippet, Map<String, Object> attributes,
int times) throws IOException {
verifySnippetInvocation(snippet, this.operationRequest, this.operationResponse, attributes, times);
}
private void verifySnippetInvocation(Snippet snippet, OperationRequest operationRequest,
OperationResponse operationResponse,
Map<String, Object> attributes, int times) throws IOException {
ArgumentCaptor<Operation> operation = ArgumentCaptor.forClass(Operation.class);
verify(snippet, Mockito.times(times)).document(operation.capture());
assertThat(this.operationRequest, is(equalTo(operation.getValue().getRequest())));
assertThat(this.operationResponse,
is(equalTo(operation.getValue().getResponse())));
assertThat(operationRequest, is(equalTo(operation.getValue().getRequest())));
assertThat(operationResponse, is(equalTo(operation.getValue().getResponse())));
assertThat(attributes, is(equalTo(operation.getValue().getAttributes())));
}
private static OperationRequest createRequest() {
return new OperationRequestFactory()
.create(URI.create("http://localhost:8080"), null, null, new HttpHeaders(), null, null);
}
private static OperationResponse createResponse() {
return new OperationResponseFactory()
.create(null, null, null);
}
}

View File

@@ -31,6 +31,9 @@ import org.springframework.restdocs.cli.HttpieRequestSnippet;
import org.springframework.restdocs.generate.RestDocumentationGenerator;
import org.springframework.restdocs.http.HttpRequestSnippet;
import org.springframework.restdocs.http.HttpResponseSnippet;
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor;
import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor;
import org.springframework.restdocs.operation.preprocess.Preprocessors;
import org.springframework.restdocs.payload.RequestBodySnippet;
import org.springframework.restdocs.payload.ResponseBodySnippet;
import org.springframework.restdocs.snippet.Snippet;
@@ -45,6 +48,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasEntry;
import static org.junit.Assert.assertThat;
@@ -54,6 +58,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link RestDocumentationConfigurer}.
*
* @author Andy Wilkinson
* @author Filip Hrisafov
*/
public class RestDocumentationConfigurerTests {
@@ -88,6 +93,14 @@ public class RestDocumentationConfigurerTests {
assertThat(snippetConfiguration.getEncoding(), is(equalTo("UTF-8")));
assertThat(snippetConfiguration.getTemplateFormat(),
is(equalTo(TemplateFormats.asciidoctor())));
OperationRequestPreprocessor defaultOperationRequestPreprocessor = (OperationRequestPreprocessor)
configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR);
assertThat(defaultOperationRequestPreprocessor, is(nullValue()));
OperationResponsePreprocessor defaultOperationResponsePreprocessor = (OperationResponsePreprocessor)
configuration.get(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR);
assertThat(defaultOperationResponsePreprocessor, is(nullValue()));
}
@Test
@@ -200,6 +213,32 @@ public class RestDocumentationConfigurerTests {
assertThat(templateContext.size(), equalTo(0));
}
@Test
public void customDefaultOperationRequestPreprocessor() {
Map<String, Object> configuration = new HashMap<>();
this.configurer.operationPreprocessors()
.withDefaultRequestPreprocessors(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
assertThat(configuration,
hasEntry(
equalTo(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_REQUEST_PREPROCESSOR),
instanceOf(OperationRequestPreprocessor.class)));
//TODO how can we actually test that the preprocessors that we set are actually there?
}
@Test
public void customDefaultOperationResponsePreprocessor() {
Map<String, Object> configuration = new HashMap<>();
this.configurer.operationPreprocessors()
.withDefaultResponsePreprocessors(Preprocessors.prettyPrint(), Preprocessors.removeHeaders("Foo"))
.apply(configuration, createContext());
assertThat(configuration,
hasEntry(
equalTo(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_OPERATION_RESPONSE_PREPROCESSOR),
instanceOf(OperationResponsePreprocessor.class)));
//TODO same as for the customDefaultOperationRequestPreprocessor
}
private RestDocumentationContext createContext() {
ManualRestDocumentation manualRestDocumentation = new ManualRestDocumentation(
"build");
@@ -209,16 +248,24 @@ public class RestDocumentationConfigurerTests {
}
private static final class TestRestDocumentationConfigurer extends
RestDocumentationConfigurer<TestSnippetConfigurer, TestRestDocumentationConfigurer> {
RestDocumentationConfigurer<TestSnippetConfigurer, TestOperationPreprocessorsConfigurer,
TestRestDocumentationConfigurer> {
private final TestSnippetConfigurer snippetConfigurer = new TestSnippetConfigurer(
this);
private final TestOperationPreprocessorsConfigurer operationPreprocessorsConfigurer =
new TestOperationPreprocessorsConfigurer(this);
@Override
public TestSnippetConfigurer snippets() {
return this.snippetConfigurer;
}
@Override
public TestOperationPreprocessorsConfigurer operationPreprocessors() {
return this.operationPreprocessorsConfigurer;
}
}
private static final class TestSnippetConfigurer extends
@@ -230,4 +277,12 @@ public class RestDocumentationConfigurerTests {
}
private static final class TestOperationPreprocessorsConfigurer extends
OperationPreprocessorsConfigurer<TestRestDocumentationConfigurer, TestOperationPreprocessorsConfigurer> {
protected TestOperationPreprocessorsConfigurer(TestRestDocumentationConfigurer parent) {
super(parent);
}
}
}