From 9ba0a9b6be0b9be039382ee6ef8efb5073df1579 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 19 Aug 2016 19:30:22 +0100 Subject: [PATCH 1/3] Stop field snippets requiring a type for missing, optional, ignored field Missing optional fields require a type to be explicitly provided as it cannot be inferred from the payload. Ignored fields are not included in the documentation, yet, previously, a field that was missing, optional, and ignored would still require a type to be provided otherwise the test would fail. This was pointless as the field wasn't going to appear in the documentation. This commit updates the fields snippets so that a type is no longer required for a field that is missing, optional and ignored. Closes gh-289 --- .../payload/AbstractFieldsSnippet.java | 20 ++++++++++--------- .../payload/RequestFieldsSnippetTests.java | 15 ++++++++++++++ .../payload/ResponseFieldsSnippetTests.java | 14 +++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) 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 a21bf524..16f7ba61 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 @@ -100,15 +100,17 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { validateFieldDocumentation(contentHandler); for (FieldDescriptor descriptor : this.fieldDescriptors) { - try { - descriptor.type(contentHandler.determineFieldType(descriptor)); - } - catch (FieldDoesNotExistException ex) { - String message = "Cannot determine the type of the field '" - + descriptor.getPath() + "' as it is not present in the " - + "payload. Please provide a type using " - + "FieldDescriptor.type(Object type)."; - throw new FieldTypeRequiredException(message); + if (!descriptor.isIgnored()) { + try { + descriptor.type(contentHandler.determineFieldType(descriptor)); + } + catch (FieldDoesNotExistException ex) { + String message = "Cannot determine the type of the field '" + + descriptor.getPath() + "' as it is not present in the " + + "payload. Please provide a type using " + + "FieldDescriptor.type(Object type)."; + throw new FieldTypeRequiredException(message); + } } } 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 32e34be9..18e89a9b 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 @@ -118,6 +118,21 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests { .request("http://localhost").content("{}").build()); } + @Test + public void missingIgnoredOptionalRequestFieldDoesNotRequireAType() + throws IOException { + this.snippet + .expectRequestFields( + "missing-ignored-optional-request-field-does-not-require-a-type") + .withContents(tableWithHeader("Path", "Type", "Description")); + new RequestFieldsSnippet(Arrays + .asList(fieldWithPath("a.b").description("one").ignored().optional())) + .document(operationBuilder( + "missing-ignored-optional-request-field-does-not-require-a-type") + .request("http://localhost").content("{}") + .build()); + } + @Test public void presentOptionalRequestField() throws IOException { this.snippet.expectRequestFields("present-optional-request-field") 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 e0525888..8d93a987 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 @@ -147,6 +147,20 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests { .response().content("{}").build()); } + @Test + public void missingIgnoredOptionalResponseFieldDoesNotRequireAType() + throws IOException { + this.snippet + .expectResponseFields( + "missing-ignored-optional-response-field-does-not-require-a-type") + .withContents(tableWithHeader("Path", "Type", "Description")); + new ResponseFieldsSnippet(Arrays + .asList(fieldWithPath("a.b").description("one").ignored().optional())) + .document(operationBuilder( + "missing-ignored-optional-response-field-does-not-require-a-type") + .response().content("{}").build()); + } + @Test public void presentOptionalResponseField() throws IOException { this.snippet.expectResponseFields("present-optional-response-field") From a0faebdb0a33f2ccede8c1293a778d78ddccd7fb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 19 Aug 2016 19:51:16 +0100 Subject: [PATCH 2/3] Ignore query string when extracting path parameters Closes gh-285 --- .../restdocs/request/PathParametersSnippet.java | 2 +- .../request/PathParametersSnippetTests.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index afbd0b52..64df77ec 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -116,7 +116,7 @@ public class PathParametersSnippet extends AbstractParametersSnippet { @Override protected Set extractActualParameters(Operation operation) { - String urlTemplate = extractUrlTemplate(operation); + String urlTemplate = removeQueryStringIfPresent(extractUrlTemplate(operation)); Matcher matcher = NAMES_PATTERN.matcher(urlTemplate); Set actualParameters = new HashSet<>(); while (matcher.find()) { diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java index e0980991..fbc7449b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/request/PathParametersSnippetTests.java @@ -130,6 +130,23 @@ public class PathParametersSnippetTests extends AbstractSnippetTests { "/{a}/{b}?foo=bar").build()); } + @Test + public void pathParametersWithQueryStringWithParameters() throws IOException { + this.snippet + .expectPathParameters("path-parameters-with-query-string-with-parameters") + .withContents( + tableWithTitleAndHeader(getTitle(), "Parameter", "Description") + .row("`a`", "one").row("`b`", "two")); + new PathParametersSnippet(Arrays.asList(parameterWithName("a").description("one"), + parameterWithName("b").description("two"))) + .document(operationBuilder( + "path-parameters-with-query-string-with-parameters") + .attribute( + RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, + "/{a}/{b}?foo={c}") + .build()); + } + @Test public void pathParametersWithCustomAttributes() throws IOException { TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); From 5c6cf7f12ff43ed97dcc2e59e1b63465d91ee175 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 19 Aug 2016 19:51:37 +0100 Subject: [PATCH 3/3] Polishing --- .../restdocs/request/PathParametersSnippet.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java index 64df77ec..254cb7b4 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/PathParametersSnippet.java @@ -129,9 +129,8 @@ public class PathParametersSnippet extends AbstractParametersSnippet { private String extractUrlTemplate(Operation operation) { String urlTemplate = (String) operation.getAttributes() .get(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE); - Assert.notNull(urlTemplate, - "urlTemplate not found. If you are using MockMvc, did you use RestDocumentationRequestBuilders to " - + "build the request?"); + Assert.notNull(urlTemplate, "urlTemplate not found. If you are using MockMvc did " + + "you use RestDocumentationRequestBuilders to build the request?"); return urlTemplate; }