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 d6e384cf..cf5ac124 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 @@ -24,6 +24,8 @@ import java.util.Map; import org.springframework.http.MediaType; import org.springframework.restdocs.operation.Operation; +import org.springframework.restdocs.snippet.Attributes; +import org.springframework.restdocs.snippet.Attributes.Attribute; import org.springframework.restdocs.snippet.ModelCreationException; import org.springframework.restdocs.snippet.SnippetException; import org.springframework.restdocs.snippet.TemplatedSnippet; @@ -166,10 +168,12 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { validateFieldDocumentation(contentHandler); + List descriptorsToDocument = new ArrayList<>(); for (FieldDescriptor descriptor : this.fieldDescriptors) { if (!descriptor.isIgnored()) { try { - descriptor.type(contentHandler.determineFieldType(descriptor)); + Object type = contentHandler.determineFieldType(descriptor); + descriptorsToDocument.add(copyWithType(descriptor, type)); } catch (FieldDoesNotExistException ex) { String message = "Cannot determine the type of the field '" @@ -184,7 +188,7 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { Map model = new HashMap<>(); List> fields = new ArrayList<>(); model.put("fields", fields); - for (FieldDescriptor descriptor : this.fieldDescriptors) { + for (FieldDescriptor descriptor : descriptorsToDocument) { if (!descriptor.isIgnored()) { fields.add(createModelForDescriptor(descriptor)); } @@ -322,4 +326,28 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { return model; } + private FieldDescriptor copyWithType(FieldDescriptor source, Object type) { + FieldDescriptor result = source instanceof SubsectionDescriptor + ? new SubsectionDescriptor(source.getPath()) + : new FieldDescriptor(source.getPath()); + result.description(source.getDescription()).type(type) + .attributes(asArray(source.getAttributes())); + if (source.isIgnored()) { + result.ignored(); + } + if (source.isOptional()) { + result.optional(); + } + return result; + } + + private static Attribute[] asArray(Map attributeMap) { + List attributes = new ArrayList<>(); + for (Map.Entry attribute : attributeMap.entrySet()) { + attributes + .add(Attributes.key(attribute.getKey()).value(attribute.getValue())); + } + return attributes.toArray(new Attribute[attributes.size()]); + } + } 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 ffb4d4dc..43eece49 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 @@ -31,6 +31,9 @@ import org.springframework.restdocs.templates.TemplateResourceResolver; import org.springframework.restdocs.templates.mustache.MustacheTemplateEngine; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.springframework.restdocs.payload.PayloadDocumentation.beneathPath; @@ -446,6 +449,17 @@ public class RequestFieldsSnippetTests extends AbstractSnippetTests { .build()); } + @Test + public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException { + this.snippets.expectRequestFields() + .withContents(tableWithHeader("Path", "Type", "Description").row("`a.b`", + "`Number`", "one")); + FieldDescriptor descriptor = fieldWithPath("a.b").description("one"); + new RequestFieldsSnippet(Arrays.asList(descriptor)).document(this.operationBuilder + .request("http://localhost").content("{\"a\": {\"b\": 5}}").build()); + assertThat(descriptor.getType(), is(nullValue())); + } + private String escapeIfNecessary(String input) { if (this.templateFormat.equals(TemplateFormats.markdown())) { return input; 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 cd6fdb52..020131df 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 @@ -31,6 +31,9 @@ import org.springframework.restdocs.templates.TemplateResourceResolver; import org.springframework.restdocs.templates.mustache.MustacheTemplateEngine; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.springframework.restdocs.payload.PayloadDocumentation.beneathPath; @@ -457,6 +460,17 @@ public class ResponseFieldsSnippetTests extends AbstractSnippetTests { .build()); } + @Test + public void typeDeterminationDoesNotSetTypeOnDescriptor() throws IOException { + this.snippets.expectResponseFields() + .withContents(tableWithHeader("Path", "Type", "Description").row("`id`", + "`Number`", "one")); + FieldDescriptor descriptor = fieldWithPath("id").description("one"); + new ResponseFieldsSnippet(Arrays.asList(descriptor)).document( + this.operationBuilder.response().content("{\"id\": 67}").build()); + assertThat(descriptor.getType(), is(nullValue())); + } + private String escapeIfNecessary(String input) { if (this.templateFormat.equals(TemplateFormats.markdown())) { return input;