diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index 8c83ab97..1a2364bf 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -219,17 +219,32 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { } private ContentHandler getContentHandler(byte[] content, MediaType contentType) { - try { - if (contentType != null - && MediaType.APPLICATION_XML.isCompatibleWith(contentType)) { - return new XmlContentHandler(content); - } - else { - return new JsonContentHandler(content); + ContentHandler contentHandler = createJsonContentHandler(content); + if (contentHandler == null) { + contentHandler = createXmlContentHandler(content); + if (contentHandler == null) { + throw new PayloadHandlingException("Cannot handle " + contentType + + " content as it could not be parsed as JSON or XML"); } } - catch (IOException ex) { - throw new ModelCreationException(ex); + return contentHandler; + } + + private ContentHandler createJsonContentHandler(byte[] content) { + try { + return new JsonContentHandler(content); + } + catch (Exception ex) { + return null; + } + } + + private ContentHandler createXmlContentHandler(byte[] content) { + try { + return new XmlContentHandler(content); + } + catch (Exception ex) { + return null; } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java index 82819a72..02eded55 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/JsonContentHandler.java @@ -41,8 +41,9 @@ class JsonContentHandler implements ContentHandler { private final byte[] rawContent; - JsonContentHandler(byte[] content) throws IOException { + JsonContentHandler(byte[] content) { this.rawContent = content; + readContent(); } @Override diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java index f5a466ff..45c08846 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/XmlContentHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-2017 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. @@ -62,6 +62,7 @@ class XmlContentHandler implements ContentHandler { throw new IllegalStateException("Failed to create document builder", ex); } this.rawContent = rawContent; + readPayload(); } @Override diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java index b5f74523..349ea04a 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/JsonContentHandlerTests.java @@ -51,4 +51,10 @@ public class JsonContentHandlerTests { assertThat((JsonFieldType) fieldType, is(equalTo(JsonFieldType.STRING))); } + @Test + public void failsFastWithNonJsonContent() { + this.thrown.expect(PayloadHandlingException.class); + new JsonContentHandler("Non-JSON content".getBytes()); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java index 80c9cdf1..bddf8801 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -135,8 +135,8 @@ public class RequestFieldsSnippetFailureTests { startsWith("The following parts of the payload were not documented:")); new RequestFieldsSnippet(Collections.emptyList()) .document(this.operationBuilder.request("http://localhost") - .content("5").header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) + .content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) .build()); } @@ -159,8 +159,8 @@ public class RequestFieldsSnippetFailureTests { this.thrown.expect(FieldTypeRequiredException.class); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description("one"))) .document(this.operationBuilder.request("http://localhost") - .content("5").header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) + .content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) .build()); } @@ -187,8 +187,20 @@ public class RequestFieldsSnippetFailureTests { + " in the payload: [a/b]")); new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a/b").description("one"))) .document(this.operationBuilder.request("http://localhost") - .content("5").header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) + .content("5") + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) + .build()); + } + + @Test + public void unsupportedContent() throws IOException { + this.thrown.expect(PayloadHandlingException.class); + this.thrown.expectMessage(equalTo("Cannot handle text/plain content as it could" + + " not be parsed as JSON or XML")); + new RequestFieldsSnippet(Collections.emptyList()) + .document(this.operationBuilder.request("http://localhost") + .content("Some plain text") + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .build()); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java index aa351b40..d1c56f3b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -264,21 +264,33 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests { } @Test - public void xmlRequestFields() throws IOException { + public void applicationXmlRequestFields() throws IOException { + xmlRequestFields(MediaType.APPLICATION_XML); + } + + @Test + public void textXmlRequestFields() throws IOException { + xmlRequestFields(MediaType.TEXT_XML); + } + + @Test + public void customXmlRequestFields() throws IOException { + xmlRequestFields(MediaType.parseMediaType("application/vnd.com.example+xml")); + } + + private void xmlRequestFields(MediaType contentType) throws IOException { this.snippets.expectRequestFields() .withContents(tableWithHeader("Path", "Type", "Description") .row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two") .row("`a`", "`a`", "three")); - new RequestFieldsSnippet( - Arrays.asList(fieldWithPath("a/b").description("one").type("b"), - fieldWithPath("a/c").description("two").type("c"), - fieldWithPath("a").description("three").type("a"))) - .document( - this.operationBuilder.request("http://localhost") - .content("5charlie") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) + new RequestFieldsSnippet(Arrays.asList( + fieldWithPath("a/b").description("one").type("b"), + fieldWithPath("a/c").description("two").type("c"), + fieldWithPath("a").description("three").type("a"))) + .document(this.operationBuilder.request("http://localhost") + .content("5charlie") + .header(HttpHeaders.CONTENT_TYPE, contentType.toString()) .build()); } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java index 92c8da49..bf322669 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetFailureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -108,7 +108,7 @@ public class ResponseFieldsSnippetFailureTests { .content("foo") .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE) - .build()); + .build()); } @Test @@ -162,4 +162,15 @@ public class ResponseFieldsSnippetFailureTests { .build()); } + @Test + public void unsupportedContent() throws IOException { + this.thrown.expect(PayloadHandlingException.class); + this.thrown.expectMessage(equalTo("Cannot handle text/plain content as it could" + + " not be parsed as JSON or XML")); + new ResponseFieldsSnippet(Collections.emptyList()) + .document(this.operationBuilder.response().content("Some plain text") + .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) + .build()); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java index 5b3438fb..a7f2f047 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/ResponseFieldsSnippetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -238,21 +238,33 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests { } @Test - public void xmlResponseFields() throws IOException { + public void applicationXmlResponseFields() throws IOException { + xmlResponseFields(MediaType.APPLICATION_XML); + } + + @Test + public void textXmlResponseFields() throws IOException { + xmlResponseFields(MediaType.TEXT_XML); + } + + @Test + public void customXmlResponseFields() throws IOException { + xmlResponseFields(MediaType.parseMediaType("application/vnd.com.example+xml")); + } + + private void xmlResponseFields(MediaType contentType) throws IOException { this.snippets.expectResponseFields() .withContents(tableWithHeader("Path", "Type", "Description") .row("`a/b`", "`b`", "one").row("`a/c`", "`c`", "two") .row("`a`", "`a`", "three")); - new ResponseFieldsSnippet( - Arrays.asList(fieldWithPath("a/b").description("one").type("b"), - fieldWithPath("a/c").description("two").type("c"), - fieldWithPath("a").description("three").type("a"))) - .document( - this.operationBuilder.response() - .content("5charlie") - .header(HttpHeaders.CONTENT_TYPE, - MediaType.APPLICATION_XML_VALUE) - .build()); + new ResponseFieldsSnippet(Arrays.asList( + fieldWithPath("a/b").description("one").type("b"), + fieldWithPath("a/c").description("two").type("c"), + fieldWithPath("a").description("three").type("a"))) + .document(this.operationBuilder.response() + .content("5charlie") + .header(HttpHeaders.CONTENT_TYPE, contentType.toString()) + .build()); } @Test diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java index 5c9f1b6e..064ed972 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/XmlContentHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 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. @@ -18,7 +18,9 @@ package org.springframework.restdocs.payload; import java.util.Arrays; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; @@ -34,6 +36,9 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.subsecti */ public class XmlContentHandlerTests { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void topLevelElementCanBeDocumented() { String undocumentedContent = createHandler("5").getUndocumentedContent( @@ -84,6 +89,12 @@ public class XmlContentHandlerTests { assertThat(undocumentedContent, is(nullValue())); } + @Test + public void failsFastWithNonXmlContent() { + this.thrown.expect(PayloadHandlingException.class); + createHandler("non-XML content"); + } + private XmlContentHandler createHandler(String xml) { return new XmlContentHandler(xml.getBytes()); }