Add support for modifying a request prior to it being documented
Prior to this commit it was not possible to modify a request prior to it being documented, only a response. This commit builds on the new Operation abstraction to simplify the existing response modification support and to add support for request modification. Closes gh-84
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
[[customizing-requests-and-responses]]
|
||||
== Customizing requests and responses
|
||||
|
||||
There may be situations where you do not want to document a request exactly as it was sent
|
||||
or a response exactly as it was received. Spring REST Docs provides a number of
|
||||
preprocessors that can be used to modify a request or response before it's documented.
|
||||
|
||||
Preprocessing is configured by calling `document` with an `OperationRequestPreprocessor`,
|
||||
and/or an `OperationResponsePreprocessor`. Instances can be obtained using the
|
||||
static `preprocessRequest` and `preprocessResponse` methods on `Preprocessors`:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{examples-dir}/com/example/Preprocessing.java[tags=general]
|
||||
----
|
||||
<1> Apply a request preprocessor that will remove the header named `Foo`.
|
||||
<2> Apply a response preprocessor that will pretty print its content.
|
||||
|
||||
Various built in preprocessors, including those illustrated above, are available via the
|
||||
static methods on `Preprocessors`. See below for further details.
|
||||
|
||||
|
||||
|
||||
[[customizing-requests-and-responses-pretty-printing]]
|
||||
=== Pretty printing
|
||||
|
||||
`prettyPrint` on `Preprocessors` formats the content of the request or response
|
||||
to make it easier to read.
|
||||
|
||||
|
||||
|
||||
[[customizing-requests-and-responses-masking-links]]
|
||||
=== Masking links
|
||||
|
||||
If you're documenting a Hypermedia-based API, you may want to encourage clients to
|
||||
navigate the API using links rather than through the use of hard coded URIs. One way to do
|
||||
this is to limit the use of URIs in the documentation. `maskLinks` on
|
||||
`Preprocessors` replaces the `href` of any links in the response with `...`. A
|
||||
different replacement can also be specified if you wish.
|
||||
|
||||
|
||||
|
||||
[[customizing-requests-and-responses-removing-headers]]
|
||||
=== Removing headers
|
||||
|
||||
`removeHeaders` on `Preprocessors` removes any occurrences of the named headers
|
||||
from the request or response.
|
||||
|
||||
|
||||
|
||||
[[customizing-requests-and-responses-replacing-patterns]]
|
||||
=== Replacing patterns
|
||||
|
||||
`replacePattern` on `Preprocessors` provides a general purpose mechanism for
|
||||
replacing content in a request or response. Any occurrences of a regular expression are
|
||||
replaced.
|
||||
@@ -1,45 +0,0 @@
|
||||
[[customizing-responses]]
|
||||
== Customizing responses
|
||||
|
||||
There may be situations where you do not want to document a response exactly as received.
|
||||
Spring REST Docs provides a number of response post processors that can be used to modify
|
||||
a response after it is received but before it's documented.
|
||||
|
||||
Response modification is configured using a `ResponseModifier`. An instance can be
|
||||
obtained using the static `modifyResponseTo` method on `RestDocumentation`. Once the
|
||||
response modifications have been provided, documentation can be configured as usual
|
||||
via the `andDocument` method:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{examples-dir}/com/example/ResponsePostProcessing.java[tags=general]
|
||||
----
|
||||
<1> Call `modifyResponseTo` to configure response modifications, passing in one or more
|
||||
`ResponsePostProcessor` implementations.
|
||||
<2> Proceed with documenting the call.
|
||||
|
||||
|
||||
[[customizing-responses-pretty-printing]]
|
||||
=== Pretty printing
|
||||
|
||||
`prettyPrintContent` on `ResponsePostProcessors` formats the body of the response to
|
||||
make it easier to read.
|
||||
|
||||
[[customizing-responses-masking-links]]
|
||||
=== Masking links
|
||||
|
||||
If you're documenting a Hypermedia-based API, you may want to encourage clients to
|
||||
navigate the API using links rather than through the use of hard coded URIs. One way to do
|
||||
this is to limit the use of URIs in the documentation. `maskLinks` on
|
||||
`ResponsePostProcessors` replaces the `href` of any links in the response with `...`. A
|
||||
different replacement can also be specified if you wish.
|
||||
|
||||
=== Removing headers
|
||||
|
||||
`removeHeaders` on `ResponsePostProcessors` removes any occurrences of the named headers
|
||||
from the response.
|
||||
|
||||
=== Replacing patterns
|
||||
|
||||
`replacePattern` on `ResponsePostProcessors` provides a general purpose mechanism for
|
||||
replacing content in a response. Any occurrences of a regular expression are replaced.
|
||||
@@ -23,7 +23,7 @@ snippets produced with Spring MVC Test.
|
||||
include::introduction.adoc[]
|
||||
include::getting-started.adoc[]
|
||||
include::documenting-your-api.adoc[]
|
||||
include::customizing-responses.adoc[]
|
||||
include::customizing-requests-and-responses.adoc[]
|
||||
include::configuration.adoc[]
|
||||
include::working-with-asciidoctor.adoc[]
|
||||
include::contributing.adoc[]
|
||||
@@ -16,13 +16,17 @@
|
||||
|
||||
package com.example;
|
||||
|
||||
import static org.springframework.restdocs.RestDocumentation.modifyResponseTo;
|
||||
import static org.springframework.restdocs.RestDocumentationRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
|
||||
import static org.springframework.restdocs.RestDocumentation.document;
|
||||
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
public class ResponsePostProcessing {
|
||||
public class Preprocessing {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@@ -30,8 +34,9 @@ public class ResponsePostProcessing {
|
||||
// tag::general[]
|
||||
this.mockMvc.perform(get("/"))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(modifyResponseTo(/* ... */) // <1>
|
||||
.andDocument("index")); // <2>
|
||||
.andDo(document("index",
|
||||
preprocessRequest(removeHeaders("Foo")), // <1>
|
||||
preprocessResponse(prettyPrint()))); // <2>
|
||||
// end::general[]
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.restdocs.response.ResponsePostProcessor;
|
||||
import org.springframework.restdocs.snippet.Snippet;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Modifies the response in an {@link MvcResult} by applying {@link ResponsePostProcessor
|
||||
* ResponsePostProcessors} to it.
|
||||
*
|
||||
* @see RestDocumentation#modifyResponseTo(ResponsePostProcessor...)
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public final class ResponseModifier {
|
||||
|
||||
private final List<ResponsePostProcessor> postProcessors;
|
||||
|
||||
ResponseModifier(ResponsePostProcessor... postProcessors) {
|
||||
this.postProcessors = Arrays.asList(postProcessors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a {@link RestDocumentationResultHandler} that can be used to document the
|
||||
* request and modified response.
|
||||
* @param identifier an identifier for the API call that is being documented
|
||||
* @param snippets the snippets to use to document the call
|
||||
* @return the result handler that will produce the documentation
|
||||
*/
|
||||
public RestDocumentationResultHandler andDocument(String identifier,
|
||||
Snippet... snippets) {
|
||||
return new ResponseModifyingRestDocumentationResultHandler(identifier, snippets);
|
||||
}
|
||||
|
||||
class ResponseModifyingRestDocumentationResultHandler extends
|
||||
RestDocumentationResultHandler {
|
||||
|
||||
private ResponseModifyingRestDocumentationResultHandler(String identifier,
|
||||
Snippet... snippets) {
|
||||
super(identifier, snippets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MvcResult result) throws Exception {
|
||||
super.handle(postProcessResponse(result));
|
||||
}
|
||||
|
||||
MvcResult postProcessResponse(MvcResult result) throws Exception {
|
||||
MockHttpServletResponse response = result.getResponse();
|
||||
for (ResponsePostProcessor postProcessor : ResponseModifier.this.postProcessors) {
|
||||
response = postProcessor.postProcess(response);
|
||||
}
|
||||
return decorateResult(result, response);
|
||||
}
|
||||
|
||||
private MvcResult decorateResult(MvcResult result,
|
||||
MockHttpServletResponse response) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(MvcResult.class);
|
||||
enhancer.setCallback(new GetResponseMethodInterceptor(response, result));
|
||||
return (MvcResult) enhancer.create();
|
||||
}
|
||||
|
||||
private class GetResponseMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private final MvcResult delegate;
|
||||
|
||||
private final MockHttpServletResponse response;
|
||||
|
||||
private final Method getResponseMethod = findMethod("getResponse");
|
||||
|
||||
private GetResponseMethodInterceptor(MockHttpServletResponse response,
|
||||
MvcResult delegate) {
|
||||
this.delegate = delegate;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args,
|
||||
MethodProxy methodProxy) throws IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
if (this.getResponseMethod.equals(method)) {
|
||||
return this.response;
|
||||
}
|
||||
return method.invoke(this.delegate, args);
|
||||
}
|
||||
|
||||
private Method findMethod(String methodName) {
|
||||
return BridgeMethodResolver.findBridgedMethod(ReflectionUtils.findMethod(
|
||||
MvcResult.class, methodName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,11 +17,10 @@
|
||||
package org.springframework.restdocs;
|
||||
|
||||
import org.springframework.restdocs.config.RestDocumentationConfigurer;
|
||||
import org.springframework.restdocs.response.ResponsePostProcessor;
|
||||
import org.springframework.restdocs.response.ResponsePostProcessors;
|
||||
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor;
|
||||
import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor;
|
||||
import org.springframework.restdocs.snippet.Snippet;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
|
||||
@@ -50,7 +49,7 @@ public abstract class RestDocumentation {
|
||||
|
||||
/**
|
||||
* Documents the API call with the given {@code identifier} using the given
|
||||
* {@code handlers}.
|
||||
* {@code snippets}.
|
||||
*
|
||||
* @param identifier an identifier for the API call that is being documented
|
||||
* @param snippets the snippets that will document the API call
|
||||
@@ -64,17 +63,60 @@ public abstract class RestDocumentation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the modification of the response in a {@link MvcResult} prior to it being
|
||||
* documented. The modification is performed using the given
|
||||
* {@code responsePostProcessors}.
|
||||
* Documents the API call with the given {@code identifier} using the given
|
||||
* {@code snippets}. The given {@code requestPreprocessor} is applied to the request
|
||||
* before it is documented.
|
||||
*
|
||||
* @param responsePostProcessors the post-processors to use to modify the response
|
||||
* @return the response modifier
|
||||
* @see ResponsePostProcessors
|
||||
* @param identifier an identifier for the API call that is being documented
|
||||
* @param requestPreprocessor the request preprocessor
|
||||
* @param snippets the snippets that will document the API call
|
||||
* @return a Mock MVC {@code ResultHandler} that will produce the documentation
|
||||
* @see MockMvc#perform(org.springframework.test.web.servlet.RequestBuilder)
|
||||
* @see ResultActions#andDo(org.springframework.test.web.servlet.ResultHandler)
|
||||
*/
|
||||
public static ResponseModifier modifyResponseTo(
|
||||
ResponsePostProcessor... responsePostProcessors) {
|
||||
return new ResponseModifier(responsePostProcessors);
|
||||
public static RestDocumentationResultHandler document(String identifier,
|
||||
OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) {
|
||||
return new RestDocumentationResultHandler(identifier, requestPreprocessor,
|
||||
snippets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Documents the API call with the given {@code identifier} using the given
|
||||
* {@code snippets}. The given {@code responsePreprocessor} is applied to the request
|
||||
* before it is documented.
|
||||
*
|
||||
* @param identifier an identifier for the API call that is being documented
|
||||
* @param responsePreprocessor the response preprocessor
|
||||
* @param snippets the snippets that will document the API call
|
||||
* @return a Mock MVC {@code ResultHandler} that will produce the documentation
|
||||
* @see MockMvc#perform(org.springframework.test.web.servlet.RequestBuilder)
|
||||
* @see ResultActions#andDo(org.springframework.test.web.servlet.ResultHandler)
|
||||
*/
|
||||
public static RestDocumentationResultHandler document(String identifier,
|
||||
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
|
||||
return new RestDocumentationResultHandler(identifier, responsePreprocessor,
|
||||
snippets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Documents the API call with the given {@code identifier} using the given
|
||||
* {@code snippets}. The given {@code requestPreprocessor} and
|
||||
* {@code responsePreprocessor} are applied to the request and response respectively
|
||||
* before they are documented.
|
||||
*
|
||||
* @param identifier an identifier for the API call that is being documented
|
||||
* @param requestPreprocessor the request preprocessor
|
||||
* @param responsePreprocessor the response preprocessor
|
||||
* @param snippets the snippets that will document the API call
|
||||
* @return a Mock MVC {@code ResultHandler} that will produce the documentation
|
||||
* @see MockMvc#perform(org.springframework.test.web.servlet.RequestBuilder)
|
||||
* @see ResultActions#andDo(org.springframework.test.web.servlet.ResultHandler)
|
||||
*/
|
||||
public static RestDocumentationResultHandler document(String identifier,
|
||||
OperationRequestPreprocessor requestPreprocessor,
|
||||
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
|
||||
return new RestDocumentationResultHandler(identifier, requestPreprocessor,
|
||||
responsePreprocessor, snippets);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,10 +26,16 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.restdocs.operation.MockMvcOperationRequestFactory;
|
||||
import org.springframework.restdocs.operation.MockMvcOperationResponseFactory;
|
||||
import org.springframework.restdocs.operation.Operation;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.restdocs.operation.StandardOperation;
|
||||
import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor;
|
||||
import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor;
|
||||
import org.springframework.restdocs.snippet.Snippet;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultHandler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A Spring MVC Test {@code ResultHandler} for documenting RESTful APIs.
|
||||
@@ -42,10 +48,39 @@ public class RestDocumentationResultHandler implements ResultHandler {
|
||||
|
||||
private final String identifier;
|
||||
|
||||
private final OperationRequestPreprocessor requestPreprocessor;
|
||||
|
||||
private final OperationResponsePreprocessor responsePreprocessor;
|
||||
|
||||
private final List<Snippet> snippets;
|
||||
|
||||
RestDocumentationResultHandler(String identifier, Snippet... snippets) {
|
||||
this(identifier, new IdentityOperationRequestPreprocessor(),
|
||||
new IdentityOperationResponsePreprocessor(), snippets);
|
||||
}
|
||||
|
||||
RestDocumentationResultHandler(String identifier,
|
||||
OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) {
|
||||
this(identifier, requestPreprocessor,
|
||||
new IdentityOperationResponsePreprocessor(), snippets);
|
||||
}
|
||||
|
||||
RestDocumentationResultHandler(String identifier,
|
||||
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
|
||||
this(identifier, new IdentityOperationRequestPreprocessor(),
|
||||
responsePreprocessor, snippets);
|
||||
}
|
||||
|
||||
RestDocumentationResultHandler(String identifier,
|
||||
OperationRequestPreprocessor requestPreprocessor,
|
||||
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
|
||||
Assert.notNull(identifier, "identifier must be non-null");
|
||||
Assert.notNull(requestPreprocessor, "requestPreprocessor must be non-null");
|
||||
Assert.notNull(responsePreprocessor, "responsePreprocessor must be non-null");
|
||||
Assert.notNull(snippets, "snippets must be non-null");
|
||||
this.identifier = identifier;
|
||||
this.requestPreprocessor = requestPreprocessor;
|
||||
this.responsePreprocessor = responsePreprocessor;
|
||||
this.snippets = Arrays.asList(snippets);
|
||||
}
|
||||
|
||||
@@ -55,11 +90,15 @@ public class RestDocumentationResultHandler implements ResultHandler {
|
||||
for (String name : iterable(result.getRequest().getAttributeNames())) {
|
||||
attributes.put(name, result.getRequest().getAttribute(name));
|
||||
}
|
||||
StandardOperation operation = new StandardOperation(this.identifier,
|
||||
new MockMvcOperationRequestFactory().createOperationRequest(result
|
||||
.getRequest()),
|
||||
new MockMvcOperationResponseFactory().createOperationResponse(result
|
||||
.getResponse()), attributes);
|
||||
OperationRequest request = this.requestPreprocessor
|
||||
.preprocess(new MockMvcOperationRequestFactory()
|
||||
.createOperationRequest(result.getRequest()));
|
||||
|
||||
OperationResponse response = this.responsePreprocessor
|
||||
.preprocess(new MockMvcOperationResponseFactory()
|
||||
.createOperationResponse(result.getResponse()));
|
||||
Operation operation = new StandardOperation(this.identifier, request, response,
|
||||
attributes);
|
||||
for (Snippet snippet : getSnippets(result)) {
|
||||
snippet.document(operation);
|
||||
}
|
||||
@@ -74,4 +113,24 @@ public class RestDocumentationResultHandler implements ResultHandler {
|
||||
return combinedSnippets;
|
||||
}
|
||||
|
||||
static final class IdentityOperationRequestPreprocessor implements
|
||||
OperationRequestPreprocessor {
|
||||
|
||||
@Override
|
||||
public OperationRequest preprocess(OperationRequest request) {
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final class IdentityOperationResponsePreprocessor implements
|
||||
OperationResponsePreprocessor {
|
||||
|
||||
@Override
|
||||
public OperationResponse preprocess(OperationResponse response) {
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class StandardOperationRequest implements OperationRequest {
|
||||
Collection<OperationRequestPart> parts) {
|
||||
this.uri = uri;
|
||||
this.method = method;
|
||||
this.content = content == null ? new byte[0] : content;
|
||||
this.content = content;
|
||||
this.headers = headers;
|
||||
this.parameters = parameters;
|
||||
this.parts = parts;
|
||||
|
||||
@@ -44,7 +44,7 @@ public class StandardOperationResponse implements OperationResponse {
|
||||
byte[] content) {
|
||||
this.status = status;
|
||||
this.headers = headers;
|
||||
this.content = content == null ? new byte[0] : content;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,26 +14,27 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
|
||||
/**
|
||||
* A {@code ResponsePostProcessor} is used to modify the response received from a MockMvc
|
||||
* call prior to the response being documented.
|
||||
* A {@code ContentModifier} modifies the content of an {@link OperationRequest} or
|
||||
* {@link OperationResponse} during the preprocessing that is performed prior to
|
||||
* documentation generation.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @see ContentModifyingOperationPreprocessor
|
||||
*/
|
||||
public interface ResponsePostProcessor {
|
||||
interface ContentModifier {
|
||||
|
||||
/**
|
||||
* Post-processes the given {@code response}, returning a, possibly new,
|
||||
* {@link MockHttpServletResponse} that should now be used.
|
||||
* Returns modified content based on the given {@code originalContent}
|
||||
*
|
||||
* @param response The response to post-process
|
||||
* @return The result of the post-processing
|
||||
* @throws Exception if a failure occurs during the post-processing
|
||||
* @param originalContent the original content
|
||||
* @return the modified content
|
||||
*/
|
||||
MockHttpServletResponse postProcess(MockHttpServletResponse response)
|
||||
throws Exception;
|
||||
byte[] modifyContent(byte[] originalContent);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.restdocs.operation.StandardOperationRequest;
|
||||
import org.springframework.restdocs.operation.StandardOperationResponse;
|
||||
|
||||
/**
|
||||
* An {@link OperationPreprocessor} that applies a {@link ContentModifier} to the content
|
||||
* of the request or response.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class ContentModifyingOperationPreprocessor implements OperationPreprocessor {
|
||||
|
||||
private final ContentModifier contentModifier;
|
||||
|
||||
ContentModifyingOperationPreprocessor(ContentModifier contentModifier) {
|
||||
this.contentModifier = contentModifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationRequest preprocess(OperationRequest request) {
|
||||
byte[] modifiedContent = this.contentModifier.modifyContent(request.getContent());
|
||||
return new StandardOperationRequest(request.getUri(), request.getMethod(),
|
||||
modifiedContent,
|
||||
getUpdatedHeaders(request.getHeaders(), modifiedContent),
|
||||
request.getParameters(), request.getParts());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResponse preprocess(OperationResponse response) {
|
||||
byte[] modifiedContent = this.contentModifier
|
||||
.modifyContent(response.getContent());
|
||||
return new StandardOperationResponse(response.getStatus(), getUpdatedHeaders(
|
||||
response.getHeaders(), modifiedContent), modifiedContent);
|
||||
}
|
||||
|
||||
private HttpHeaders getUpdatedHeaders(HttpHeaders headers, byte[] updatedContent) {
|
||||
HttpHeaders updatedHeaders = new HttpHeaders();
|
||||
updatedHeaders.putAll(headers);
|
||||
if (updatedHeaders.getContentLength() > -1) {
|
||||
updatedHeaders.setContentLength(updatedContent.length);
|
||||
}
|
||||
return updatedHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link OperationRequestPreprocessor} that delgates to one or more
|
||||
* {@link OperationPreprocessor OperationPreprocessors} to preprocess an
|
||||
* {@link OperationRequest}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
class DelegatingOperationRequestPreprocessor implements OperationRequestPreprocessor {
|
||||
|
||||
private final List<OperationPreprocessor> delegates;
|
||||
|
||||
/**
|
||||
* Creates a new {@code DelegatingOperationRequestPreprocessor} that will delegate to
|
||||
* the given {@code delegates} by calling
|
||||
* {@link OperationPreprocessor#preprocess(OperationRequest)}.
|
||||
*
|
||||
* @param delegates the delegates
|
||||
*/
|
||||
DelegatingOperationRequestPreprocessor(List<OperationPreprocessor> delegates) {
|
||||
Assert.notNull(delegates, "delegates must be non-null");
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationRequest preprocess(OperationRequest operationRequest) {
|
||||
OperationRequest preprocessedRequest = operationRequest;
|
||||
for (OperationPreprocessor delegate : this.delegates) {
|
||||
preprocessedRequest = delegate.preprocess(preprocessedRequest);
|
||||
}
|
||||
return preprocessedRequest;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link OperationResponsePreprocessor} that delgates to one or more
|
||||
* {@link OperationPreprocessor OperationPreprocessors} to preprocess an
|
||||
* {@link OperationResponse}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class DelegatingOperationResponsePreprocessor implements OperationResponsePreprocessor {
|
||||
|
||||
private final List<OperationPreprocessor> delegates;
|
||||
|
||||
/**
|
||||
* Creates a new {@code DelegatingOperationResponsePreprocessor} that will delegate to
|
||||
* the given {@code delegates} by calling
|
||||
* {@link OperationPreprocessor#preprocess(OperationResponse)}.
|
||||
*
|
||||
* @param delegates the delegates
|
||||
*/
|
||||
DelegatingOperationResponsePreprocessor(List<OperationPreprocessor> delegates) {
|
||||
Assert.notNull(delegates, "delegates must be non-null");
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResponse preprocess(OperationResponse response) {
|
||||
OperationResponse preprocessedResponse = response;
|
||||
for (OperationPreprocessor delegate : this.delegates) {
|
||||
preprocessedResponse = delegate.preprocess(preprocessedResponse);
|
||||
}
|
||||
return preprocessedResponse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.restdocs.operation.StandardOperationRequest;
|
||||
import org.springframework.restdocs.operation.StandardOperationResponse;
|
||||
|
||||
/**
|
||||
* An {@link OperationPreprocessor} that removes headers
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class HeaderRemovingOperationPreprocessor implements OperationPreprocessor {
|
||||
|
||||
private final Set<String> headersToRemove;
|
||||
|
||||
HeaderRemovingOperationPreprocessor(String... headersToRemove) {
|
||||
this.headersToRemove = new HashSet<>(Arrays.asList(headersToRemove));
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationResponse preprocess(OperationResponse response) {
|
||||
return new StandardOperationResponse(response.getStatus(),
|
||||
removeHeaders(response.getHeaders()), response.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationRequest preprocess(OperationRequest request) {
|
||||
return new StandardOperationRequest(request.getUri(), request.getMethod(),
|
||||
request.getContent(), removeHeaders(request.getHeaders()),
|
||||
request.getParameters(), request.getParts());
|
||||
}
|
||||
|
||||
private HttpHeaders removeHeaders(HttpHeaders originalHeaders) {
|
||||
HttpHeaders processedHeaders = new HttpHeaders();
|
||||
processedHeaders.putAll(originalHeaders);
|
||||
for (String headerToRemove : this.headersToRemove) {
|
||||
processedHeaders.remove(headerToRemove);
|
||||
}
|
||||
return processedHeaders;
|
||||
}
|
||||
}
|
||||
@@ -14,30 +14,35 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A {@link ResponsePostProcessor} that modifies the content of a hypermedia response to
|
||||
* mask the hrefs of any links.
|
||||
* A content modifier the masks the {@code href} of any hypermedia links
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
class LinkMaskingResponsePostProcessor extends PatternReplacingResponsePostProcessor {
|
||||
class LinkMaskingContentModifier implements ContentModifier {
|
||||
|
||||
private static final String DEFAULT_MASK = "...";
|
||||
|
||||
private static final Pattern LINK_HREF = Pattern.compile(
|
||||
"\"href\"\\s*:\\s*\"(.*?)\"", Pattern.DOTALL);
|
||||
|
||||
LinkMaskingResponsePostProcessor() {
|
||||
super(LINK_HREF, DEFAULT_MASK);
|
||||
private final ContentModifier contentModifier;
|
||||
|
||||
LinkMaskingContentModifier() {
|
||||
this(DEFAULT_MASK);
|
||||
}
|
||||
|
||||
LinkMaskingResponsePostProcessor(String mask) {
|
||||
super(LINK_HREF, mask);
|
||||
LinkMaskingContentModifier(String mask) {
|
||||
this.contentModifier = new PatternReplacingContentModifier(LINK_HREF, mask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modifyContent(byte[] originalContent) {
|
||||
return this.contentModifier.modifyContent(originalContent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import org.springframework.restdocs.operation.Operation;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
|
||||
/**
|
||||
* An {@code OperationPreprocessor} processes the {@link OperationRequest} and
|
||||
* {@link OperationResponse} of an {@link Operation} prior to it being documented.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public interface OperationPreprocessor {
|
||||
|
||||
/**
|
||||
* Processes the given {@code request}
|
||||
*
|
||||
* @param request the request to process
|
||||
* @return the processed request
|
||||
*/
|
||||
OperationRequest preprocess(OperationRequest request);
|
||||
|
||||
/**
|
||||
* Processes the given {@code response}
|
||||
*
|
||||
* @param response the response to process
|
||||
* @return the processed response
|
||||
*/
|
||||
OperationResponse preprocess(OperationResponse response);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
|
||||
/**
|
||||
* An {@code OperationRequestPreprocessor} is used to modify an {@code OperationRequest}
|
||||
* prior to it being documented.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public interface OperationRequestPreprocessor {
|
||||
|
||||
/**
|
||||
* Processes and potentially modifies the given {@code request} before it is
|
||||
* documented.
|
||||
*
|
||||
* @param request the request
|
||||
* @return the modified request
|
||||
*/
|
||||
OperationRequest preprocess(OperationRequest request);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
|
||||
/**
|
||||
* An {@code OperationRequestPreprocessor} is used to modify an {@code OperationRequest}
|
||||
* prior to it being documented.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public interface OperationResponsePreprocessor {
|
||||
|
||||
/**
|
||||
* Processes and potentially modifies the given {@code response} before it is
|
||||
* documented.
|
||||
*
|
||||
* @param response the response
|
||||
* @return the modified response
|
||||
*/
|
||||
OperationResponse preprocess(OperationResponse response);
|
||||
|
||||
}
|
||||
@@ -14,43 +14,51 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A {@link ResponsePostProcessor} that modifies the content of the response by replacing
|
||||
* occurrences of a regular expression {@link Pattern}.
|
||||
* A {@link ContentModifier} that modifies the content by replacing occurrences of a
|
||||
* regular expression {@link Pattern}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
class PatternReplacingResponsePostProcessor extends ContentModifyingReponsePostProcessor {
|
||||
class PatternReplacingContentModifier implements ContentModifier {
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
private final String replacement;
|
||||
|
||||
PatternReplacingResponsePostProcessor(Pattern pattern, String replacement) {
|
||||
/**
|
||||
* Creates a new {@link PatternReplacingContentModifier} that will replace occurences
|
||||
* the given {@code pattern} with the given {@code replacement}.
|
||||
*
|
||||
* @param pattern the pattern
|
||||
* @param replacement the replacement
|
||||
*/
|
||||
PatternReplacingContentModifier(Pattern pattern, String replacement) {
|
||||
this.pattern = pattern;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String modifyContent(String originalContent) {
|
||||
Matcher matcher = this.pattern.matcher(originalContent);
|
||||
public byte[] modifyContent(byte[] content) {
|
||||
String original = new String(content);
|
||||
Matcher matcher = this.pattern.matcher(original);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
int previous = 0;
|
||||
while (matcher.find()) {
|
||||
buffer.append(originalContent.substring(previous, matcher.start(1)));
|
||||
buffer.append(original.substring(previous, matcher.start(1)));
|
||||
buffer.append(this.replacement);
|
||||
previous = matcher.end(1);
|
||||
}
|
||||
if (previous < originalContent.length()) {
|
||||
buffer.append(originalContent.substring(previous));
|
||||
if (previous < original.length()) {
|
||||
buffer.append(original.substring(previous));
|
||||
}
|
||||
return buffer.toString();
|
||||
return buffer.toString().getBytes();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.operation.preprocess;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.restdocs.operation.Operation;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
|
||||
/**
|
||||
* Static factory methods for creating {@link OperationPreprocessor
|
||||
* OperationPreprocessors} that can be applied to an {@link Operation Operation's}
|
||||
* {@link OperationRequest request} or {@link OperationResponse response} before it is
|
||||
* documented.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class Preprocessors {
|
||||
|
||||
private Preprocessors() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link OperationRequestPreprocessor} that will preprocess the request by
|
||||
* applying the given {@code preprocessors} to it.
|
||||
*
|
||||
* @param preprocessors the preprocessors
|
||||
* @return the request preprocessor
|
||||
*/
|
||||
public static OperationRequestPreprocessor preprocessRequest(
|
||||
OperationPreprocessor... preprocessors) {
|
||||
return new DelegatingOperationRequestPreprocessor(Arrays.asList(preprocessors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link OperationResponsePreprocessor} that will preprocess the response
|
||||
* by applying the given {@code preprocessors} to it.
|
||||
*
|
||||
* @param preprocessors the preprocessors
|
||||
* @return the response preprocessor
|
||||
*/
|
||||
public static OperationResponsePreprocessor preprocessResponse(
|
||||
OperationPreprocessor... preprocessors) {
|
||||
return new DelegatingOperationResponsePreprocessor(Arrays.asList(preprocessors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code OperationPreprocessor} that will pretty print the content of the
|
||||
* request or response.
|
||||
*
|
||||
* @return the preprocessor
|
||||
*/
|
||||
public static OperationPreprocessor prettyPrint() {
|
||||
return new ContentModifyingOperationPreprocessor(
|
||||
new PrettyPrintingContentModifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code OperationPreprocessor} that will remove headers from the request
|
||||
* or response.
|
||||
*
|
||||
* @param headersToRemove the names of the headers to remove
|
||||
* @return the preprocessor
|
||||
*/
|
||||
public static OperationPreprocessor removeHeaders(String... headersToRemove) {
|
||||
return new HeaderRemovingOperationPreprocessor(headersToRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code OperationPreprocessor} that will mask the href of hypermedia
|
||||
* links in the request or response.
|
||||
*
|
||||
* @return the preprocessor
|
||||
*/
|
||||
public static OperationPreprocessor maskLinks() {
|
||||
return new ContentModifyingOperationPreprocessor(new LinkMaskingContentModifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code OperationPreprocessor} that will mask the href of hypermedia
|
||||
* links in the request or response.
|
||||
*
|
||||
* @param mask the link mask
|
||||
* @return the preprocessor
|
||||
*/
|
||||
public static OperationPreprocessor maskLinks(String mask) {
|
||||
return new ContentModifyingOperationPreprocessor(new LinkMaskingContentModifier(
|
||||
mask));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@code OperationPreprocessor} that will modify the content of the
|
||||
* request or response by replacing occurences of the given {@code pattern} with the
|
||||
* given {@code replacement}
|
||||
*
|
||||
* @param pattern the pattern
|
||||
* @param replacement the replacement
|
||||
* @return the preprocessor
|
||||
*/
|
||||
public static OperationPreprocessor replacePattern(Pattern pattern, String replacement) {
|
||||
return new ContentModifyingOperationPreprocessor(
|
||||
new PatternReplacingContentModifier(pattern, replacement));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -29,27 +29,28 @@ import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
class PrettyPrintingResponsePostProcessor extends ContentModifyingReponsePostProcessor {
|
||||
/**
|
||||
* A {@link ContentModifier} that modifies the content by pretty printing it.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class PrettyPrintingContentModifier implements ContentModifier {
|
||||
|
||||
private static final List<PrettyPrinter> PRETTY_PRINTERS = Collections
|
||||
.unmodifiableList(Arrays.asList(new JsonPrettyPrinter(),
|
||||
new XmlPrettyPrinter()));
|
||||
|
||||
@Override
|
||||
protected String modifyContent(String originalContent) {
|
||||
if (StringUtils.hasText(originalContent)) {
|
||||
for (PrettyPrinter prettyPrinter : PRETTY_PRINTERS) {
|
||||
try {
|
||||
return prettyPrinter.prettyPrint(originalContent);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue
|
||||
}
|
||||
public byte[] modifyContent(byte[] originalContent) {
|
||||
for (PrettyPrinter prettyPrinter : PRETTY_PRINTERS) {
|
||||
try {
|
||||
return prettyPrinter.prettyPrint(originalContent).getBytes();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
return originalContent;
|
||||
@@ -57,21 +58,21 @@ class PrettyPrintingResponsePostProcessor extends ContentModifyingReponsePostPro
|
||||
|
||||
private interface PrettyPrinter {
|
||||
|
||||
String prettyPrint(String string) throws Exception;
|
||||
String prettyPrint(byte[] content) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
private static final class XmlPrettyPrinter implements PrettyPrinter {
|
||||
|
||||
@Override
|
||||
public String prettyPrint(String original) throws Exception {
|
||||
public String prettyPrint(byte[] original) throws Exception {
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
|
||||
"4");
|
||||
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
|
||||
StringWriter transformed = new StringWriter();
|
||||
transformer.transform(new StreamSource(new StringReader(original)),
|
||||
transformer.transform(new StreamSource(new ByteArrayInputStream(original)),
|
||||
new StreamResult(transformed));
|
||||
return transformed.toString();
|
||||
}
|
||||
@@ -80,7 +81,7 @@ class PrettyPrintingResponsePostProcessor extends ContentModifyingReponsePostPro
|
||||
private static final class JsonPrettyPrinter implements PrettyPrinter {
|
||||
|
||||
@Override
|
||||
public String prettyPrint(String original) throws IOException {
|
||||
public String prettyPrint(byte[] original) throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper().configure(
|
||||
SerializationFeature.INDENT_OUTPUT, true);
|
||||
return objectMapper.writeValueAsString(objectMapper.readTree(original));
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* A base class for {@link ResponsePostProcessor ResponsePostProcessors} that modify the
|
||||
* content of the response.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public abstract class ContentModifyingReponsePostProcessor implements
|
||||
ResponsePostProcessor {
|
||||
|
||||
@Override
|
||||
public MockHttpServletResponse postProcess(MockHttpServletResponse response)
|
||||
throws Exception {
|
||||
String modifiedContent = modifyContent(response.getContentAsString());
|
||||
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(MockHttpServletResponse.class);
|
||||
enhancer.setCallback(new ContentModifyingMethodInterceptor(modifiedContent,
|
||||
response));
|
||||
|
||||
return (MockHttpServletResponse) enhancer.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a modified version of the given {@code originalContent}
|
||||
*
|
||||
* @param originalContent the content to modify
|
||||
* @return the modified content
|
||||
* @throws Exception if a failure occurs while modifying the content
|
||||
*/
|
||||
protected abstract String modifyContent(String originalContent) throws Exception;
|
||||
|
||||
private static class ContentModifyingMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private final Method getContentAsStringMethod = findMethod("getContentAsString");
|
||||
|
||||
private final Method getContentAsByteArray = findMethod("getContentAsByteArray");
|
||||
|
||||
private final String modifiedContent;
|
||||
|
||||
private final MockHttpServletResponse delegate;
|
||||
|
||||
private ContentModifyingMethodInterceptor(String modifiedContent,
|
||||
MockHttpServletResponse delegate) {
|
||||
this.modifiedContent = modifiedContent;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args,
|
||||
MethodProxy methodProxy) throws IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
if (this.getContentAsStringMethod.equals(method)) {
|
||||
return this.modifiedContent;
|
||||
}
|
||||
if (this.getContentAsByteArray.equals(method)) {
|
||||
return this.modifiedContent.getBytes();
|
||||
}
|
||||
return method.invoke(this.delegate, args);
|
||||
}
|
||||
|
||||
private static Method findMethod(String methodName) {
|
||||
return BridgeMethodResolver.findBridgedMethod(ReflectionUtils.findMethod(
|
||||
MockHttpServletResponse.class, methodName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* A {@link ResponsePostProcessor} that removes headers from the response
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class HeaderRemovingResponsePostProcessor implements ResponsePostProcessor {
|
||||
|
||||
private final Set<String> headersToRemove;
|
||||
|
||||
HeaderRemovingResponsePostProcessor(String... headersToRemove) {
|
||||
this.headersToRemove = new HashSet<>(Arrays.asList(headersToRemove));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MockHttpServletResponse postProcess(final MockHttpServletResponse response) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(MockHttpServletResponse.class);
|
||||
enhancer.setCallback(new HeaderHidingMethodInterceptor(this.headersToRemove,
|
||||
response));
|
||||
|
||||
return (MockHttpServletResponse) enhancer.create();
|
||||
}
|
||||
|
||||
private static final class HeaderHidingMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private final MockHttpServletResponse response;
|
||||
|
||||
private final List<Method> interceptedMethods = Arrays.asList(
|
||||
findHeaderMethod("containsHeader", String.class),
|
||||
findHeaderMethod("getHeader", String.class),
|
||||
findHeaderMethod("getHeaderValue", String.class),
|
||||
findHeaderMethod("getHeaders", String.class),
|
||||
findHeaderMethod("getHeaderValues", String.class));
|
||||
|
||||
private final Method getHeaderNamesMethod = findHeaderMethod("getHeaderNames");
|
||||
|
||||
private final Set<String> hiddenHeaders;
|
||||
|
||||
private HeaderHidingMethodInterceptor(Set<String> hiddenHeaders,
|
||||
MockHttpServletResponse response) {
|
||||
this.hiddenHeaders = hiddenHeaders;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object proxy, Method method, Object[] args,
|
||||
MethodProxy methodProxy) throws IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
if (this.getHeaderNamesMethod.equals(method)) {
|
||||
List<String> headerNames = new ArrayList<>();
|
||||
for (String candidate : this.response.getHeaderNames()) {
|
||||
if (!isHiddenHeader(candidate)) {
|
||||
headerNames.add(candidate);
|
||||
}
|
||||
}
|
||||
return headerNames;
|
||||
}
|
||||
if (this.interceptedMethods.contains(method) && isHiddenHeader(args)) {
|
||||
if (method.getReturnType().equals(boolean.class)) {
|
||||
return false;
|
||||
}
|
||||
else if (Collection.class.isAssignableFrom(method.getReturnType())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return method.invoke(this.response, args);
|
||||
}
|
||||
|
||||
private boolean isHiddenHeader(Object[] args) {
|
||||
if (args.length == 1 && args[0] instanceof String) {
|
||||
return isHiddenHeader((String) args[0]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isHiddenHeader(String headerName) {
|
||||
for (String hiddenHeader : this.hiddenHeaders) {
|
||||
if (hiddenHeader.equalsIgnoreCase(headerName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Method findHeaderMethod(String methodName, Class<?>... args) {
|
||||
Method candidate = ReflectionUtils.findMethod(MockHttpServletResponse.class,
|
||||
methodName, args);
|
||||
if (candidate.isBridge()) {
|
||||
return BridgeMethodResolver.findBridgedMethod(candidate);
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Static factory methods for accessing various {@link ResponsePostProcessor
|
||||
* ResponsePostProcessors}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
public abstract class ResponsePostProcessors {
|
||||
|
||||
private ResponsePostProcessors() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResponsePostProcessor} that will pretty print the content of the
|
||||
* response.
|
||||
*
|
||||
* @return the response post-processor
|
||||
*/
|
||||
public static ResponsePostProcessor prettyPrintContent() {
|
||||
return new PrettyPrintingResponsePostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResponsePostProcessor} that will remove the headers with the given
|
||||
* {@code headerNames} from the response.
|
||||
*
|
||||
* @param headerNames the name of the headers to remove
|
||||
* @return the response post-processor
|
||||
*/
|
||||
public static ResponsePostProcessor removeHeaders(String... headerNames) {
|
||||
return new HeaderRemovingResponsePostProcessor(headerNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResponsePostProcessor} that will update the content of the
|
||||
* response to mask any links that it contains. Each link is masked my replacing its
|
||||
* {@code href} with {@code ...}.
|
||||
*
|
||||
* @return the response post-processor
|
||||
*/
|
||||
public static ResponsePostProcessor maskLinks() {
|
||||
return new LinkMaskingResponsePostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResponsePostProcessor} that will update the content of the
|
||||
* response to mask any links that it contains. Each link is masked my replacing its
|
||||
* {@code href} with the given {@code mask}.
|
||||
*
|
||||
* @param mask the mask to apply
|
||||
* @return the response post-processor
|
||||
*/
|
||||
public static ResponsePostProcessor maskLinksWith(String mask) {
|
||||
return new LinkMaskingResponsePostProcessor(mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResponsePostProcessor} that will update the content of the
|
||||
* response by replacing any occurrences of the given {@code pattern} with the given
|
||||
* {@code replacement}.
|
||||
*
|
||||
* @param pattern the pattern to match
|
||||
* @param replacement the replacement to apply
|
||||
* @return the response post-processor
|
||||
*/
|
||||
public static ResponsePostProcessor replacePattern(Pattern pattern, String replacement) {
|
||||
return new PatternReplacingResponsePostProcessor(pattern, replacement);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.springframework.restdocs.test.StubMvcResult.result;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.restdocs.ResponseModifier.ResponseModifyingRestDocumentationResultHandler;
|
||||
import org.springframework.restdocs.response.ResponsePostProcessor;
|
||||
|
||||
/**
|
||||
* Tests for {@link ResponseModifier}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class ResponseModifierTests {
|
||||
|
||||
@Test
|
||||
public void postProcessorsAreApplied() throws Exception {
|
||||
ResponsePostProcessor first = mock(ResponsePostProcessor.class);
|
||||
ResponsePostProcessor second = mock(ResponsePostProcessor.class);
|
||||
|
||||
MockHttpServletResponse original = new MockHttpServletResponse();
|
||||
MockHttpServletResponse afterFirst = new MockHttpServletResponse();
|
||||
MockHttpServletResponse afterSecond = new MockHttpServletResponse();
|
||||
|
||||
given(first.postProcess(original)).willReturn(afterFirst);
|
||||
given(second.postProcess(afterFirst)).willReturn(afterSecond);
|
||||
|
||||
RestDocumentationResultHandler resultHandler = new ResponseModifier(first, second)
|
||||
.andDocument("test");
|
||||
assertThat(
|
||||
afterSecond,
|
||||
is(equalTo(((ResponseModifyingRestDocumentationResultHandler) resultHandler)
|
||||
.postProcessResponse(result(original)).getResponse())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,23 +21,25 @@ import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.restdocs.RestDocumentation.document;
|
||||
import static org.springframework.restdocs.RestDocumentation.modifyResponseTo;
|
||||
import static org.springframework.restdocs.RestDocumentationRequestBuilders.get;
|
||||
import static org.springframework.restdocs.curl.CurlDocumentation.curlRequest;
|
||||
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
|
||||
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.maskLinks;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.replacePattern;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
||||
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
||||
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
|
||||
import static org.springframework.restdocs.response.ResponsePostProcessors.maskLinks;
|
||||
import static org.springframework.restdocs.response.ResponsePostProcessors.prettyPrintContent;
|
||||
import static org.springframework.restdocs.response.ResponsePostProcessors.removeHeaders;
|
||||
import static org.springframework.restdocs.response.ResponsePostProcessors.replacePattern;
|
||||
import static org.springframework.restdocs.snippet.Attributes.attributes;
|
||||
import static org.springframework.restdocs.snippet.Attributes.key;
|
||||
import static org.springframework.restdocs.test.SnippetMatchers.httpRequest;
|
||||
import static org.springframework.restdocs.test.SnippetMatchers.httpResponse;
|
||||
import static org.springframework.restdocs.test.SnippetMatchers.snippet;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
@@ -71,6 +73,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
@@ -236,15 +239,62 @@ public class RestDocumentationIntegrationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postProcessedResponse() throws Exception {
|
||||
public void preprocessedRequest() throws Exception {
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
|
||||
.apply(new RestDocumentationConfigurer()).build();
|
||||
|
||||
mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk()).andDo(document("original"));
|
||||
Pattern pattern = Pattern.compile("(\"alpha\")");
|
||||
|
||||
mockMvc.perform(
|
||||
get("/").header("a", "alpha").header("b", "bravo")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON).content("{\"a\":\"alpha\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("original-request"))
|
||||
.andDo(document(
|
||||
"preprocessed-request",
|
||||
preprocessRequest(prettyPrint(), removeHeaders("a"),
|
||||
replacePattern(pattern, "\"<<beta>>\""))));
|
||||
|
||||
assertThat(
|
||||
new File("build/generated-snippets/original/http-response.adoc"),
|
||||
new File("build/generated-snippets/original-request/http-request.adoc"),
|
||||
is(snippet().withContents(
|
||||
httpRequest(RequestMethod.GET, "/").header("Host", "localhost")
|
||||
.header("a", "alpha").header("b", "bravo")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", MediaType.APPLICATION_JSON_VALUE)
|
||||
.header("Content-Length", "13")
|
||||
.content("{\"a\":\"alpha\"}"))));
|
||||
assertThat(
|
||||
new File(
|
||||
"build/generated-snippets/preprocessed-request/http-request.adoc"),
|
||||
is(snippet().withContents(
|
||||
httpRequest(RequestMethod.GET, "/").header("Host", "localhost")
|
||||
.header("b", "bravo")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", MediaType.APPLICATION_JSON_VALUE)
|
||||
.header("Content-Length", "22")
|
||||
.content(String.format("{%n \"a\" : \"<<beta>>\"%n}")))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preprocessedResponse() throws Exception {
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
|
||||
.apply(new RestDocumentationConfigurer()).build();
|
||||
|
||||
Pattern pattern = Pattern.compile("(\"alpha\")");
|
||||
|
||||
mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(document("original-response"))
|
||||
.andDo(document(
|
||||
"preprocessed-response",
|
||||
preprocessResponse(prettyPrint(), maskLinks(),
|
||||
removeHeaders("a"),
|
||||
replacePattern(pattern, "\"<<beta>>\""))));
|
||||
|
||||
assertThat(
|
||||
new File("build/generated-snippets/original-response/http-response.adoc"),
|
||||
is(snippet().withContents(
|
||||
httpResponse(HttpStatus.OK)
|
||||
.header("a", "alpha")
|
||||
@@ -252,16 +302,9 @@ public class RestDocumentationIntegrationTests {
|
||||
.content(
|
||||
"{\"a\":\"alpha\",\"links\":[{\"rel\":\"rel\","
|
||||
+ "\"href\":\"href\"}]}"))));
|
||||
|
||||
Pattern pattern = Pattern.compile("(\"alpha\")");
|
||||
mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(modifyResponseTo(prettyPrintContent(), removeHeaders("a"),
|
||||
replacePattern(pattern, "\"<<beta>>\""), maskLinks())
|
||||
.andDocument("post-processed"));
|
||||
|
||||
assertThat(
|
||||
new File("build/generated-snippets/post-processed/http-response.adoc"),
|
||||
new File(
|
||||
"build/generated-snippets/preprocessed-response/http-response.adoc"),
|
||||
is(snippet().withContents(
|
||||
httpResponse(HttpStatus.OK).header("Content-Type",
|
||||
"application/json").content(
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationRequestPart;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.restdocs.operation.Parameters;
|
||||
import org.springframework.restdocs.operation.StandardOperationRequest;
|
||||
import org.springframework.restdocs.operation.StandardOperationResponse;
|
||||
|
||||
/**
|
||||
* Tests for {@link ContentModifyingOperationPreprocessor}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class ContentModifyingOperationPreprocessorTests {
|
||||
|
||||
private final ContentModifyingOperationPreprocessor preprocessor = new ContentModifyingOperationPreprocessor(
|
||||
new ContentModifier() {
|
||||
|
||||
@Override
|
||||
public byte[] modifyContent(byte[] originalContent) {
|
||||
return "modified".getBytes();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Test
|
||||
public void modifyRequestContent() {
|
||||
StandardOperationRequest request = new StandardOperationRequest(
|
||||
URI.create("http://localhost"), HttpMethod.GET, "content".getBytes(),
|
||||
new HttpHeaders(), new Parameters(),
|
||||
Collections.<OperationRequestPart> emptyList());
|
||||
OperationRequest preprocessed = this.preprocessor.preprocess(request);
|
||||
assertThat(preprocessed.getContent(), is(equalTo("modified".getBytes())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResponseContent() {
|
||||
StandardOperationResponse response = new StandardOperationResponse(HttpStatus.OK,
|
||||
new HttpHeaders(), "content".getBytes());
|
||||
OperationResponse preprocessed = this.preprocessor.preprocess(response);
|
||||
assertThat(preprocessed.getContent(), is(equalTo("modified".getBytes())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownContentLengthIsUnchanged() {
|
||||
StandardOperationRequest request = new StandardOperationRequest(
|
||||
URI.create("http://localhost"), HttpMethod.GET, "content".getBytes(),
|
||||
new HttpHeaders(), new Parameters(),
|
||||
Collections.<OperationRequestPart> emptyList());
|
||||
OperationRequest preprocessed = this.preprocessor.preprocess(request);
|
||||
assertThat(preprocessed.getHeaders().getContentLength(), is(equalTo(-1L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthIsUpdated() {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.setContentLength(7);
|
||||
StandardOperationRequest request = new StandardOperationRequest(
|
||||
URI.create("http://localhost"), HttpMethod.GET, "content".getBytes(),
|
||||
httpHeaders, new Parameters(),
|
||||
Collections.<OperationRequestPart> emptyList());
|
||||
OperationRequest preprocessed = this.preprocessor.preprocess(request);
|
||||
assertThat(preprocessed.getHeaders().getContentLength(), is(equalTo(8L)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.hasEntry;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
import org.springframework.restdocs.operation.OperationRequestPart;
|
||||
import org.springframework.restdocs.operation.OperationResponse;
|
||||
import org.springframework.restdocs.operation.Parameters;
|
||||
import org.springframework.restdocs.operation.StandardOperationRequest;
|
||||
import org.springframework.restdocs.operation.StandardOperationResponse;
|
||||
|
||||
/**
|
||||
* Tests for {@link HeaderRemovingOperationPreprocessorTests}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class HeaderRemovingOperationPreprocessorTests {
|
||||
|
||||
private final HeaderRemovingOperationPreprocessor preprocessor = new HeaderRemovingOperationPreprocessor(
|
||||
"b");
|
||||
|
||||
@Test
|
||||
public void modifyRequestHeaders() {
|
||||
StandardOperationRequest request = new StandardOperationRequest(
|
||||
URI.create("http://localhost"), HttpMethod.GET, new byte[0],
|
||||
getHttpHeaders(), new Parameters(),
|
||||
Collections.<OperationRequestPart> emptyList());
|
||||
OperationRequest preprocessed = this.preprocessor.preprocess(request);
|
||||
assertThat(preprocessed.getHeaders().size(), is(equalTo(1)));
|
||||
assertThat(preprocessed.getHeaders(), hasEntry("a", Arrays.asList("alpha")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResponseHeaders() {
|
||||
StandardOperationResponse response = new StandardOperationResponse(HttpStatus.OK,
|
||||
getHttpHeaders(), new byte[0]);
|
||||
OperationResponse preprocessed = this.preprocessor.preprocess(response);
|
||||
assertThat(preprocessed.getHeaders().size(), is(equalTo(1)));
|
||||
assertThat(preprocessed.getHeaders(), hasEntry("a", Arrays.asList("alpha")));
|
||||
}
|
||||
|
||||
private HttpHeaders getHttpHeaders() {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add("a", "alpha");
|
||||
httpHeaders.add("b", "bravo");
|
||||
httpHeaders.add("b", "banana");
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +1,4 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
@@ -34,9 +18,15 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
|
||||
public class LinkMaskingResponsePostProcessorTests {
|
||||
/**
|
||||
* Tests for {@link LinkMaskingContentModifier}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class LinkMaskingContentModifierTests {
|
||||
|
||||
private final LinkMaskingResponsePostProcessor postProcessor = new LinkMaskingResponsePostProcessor();
|
||||
private final ContentModifier contentModifier = new LinkMaskingContentModifier();
|
||||
|
||||
private final Link[] links = new Link[] { new Link("a", "alpha"),
|
||||
new Link("b", "bravo") };
|
||||
@@ -46,28 +36,28 @@ public class LinkMaskingResponsePostProcessorTests {
|
||||
|
||||
@Test
|
||||
public void halLinksAreMasked() throws Exception {
|
||||
assertThat(this.postProcessor.modifyContent(halPayloadWithLinks(this.links)),
|
||||
assertThat(this.contentModifier.modifyContent(halPayloadWithLinks(this.links)),
|
||||
is(equalTo(halPayloadWithLinks(this.maskedLinks))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formattedHalLinksAreMasked() throws Exception {
|
||||
assertThat(
|
||||
this.postProcessor
|
||||
this.contentModifier
|
||||
.modifyContent(formattedHalPayloadWithLinks(this.links)),
|
||||
is(equalTo(formattedHalPayloadWithLinks(this.maskedLinks))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void atomLinksAreMasked() throws Exception {
|
||||
assertThat(this.postProcessor.modifyContent(atomPayloadWithLinks(this.links)),
|
||||
assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links)),
|
||||
is(equalTo(atomPayloadWithLinks(this.maskedLinks))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formattedAtomLinksAreMasked() throws Exception {
|
||||
assertThat(
|
||||
this.postProcessor
|
||||
this.contentModifier
|
||||
.modifyContent(formattedAtomPayloadWithLinks(this.links)),
|
||||
is(equalTo(formattedAtomPayloadWithLinks(this.maskedLinks))));
|
||||
}
|
||||
@@ -75,20 +65,20 @@ public class LinkMaskingResponsePostProcessorTests {
|
||||
@Test
|
||||
public void maskCanBeCustomized() throws Exception {
|
||||
assertThat(
|
||||
new LinkMaskingResponsePostProcessor("custom")
|
||||
new LinkMaskingContentModifier("custom")
|
||||
.modifyContent(formattedAtomPayloadWithLinks(this.links)),
|
||||
is(equalTo(formattedAtomPayloadWithLinks(new Link("a", "custom"),
|
||||
new Link("b", "custom")))));
|
||||
}
|
||||
|
||||
private String atomPayloadWithLinks(Link... links) throws JsonProcessingException {
|
||||
return new ObjectMapper().writeValueAsString(createAtomPayload(links));
|
||||
private byte[] atomPayloadWithLinks(Link... links) throws JsonProcessingException {
|
||||
return new ObjectMapper().writeValueAsBytes(createAtomPayload(links));
|
||||
}
|
||||
|
||||
private String formattedAtomPayloadWithLinks(Link... links)
|
||||
private byte[] formattedAtomPayloadWithLinks(Link... links)
|
||||
throws JsonProcessingException {
|
||||
return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
.writeValueAsString(createAtomPayload(links));
|
||||
.writeValueAsBytes(createAtomPayload(links));
|
||||
}
|
||||
|
||||
private AtomPayload createAtomPayload(Link... links) {
|
||||
@@ -97,14 +87,14 @@ public class LinkMaskingResponsePostProcessorTests {
|
||||
return payload;
|
||||
}
|
||||
|
||||
private String halPayloadWithLinks(Link... links) throws JsonProcessingException {
|
||||
return new ObjectMapper().writeValueAsString(createHalPayload(links));
|
||||
private byte[] halPayloadWithLinks(Link... links) throws JsonProcessingException {
|
||||
return new ObjectMapper().writeValueAsBytes(createHalPayload(links));
|
||||
}
|
||||
|
||||
private String formattedHalPayloadWithLinks(Link... links)
|
||||
private byte[] formattedHalPayloadWithLinks(Link... links)
|
||||
throws JsonProcessingException {
|
||||
return new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
.writeValueAsString(createHalPayload(links));
|
||||
.writeValueAsBytes(createHalPayload(links));
|
||||
}
|
||||
|
||||
private HalPayload createHalPayload(Link... links) {
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link PatternReplacingContentModifier}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class PatternReplacingContentModifierTests {
|
||||
|
||||
@Test
|
||||
public void patternsAreReplaced() throws Exception {
|
||||
Pattern pattern = Pattern.compile(
|
||||
"([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(
|
||||
pattern, "<<uuid>>");
|
||||
assertThat(
|
||||
contentModifier.modifyContent("{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}"
|
||||
.getBytes()), is(equalTo("{\"id\" : \"<<uuid>>\"}".getBytes())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
package org.springframework.restdocs.operation.preprocess;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -22,38 +22,40 @@ import static org.junit.Assert.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link PrettyPrintingResponsePostProcessor}
|
||||
* Tests for {@link PrettyPrintingContentModifier}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class PrettyPrintingResponsePostProcessorTests {
|
||||
public class PrettyPrintingContentModifierTests {
|
||||
|
||||
@Test
|
||||
public void prettyPrintJson() throws Exception {
|
||||
assertThat(new PrettyPrintingResponsePostProcessor().modifyContent("{\"a\":5}"),
|
||||
equalTo(String.format("{%n \"a\" : 5%n}")));
|
||||
assertThat(
|
||||
new PrettyPrintingContentModifier().modifyContent("{\"a\":5}".getBytes()),
|
||||
equalTo(String.format("{%n \"a\" : 5%n}").getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prettyPrintXml() throws Exception {
|
||||
assertThat(
|
||||
new PrettyPrintingResponsePostProcessor()
|
||||
.modifyContent("<one a=\"alpha\"><two b=\"bravo\"/></one>"),
|
||||
equalTo(String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n"
|
||||
+ "<one a=\"alpha\">%n <two b=\"bravo\"/>%n</one>%n")));
|
||||
new PrettyPrintingContentModifier().modifyContent("<one a=\"alpha\"><two b=\"bravo\"/></one>"
|
||||
.getBytes()), equalTo(String.format(
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n"
|
||||
+ "<one a=\"alpha\">%n <two b=\"bravo\"/>%n</one>%n")
|
||||
.getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void empytContentIsHandledGracefully() throws Exception {
|
||||
assertThat(new PrettyPrintingResponsePostProcessor().modifyContent(""),
|
||||
equalTo(""));
|
||||
assertThat(new PrettyPrintingContentModifier().modifyContent("".getBytes()),
|
||||
equalTo("".getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonJsonAndNonXmlContentIsHandledGracefully() throws Exception {
|
||||
String content = "abcdefg";
|
||||
assertThat(new PrettyPrintingResponsePostProcessor().modifyContent(content),
|
||||
equalTo(content));
|
||||
assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes()),
|
||||
equalTo(content.getBytes()));
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
public class ContentModifyingResponsePostProcessorTests {
|
||||
|
||||
private final MockHttpServletResponse original = new MockHttpServletResponse();
|
||||
|
||||
private final ContentModifyingReponsePostProcessor postProcessor = new TestContentModifyingResponsePostProcessor();
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void contentCanBeModified() throws Exception {
|
||||
MockHttpServletResponse modified = this.postProcessor.postProcess(this.original);
|
||||
assertThat(modified.getContentAsString(), is(equalTo("modified")));
|
||||
assertThat(modified.getContentAsByteArray(), is(equalTo("modified".getBytes())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonContentMethodsAreDelegated() throws Exception {
|
||||
this.original.addHeader("a", "alpha");
|
||||
MockHttpServletResponse modified = this.postProcessor.postProcess(this.original);
|
||||
assertThat(modified.getHeader("a"), is(equalTo("alpha")));
|
||||
}
|
||||
|
||||
private static final class TestContentModifyingResponsePostProcessor extends
|
||||
ContentModifyingReponsePostProcessor {
|
||||
|
||||
@Override
|
||||
protected String modifyContent(String originalContent) throws Exception {
|
||||
return "modified";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
/**
|
||||
* Tests for {@link HeaderRemovingResponsePostProcessor}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class HeaderRemovingResponsePostProcessorTests {
|
||||
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@Before
|
||||
public void configureResponse() {
|
||||
this.response.addHeader("a", "alpha");
|
||||
this.response.addHeader("b", "bravo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void containsHeaderHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.containsHeader("a"), is(false));
|
||||
assertThat(response.containsHeader("b"), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeaderNamesHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.getHeaderNames(), contains("b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeaderHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.getHeader("a"), is(nullValue()));
|
||||
assertThat(response.getHeader("b"), is("bravo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeadersHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.getHeaders("a"), is(empty()));
|
||||
assertThat(response.getHeaders("b"), contains("bravo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeaderValueHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.getHeaderValue("a"), is(nullValue()));
|
||||
assertThat(response.getHeaderValue("b"), is((Object) "bravo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHeaderValuesHonoursRemovedHeaders() {
|
||||
MockHttpServletResponse response = removeHeaders("a");
|
||||
assertThat(response.getHeaderValues("a"), is(empty()));
|
||||
assertThat(response.getHeaderValues("b"), contains((Object) "bravo"));
|
||||
}
|
||||
|
||||
private MockHttpServletResponse removeHeaders(String... headerNames) {
|
||||
return new HeaderRemovingResponsePostProcessor(headerNames)
|
||||
.postProcess(this.response);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-2015 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.response;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link PatternReplacingResponsePostProcessor}.
|
||||
*
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
public class PatternReplacingResponsePostProcessorTests {
|
||||
|
||||
@Test
|
||||
public void patternsAreReplaced() throws Exception {
|
||||
Pattern pattern = Pattern.compile(
|
||||
"([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
PatternReplacingResponsePostProcessor postProcessor = new PatternReplacingResponsePostProcessor(
|
||||
pattern, "<<uuid>>");
|
||||
assertThat(
|
||||
postProcessor
|
||||
.modifyContent("{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}"),
|
||||
is(equalTo("{\"id\" : \"<<uuid>>\"}")));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user