Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty printing truncates non-json responses that happen to begin with valid json #730

Closed
OrangeDog opened this issue May 26, 2021 · 5 comments

Comments

@OrangeDog
Copy link

The following test passes

mockMvc.perform(post(URI))
        .andExpect(status().isOk())
        .andExpect(content().contentType("text/csv"))
        .andExpect(content().string("0.33\r\nnull\r\n8.20\r\n"))
        .andDo(document("example"));

But example/http-response.snippet only has:

[source,http,options="nowrap"]
----
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Length: 4

0.33
----

spring-restdocs-mockmvc 2.0.5.RELEASE

@OrangeDog
Copy link
Author

OrangeDog commented May 26, 2021

This only seems to happen if the first line contains only a valid number.
Anything else on the first line and no truncation occurs.

@wilkinsona
Copy link
Member

The response snippet should just use the body as-is so the nature of the content shouldn’t make any difference. The content length and body content are also in agreement so I’m not sure why it’s apparently being truncated. It’s possible that the cause lies somewhere before REST Docs gets involved.

To help with figuring out what’s going on, please provide a minimal sample that reproduces the problem.

@OrangeDog
Copy link
Author

Found it:

@Override
public void customize(MockMvcRestDocumentationConfigurer configurer) {
    configurer.operationPreprocessors().withResponseDefaults(prettyPrint());
}

It uses the JsonPrettyPrinter regardless of the content type, and FAIL_ON_TRAILING_TOKENS defaults to false. Therefore if the response starts with some valid JSON, the remainder will be truncated.

What's the best way to work around this for a single test?

@wilkinsona
Copy link
Member

Thanks for tracking down the cause. I think your best bet for now may be to decorate the pretty-printer with something that checks the content type. Something like this, with changes to the media type compatibility checks to meet your needs:

private OperationPreprocessor prettyPrintJson() {
	ContentModifier prettyPrinter = new PrettyPrintingContentModifier();
	return new ContentModifyingOperationPreprocessor((content, mediaType) -> {
		if (mediaType.isCompatibleWith(MediaType.parseMediaType("application/*+json"))
				|| mediaType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
			return prettyPrinter.modifyContent(content, mediaType);
		}
		return content;
	});
}

You can then use prettyPrintJson() in places where you'd use prettyPrint().

@wilkinsona wilkinsona changed the title http-response snippet truncated Pretty printing truncates non-json responses that happen to begin with valid json Jun 7, 2021
@wilkinsona wilkinsona added this to the 2.0.6.RELEASE milestone Jun 7, 2021
@wilkinsona
Copy link
Member

The simplest fix for this would be to set DeserializationFeature.FAIL_ON_TRAILING_TOKENS to true on the ObjectMapper that's used for pretty printing. I'm slightly wary of this being a breaking change for someone who was, perhaps inadvertently, relying upon trailing tokens being ignored. An alternative would be to restrict pretty printing based on content type. Done by default this too would be a potentially breaking change, but this could be avoided by adding an API that preserves the current default behaviour but allows the content types that will be pretty printed to be restricted. This feels more like a 2.x enhancement than a bug fix though. I'm quite tempted to stop ignoring trailing tokens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants