Honour Content-Type charset whenever content is turned into a String

This commit builds on the changes made in the previous commit to
make wider use of the new getContentAsString methods on
OperationRequest and OperationResponse. It also adds such a method to
OperationRequestPart. Any code that previously got the content as a
byte array and then created a String has been updated to either use
getContentAsString or to use the charset from the Content-Type header
when creating a String.

See gh-126
This commit is contained in:
Andy Wilkinson
2015-09-23 17:05:26 +01:00
parent 9b31c0ce9b
commit 3f6d4b9639
22 changed files with 202 additions and 198 deletions

View File

@@ -80,7 +80,6 @@ public class CurlRequestSnippet extends TemplatedSnippet {
writeHttpMethodIfNecessary(operation.getRequest(), printer);
writeHeaders(headers, printer);
writePartsIfNecessary(operation.getRequest(), printer);
writeContent(operation.getRequest(), printer);
return command.toString();
@@ -126,7 +125,7 @@ public class CurlRequestSnippet extends TemplatedSnippet {
for (OperationRequestPart part : request.getParts()) {
writer.printf(" -F '%s=", part.getName());
if (!StringUtils.hasText(part.getSubmittedFileName())) {
writer.append(new String(part.getContent()));
writer.append(part.getContentAsString());
}
else {
writer.printf("@%s", part.getSubmittedFileName());
@@ -141,8 +140,9 @@ public class CurlRequestSnippet extends TemplatedSnippet {
}
private void writeContent(OperationRequest request, PrintWriter writer) {
if (request.getContent().length > 0) {
writer.print(String.format(" -d '%s'", new String(request.getContent())));
String content = request.getContentAsString();
if (StringUtils.hasText(content)) {
writer.print(String.format(" -d '%s'", content));
}
else if (!request.getParts().isEmpty()) {
for (Entry<String, List<String>> entry : request.getParameters().entrySet()) {

View File

@@ -16,7 +16,6 @@
package org.springframework.restdocs.http;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -31,7 +30,6 @@ import org.springframework.http.MediaType;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.operation.OperationRequest;
import org.springframework.restdocs.operation.OperationRequestPart;
import org.springframework.restdocs.snippet.ModelCreationException;
import org.springframework.restdocs.snippet.Snippet;
import org.springframework.restdocs.snippet.TemplatedSnippet;
import org.springframework.util.StringUtils;
@@ -108,8 +106,9 @@ public class HttpRequestSnippet extends TemplatedSnippet {
private String getRequestBody(OperationRequest request) {
StringWriter httpRequest = new StringWriter();
PrintWriter writer = new PrintWriter(httpRequest);
if (request.getContent().length > 0) {
writer.print(requestBody(request));
String content = request.getContentAsString();
if (StringUtils.hasText(content)) {
writer.printf("%n%s", content);
}
else if (isPutOrPost(request)) {
if (request.getParts().isEmpty()) {
@@ -126,16 +125,6 @@ public class HttpRequestSnippet extends TemplatedSnippet {
return httpRequest.toString();
}
private String requestBody(OperationRequest request) {
try {
String content = request.getContentAsString();
return content.isEmpty() ? content : String.format("%n%s", content);
}
catch (IOException e) {
throw new ModelCreationException("Failed to create response body.", e);
}
}
private boolean isPutOrPost(OperationRequest request) {
return HttpMethod.PUT.equals(request.getMethod())
|| HttpMethod.POST.equals(request.getMethod());
@@ -163,7 +152,7 @@ public class HttpRequestSnippet extends TemplatedSnippet {
}
private void writePart(OperationRequestPart part, PrintWriter writer) {
writePart(part.getName(), new String(part.getContent()), part.getHeaders()
writePart(part.getName(), part.getContentAsString(), part.getHeaders()
.getContentType(), writer);
}

View File

@@ -16,7 +16,6 @@
package org.springframework.restdocs.http;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -26,7 +25,6 @@ import java.util.Map.Entry;
import org.springframework.http.HttpStatus;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.operation.OperationResponse;
import org.springframework.restdocs.snippet.ModelCreationException;
import org.springframework.restdocs.snippet.Snippet;
import org.springframework.restdocs.snippet.TemplatedSnippet;
@@ -69,13 +67,8 @@ public class HttpResponseSnippet extends TemplatedSnippet {
}
private String responseBody(OperationResponse response) {
try {
String content = response.getContentAsString();
return content.isEmpty() ? content : String.format("%n%s", content);
}
catch (IOException e) {
throw new ModelCreationException("Failed to create response body.", e);
}
String content = response.getContentAsString();
return content.isEmpty() ? content : String.format("%n%s", content);
}
private List<Map<String, String>> headers(OperationResponse response) {

View File

@@ -38,7 +38,7 @@ abstract class AbstractJsonLinkExtractor implements LinkExtractor {
public Map<String, List<Link>> extractLinks(OperationResponse response)
throws IOException {
Map<String, Object> jsonContent = this.objectMapper.readValue(
new String(response.getContent()), Map.class);
response.getContent(), Map.class);
return extractLinks(jsonContent);
}

View File

@@ -0,0 +1,69 @@
/*
* 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;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
/**
* Abstract base class for operation requests, request parts, and responses.
*
* @author Andy Wilkinson
*/
abstract class AbstractOperationMessage {
private final byte[] content;
private final HttpHeaders headers;
AbstractOperationMessage(byte[] content, HttpHeaders headers) {
this.content = content == null ? new byte[0] : content;
this.headers = headers;
}
public byte[] getContent() {
return Arrays.copyOf(this.content, this.content.length);
}
public HttpHeaders getHeaders() {
return HttpHeaders.readOnlyHttpHeaders(this.headers);
}
public String getContentAsString() {
if (this.content.length > 0) {
Charset charset = extractCharsetFromContentTypeHeader();
return charset != null ? new String(this.content, charset) : new String(
this.content);
}
return "";
}
private Charset extractCharsetFromContentTypeHeader() {
if (this.headers == null) {
return null;
}
MediaType contentType = this.headers.getContentType();
if (contentType == null) {
return null;
}
return contentType.getCharSet();
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.restdocs.operation;
import java.io.IOException;
import java.net.URI;
import java.util.Collection;
@@ -32,20 +31,22 @@ import org.springframework.http.HttpMethod;
public interface OperationRequest {
/**
* Returns the contents of the request. If the request has no content an empty array
* is returned.
* Returns the content of the request. If the request has no content an empty array is
* returned.
*
* @return the contents, never {@code null}
*/
byte[] getContent();
/**
* Returns the contents as string of the request. If the request has no content an empty string
* is returned
* Returns the content of the request as a {@link String}. If the request has no
* content an empty string is returned. If the request has a {@code Content-Type}
* header that specifies a charset then that charset will be used when converting the
* contents to a {@code String}.
*
* @return the contents as string, never {@code null}
* @throws IOException if an input or output exception occurred
*/
String getContentAsString() throws IOException;
String getContentAsString();
/**
* Returns the headers that were included in the request.

View File

@@ -47,6 +47,16 @@ public interface OperationRequestPart {
*/
byte[] getContent();
/**
* Returns the content of the part as a {@link String}. If the part has no content an
* empty string is returned. If the part has a {@code Content-Type} header that
* specifies a charset then that charset will be used when converting the contents to
* a {@code String}.
*
* @return the contents as string, never {@code null}
*/
String getContentAsString();
/**
* Returns the part's headers.
*

View File

@@ -16,8 +16,6 @@
package org.springframework.restdocs.operation;
import java.io.IOException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
@@ -45,7 +43,7 @@ public interface OperationResponse {
HttpHeaders getHeaders();
/**
* Returns the contents of the response. If the response has no content an empty array
* Returns the content of the response. If the response has no content an empty array
* is returned.
*
* @return the contents, never {@code null}
@@ -53,10 +51,13 @@ public interface OperationResponse {
byte[] getContent();
/**
* Returns the contents as string of the response. If the response has no content an empty string
* is returned
* Returns the content of the response as a {@link String}. If the response has no
* content an empty string is returned. If the response has a {@code Content-Type}
* header that specifies a charset then that charset will be used when converting the
* contents to a {@code String}.
*
* @return the contents as string, never {@code null}
* @throws IOException if an input or output exception occurred
*/
String getContentAsString() throws IOException;
String getContentAsString();
}

View File

@@ -16,28 +16,20 @@
package org.springframework.restdocs.operation;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
/**
* Standard implementation of {@link OperationRequest}.
*
* @author Andy Wilkinson
*/
public class StandardOperationRequest implements OperationRequest {
private byte[] content;
private String characterEncoding;
private HttpHeaders headers;
public class StandardOperationRequest extends AbstractOperationMessage implements
OperationRequest {
private HttpMethod method;
@@ -61,36 +53,13 @@ public class StandardOperationRequest implements OperationRequest {
public StandardOperationRequest(URI uri, HttpMethod method, byte[] content,
HttpHeaders headers, Parameters parameters,
Collection<OperationRequestPart> parts) {
super(content, headers);
this.uri = uri;
this.method = method;
this.content = content;
this.characterEncoding = detectCharsetFromContentTypeHeader(headers);
this.headers = headers;
this.parameters = parameters;
this.parts = parts;
}
@Override
public byte[] getContent() {
return Arrays.copyOf(this.content, this.content.length);
}
@Override
public String getContentAsString() throws UnsupportedEncodingException {
if (content.length > 0) {
return characterEncoding != null ?
new String(content, characterEncoding) : new String(content);
}
else {
return "";
}
}
@Override
public HttpHeaders getHeaders() {
return this.headers;
}
@Override
public HttpMethod getMethod() {
return this.method;
@@ -111,14 +80,4 @@ public class StandardOperationRequest implements OperationRequest {
return this.uri;
}
private String detectCharsetFromContentTypeHeader(HttpHeaders headers) {
if (headers == null) {
return null;
}
MediaType contentType = headers.getContentType();
if (contentType == null) {
return null;
}
return contentType.getParameter("charset");
}
}

View File

@@ -23,16 +23,13 @@ import org.springframework.http.HttpHeaders;
*
* @author Andy Wilkinson
*/
public class StandardOperationRequestPart implements OperationRequestPart {
public class StandardOperationRequestPart extends AbstractOperationMessage implements
OperationRequestPart {
private final String name;
private final String submittedFileName;
private final byte[] content;
private final HttpHeaders headers;
/**
* Creates a new {@code StandardOperationRequestPart} with the given {@code name}.
*
@@ -43,10 +40,9 @@ public class StandardOperationRequestPart implements OperationRequestPart {
*/
public StandardOperationRequestPart(String name, String submittedFileName,
byte[] content, HttpHeaders headers) {
super(content, headers);
this.name = name;
this.submittedFileName = submittedFileName;
this.content = content;
this.headers = headers;
}
@Override
@@ -59,14 +55,4 @@ public class StandardOperationRequestPart implements OperationRequestPart {
return this.submittedFileName;
}
@Override
public byte[] getContent() {
return this.content;
}
@Override
public HttpHeaders getHeaders() {
return this.headers;
}
}

View File

@@ -16,27 +16,19 @@
package org.springframework.restdocs.operation;
import java.io.UnsupportedEncodingException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
/**
* Standard implementation of {@link OperationResponse}.
*
* @author Andy Wilkinson
*/
public class StandardOperationResponse implements OperationResponse {
public class StandardOperationResponse extends AbstractOperationMessage implements
OperationResponse {
private final HttpStatus status;
private final HttpHeaders headers;
private final byte[] content;
private String characterEncoding;
/**
* Creates a new response with the given {@code status}, {@code headers}, and
* {@code content}.
@@ -47,10 +39,8 @@ public class StandardOperationResponse implements OperationResponse {
*/
public StandardOperationResponse(HttpStatus status, HttpHeaders headers,
byte[] content) {
super(content, headers);
this.status = status;
this.headers = headers;
this.content = content;
this.characterEncoding = detectCharsetFromContentTypeHeader(headers);
}
@Override
@@ -58,35 +48,4 @@ public class StandardOperationResponse implements OperationResponse {
return this.status;
}
@Override
public HttpHeaders getHeaders() {
return this.headers;
}
@Override
public byte[] getContent() {
return this.content;
}
@Override
public String getContentAsString() throws UnsupportedEncodingException {
if (content.length > 0) {
return characterEncoding != null ?
new String(content, characterEncoding) : new String(content);
}
else {
return "";
}
}
private String detectCharsetFromContentTypeHeader(HttpHeaders headers) {
if (headers == null) {
return null;
}
MediaType contentType = headers.getContentType();
if (contentType == null) {
return null;
}
return contentType.getParameter("charset");
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.restdocs.operation.preprocess;
import org.springframework.http.MediaType;
import org.springframework.restdocs.operation.OperationRequest;
import org.springframework.restdocs.operation.OperationResponse;
@@ -33,8 +34,9 @@ public interface ContentModifier {
* Returns modified content based on the given {@code originalContent}.
*
* @param originalContent the original content
* @param contentType the type of the original content, may be {@code null}
* @return the modified content
*/
byte[] modifyContent(byte[] originalContent);
byte[] modifyContent(byte[] originalContent, MediaType contentType);
}

View File

@@ -44,7 +44,8 @@ public class ContentModifyingOperationPreprocessor implements OperationPreproces
@Override
public OperationRequest preprocess(OperationRequest request) {
byte[] modifiedContent = this.contentModifier.modifyContent(request.getContent());
byte[] modifiedContent = this.contentModifier.modifyContent(request.getContent(),
request.getHeaders().getContentType());
return new StandardOperationRequest(request.getUri(), request.getMethod(),
modifiedContent,
getUpdatedHeaders(request.getHeaders(), modifiedContent),
@@ -53,8 +54,8 @@ public class ContentModifyingOperationPreprocessor implements OperationPreproces
@Override
public OperationResponse preprocess(OperationResponse response) {
byte[] modifiedContent = this.contentModifier
.modifyContent(response.getContent());
byte[] modifiedContent = this.contentModifier.modifyContent(
response.getContent(), response.getHeaders().getContentType());
return new StandardOperationResponse(response.getStatus(), getUpdatedHeaders(
response.getHeaders(), modifiedContent), modifiedContent);
}

View File

@@ -18,6 +18,8 @@ package org.springframework.restdocs.operation.preprocess;
import java.util.regex.Pattern;
import org.springframework.http.MediaType;
/**
* A content modifier the masks the {@code href} of any hypermedia links.
*
@@ -41,8 +43,8 @@ class LinkMaskingContentModifier implements ContentModifier {
}
@Override
public byte[] modifyContent(byte[] originalContent) {
return this.contentModifier.modifyContent(originalContent);
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
return this.contentModifier.modifyContent(originalContent, contentType);
}
}

View File

@@ -19,6 +19,8 @@ package org.springframework.restdocs.operation.preprocess;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.http.MediaType;
/**
* A {@link ContentModifier} that modifies the content by replacing occurrences of a
* regular expression {@link Pattern}.
@@ -45,15 +47,29 @@ class PatternReplacingContentModifier implements ContentModifier {
}
@Override
public byte[] modifyContent(byte[] content) {
String original = new String(content);
public byte[] modifyContent(byte[] content, MediaType contentType) {
String original;
if (contentType != null && contentType.getCharSet() != null) {
original = new String(content, contentType.getCharSet());
}
else {
original = new String(content);
}
Matcher matcher = this.pattern.matcher(original);
StringBuilder buffer = new StringBuilder();
int previous = 0;
while (matcher.find()) {
buffer.append(original.substring(previous, matcher.start(1)));
String prefix;
if (matcher.groupCount() > 0) {
prefix = original.substring(previous, matcher.start(1));
previous = matcher.end(1);
}
else {
prefix = original.substring(previous, matcher.start());
previous = matcher.end();
}
buffer.append(prefix);
buffer.append(this.replacement);
previous = matcher.end(1);
}
if (previous < original.length()) {
buffer.append(original.substring(previous));

View File

@@ -29,6 +29,8 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.springframework.http.MediaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -44,7 +46,7 @@ public class PrettyPrintingContentModifier implements ContentModifier {
new XmlPrettyPrinter()));
@Override
public byte[] modifyContent(byte[] originalContent) {
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
for (PrettyPrinter prettyPrinter : PRETTY_PRINTERS) {
try {
return prettyPrinter.prettyPrint(originalContent).getBytes();

View File

@@ -84,23 +84,22 @@ public class HttpRequestSnippetTests {
.request("http://localhost/foo").method("POST").content("Hello, world")
.build());
}
@Test
public void postRequestWithCharset() throws IOException {
this.snippet.expectHttpRequest("post-request-with-charset").withContents(
httpRequest(POST, "/foo")
.header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "text/plain;charset=UTF-8").content(
"こんにちわ, 世界")); // Hello, World in japanese.
httpRequest(RequestMethod.POST, "/foo")
.header(HttpHeaders.HOST, "localhost")
.header("Content-Type", "text/plain;charset=UTF-8")
.content("こんにちわ, 世界")); // Hello, World in Japanese
new HttpRequestSnippet().document(new OperationBuilder(
"post-request-with-charset", this.snippet.getOutputDirectory())
.request("http://localhost/foo").method("POST")
.header("Content-Type", "text/plain;charset=UTF-8")
.content("こんにちわ, 世界")
.header("Content-Type", "text/plain;charset=UTF-8").content("こんにちわ, 世界")
.build());
}
@Test
public void postRequestWithParameter() throws IOException {
this.snippet.expectHttpRequest("post-request-with-parameter").withContents(

View File

@@ -68,8 +68,7 @@ public class HttpResponseSnippetTests {
@Test
public void responseWithHeaders() throws IOException {
this.snippet.expectHttpResponse("response-with-headers").withContents(
httpResponse(HttpStatus.OK) //
.header("Content-Type", "application/json") //
httpResponse(HttpStatus.OK).header("Content-Type", "application/json")
.header("a", "alpha"));
new HttpResponseSnippet().document(new OperationBuilder("response-with-headers",
this.snippet.getOutputDirectory()).response()
@@ -84,15 +83,18 @@ public class HttpResponseSnippetTests {
new HttpResponseSnippet().document(new OperationBuilder("response-with-content",
this.snippet.getOutputDirectory()).response().content("content").build());
}
@Test
public void responseWithCharset() throws IOException {
this.snippet.expectHttpResponse("response-with-charset").withContents(
httpResponse(OK).header("Content-Type", "text/plain;charset=UTF-8").content("コンテンツ"));
httpResponse(HttpStatus.OK).header("Content-Type",
"text/plain;charset=UTF-8").content("コンテンツ"));
new HttpResponseSnippet().document(new OperationBuilder("response-with-charset",
this.snippet.getOutputDirectory()).response().header("Content-Type", "text/plain;charset=UTF-8").content("コンテンツ").build());
this.snippet.getOutputDirectory()).response()
.header("Content-Type", "text/plain;charset=UTF-8").content("コンテンツ")
.build());
}
@Test
public void responseWithCustomSnippetAttributes() throws IOException {
this.snippet.expectHttpResponse("response-with-snippet-attributes").withContents(

View File

@@ -23,6 +23,7 @@ import org.junit.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.restdocs.operation.OperationRequest;
import org.springframework.restdocs.operation.OperationRequestPart;
import org.springframework.restdocs.operation.OperationResponse;
@@ -46,7 +47,7 @@ public class ContentModifyingOperationPreprocessorTests {
new ContentModifier() {
@Override
public byte[] modifyContent(byte[] originalContent) {
public byte[] modifyContent(byte[] originalContent, MediaType mediaType) {
return "modified".getBytes();
}

View File

@@ -52,37 +52,36 @@ public class LinkMaskingContentModifierTests {
@Test
public void halLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(halPayloadWithLinks(this.links)),
assertThat(
this.contentModifier.modifyContent(halPayloadWithLinks(this.links), null),
is(equalTo(halPayloadWithLinks(this.maskedLinks))));
}
@Test
public void formattedHalLinksAreMasked() throws Exception {
assertThat(
this.contentModifier
.modifyContent(formattedHalPayloadWithLinks(this.links)),
assertThat(this.contentModifier.modifyContent(
formattedHalPayloadWithLinks(this.links), null),
is(equalTo(formattedHalPayloadWithLinks(this.maskedLinks))));
}
@Test
public void atomLinksAreMasked() throws Exception {
assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links)),
is(equalTo(atomPayloadWithLinks(this.maskedLinks))));
assertThat(this.contentModifier.modifyContent(atomPayloadWithLinks(this.links),
null), is(equalTo(atomPayloadWithLinks(this.maskedLinks))));
}
@Test
public void formattedAtomLinksAreMasked() throws Exception {
assertThat(
this.contentModifier
.modifyContent(formattedAtomPayloadWithLinks(this.links)),
assertThat(this.contentModifier.modifyContent(
formattedAtomPayloadWithLinks(this.links), null),
is(equalTo(formattedAtomPayloadWithLinks(this.maskedLinks))));
}
@Test
public void maskCanBeCustomized() throws Exception {
assertThat(
new LinkMaskingContentModifier("custom")
.modifyContent(formattedAtomPayloadWithLinks(this.links)),
new LinkMaskingContentModifier("custom").modifyContent(
formattedAtomPayloadWithLinks(this.links), null),
is(equalTo(formattedAtomPayloadWithLinks(new Link("a", "custom"),
new Link("b", "custom")))));
}

View File

@@ -16,9 +16,11 @@
package org.springframework.restdocs.operation.preprocess;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
import org.junit.Test;
import org.springframework.http.MediaType;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
@@ -35,13 +37,23 @@ 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})",
"[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())));
assertThat(contentModifier.modifyContent(
"{\"id\" : \"CA761232-ED42-11CE-BACD-00AA0057B223\"}".getBytes(), null),
is(equalTo("{\"id\" : \"<<uuid>>\"}".getBytes())));
}
@Test
public void encodingIsPreserved() {
Pattern pattern = Pattern.compile("[0-9]+");
PatternReplacingContentModifier contentModifier = new PatternReplacingContentModifier(
pattern, "<<number>>");
assertThat(contentModifier.modifyContent("こんにちわ, 世界 123".getBytes(),
new MediaType("text", "plain", Charset.forName("UTF-8"))),
is(equalTo("こんにちわ, 世界 <<number>>".getBytes())));
}
}

View File

@@ -31,16 +31,16 @@ public class PrettyPrintingContentModifierTests {
@Test
public void prettyPrintJson() throws Exception {
assertThat(
new PrettyPrintingContentModifier().modifyContent("{\"a\":5}".getBytes()),
equalTo(String.format("{%n \"a\" : 5%n}").getBytes()));
assertThat(new PrettyPrintingContentModifier().modifyContent(
"{\"a\":5}".getBytes(), null), equalTo(String.format("{%n \"a\" : 5%n}")
.getBytes()));
}
@Test
public void prettyPrintXml() throws Exception {
assertThat(
new PrettyPrintingContentModifier().modifyContent("<one a=\"alpha\"><two b=\"bravo\"/></one>"
.getBytes()), equalTo(String.format(
assertThat(new PrettyPrintingContentModifier().modifyContent(
"<one a=\"alpha\"><two b=\"bravo\"/></one>".getBytes(), null),
equalTo(String.format(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n"
+ "<one a=\"alpha\">%n <two b=\"bravo\"/>%n</one>%n")
.getBytes()));
@@ -48,14 +48,15 @@ public class PrettyPrintingContentModifierTests {
@Test
public void empytContentIsHandledGracefully() throws Exception {
assertThat(new PrettyPrintingContentModifier().modifyContent("".getBytes()),
assertThat(
new PrettyPrintingContentModifier().modifyContent("".getBytes(), null),
equalTo("".getBytes()));
}
@Test
public void nonJsonAndNonXmlContentIsHandledGracefully() throws Exception {
String content = "abcdefg";
assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes()),
equalTo(content.getBytes()));
assertThat(new PrettyPrintingContentModifier().modifyContent(content.getBytes(),
null), equalTo(content.getBytes()));
}
}