Add a response post processor that performs generic pattern replacement
This commit introduces a new ResponsePostProcessor, PatternReplacingResponsePostProcessor, that modifies the content of the response by replacing occurrences of a regular expression with a configurable replacement. The existing LinkMaskingResponsePostProcessor, which was already performing pattern replacement, has been updated to subclass PatternReplacingResponsePostProcessor. Closes gh-65
This commit is contained in:
committed by
Andy Wilkinson
parent
ca375c919c
commit
84fe379f64
@@ -16,40 +16,28 @@
|
||||
|
||||
package org.springframework.restdocs.response;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
class LinkMaskingResponsePostProcessor extends ContentModifyingReponsePostProcessor {
|
||||
/**
|
||||
* A {@link ResponsePostProcessor} that modifies the content of a hypermedia response to
|
||||
* mask the hrefs of any links.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
class LinkMaskingResponsePostProcessor extends PatternReplacingResponsePostProcessor {
|
||||
|
||||
private static final String DEFAULT_MASK = "...";
|
||||
|
||||
private static final Pattern LINK_HREF = Pattern.compile(
|
||||
"\"href\"\\s*:\\s*\"(.*?)\"", Pattern.DOTALL);
|
||||
|
||||
private final String mask;
|
||||
|
||||
LinkMaskingResponsePostProcessor() {
|
||||
this(DEFAULT_MASK);
|
||||
super(LINK_HREF, DEFAULT_MASK);
|
||||
}
|
||||
|
||||
LinkMaskingResponsePostProcessor(String mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String modifyContent(String originalContent) {
|
||||
Matcher matcher = LINK_HREF.matcher(originalContent);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
int previous = 0;
|
||||
while (matcher.find()) {
|
||||
buffer.append(originalContent.substring(previous, matcher.start(1)));
|
||||
buffer.append(this.mask);
|
||||
previous = matcher.end(1);
|
||||
}
|
||||
if (previous < originalContent.length()) {
|
||||
buffer.append(originalContent.substring(previous));
|
||||
}
|
||||
return buffer.toString();
|
||||
super(LINK_HREF, mask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.response;
|
||||
|
||||
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}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
class PatternReplacingResponsePostProcessor extends ContentModifyingReponsePostProcessor {
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
private final String replacement;
|
||||
|
||||
PatternReplacingResponsePostProcessor(Pattern pattern, String replacement) {
|
||||
this.pattern = pattern;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String modifyContent(String originalContent) {
|
||||
Matcher matcher = this.pattern.matcher(originalContent);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
int previous = 0;
|
||||
while (matcher.find()) {
|
||||
buffer.append(originalContent.substring(previous, matcher.start(1)));
|
||||
buffer.append(this.replacement);
|
||||
previous = matcher.end(1);
|
||||
}
|
||||
if (previous < originalContent.length()) {
|
||||
buffer.append(originalContent.substring(previous));
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
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 {
|
||||
|
||||
@@ -71,4 +74,18 @@ public abstract class ResponsePostProcessors {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static org.springframework.restdocs.RestDocumentation.modifyResponseTo;
|
||||
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.test.SnippetMatchers.httpResponse;
|
||||
import static org.springframework.restdocs.test.SnippetMatchers.snippet;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
@@ -33,6 +34,7 @@ import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -64,6 +66,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
|
||||
* Integration tests for Spring REST Docs
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Dewet Diener
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@@ -155,17 +158,19 @@ public class RestDocumentationIntegrationTests {
|
||||
"{\"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"),
|
||||
maskLinks()).andDocument("post-processed"));
|
||||
replacePattern(pattern, "\"<<beta>>\""), maskLinks())
|
||||
.andDocument("post-processed"));
|
||||
|
||||
assertThat(
|
||||
new File("build/generated-snippets/post-processed/http-response.adoc"),
|
||||
is(snippet().withContents(
|
||||
httpResponse(HttpStatus.OK).header("Content-Type",
|
||||
"application/json").content(
|
||||
String.format("{%n \"a\" : \"alpha\",%n \"links\" :"
|
||||
String.format("{%n \"a\" : \"<<beta>>\",%n \"links\" :"
|
||||
+ " [ {%n \"rel\" : \"rel\",%n \"href\" :"
|
||||
+ " \"...\"%n } ]%n}")))));
|
||||
}
|
||||
|
||||
@@ -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.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