From 82a0da2627a0418f780025300aa329ce2f8a093c Mon Sep 17 00:00:00 2001 From: John Thompson Date: Tue, 28 May 2019 08:41:41 -0400 Subject: [PATCH] adding constraint validation example --- .../sfgrestdocsexample/web/model/BeerDto.java | 7 ++-- .../web/controller/BeerControllerTest.java | 39 ++++++++++++++----- .../restdocs/templates/request-fields.snippet | 11 ++++++ 3 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 src/test/resources/org/springframework/restdocs/templates/request-fields.snippet diff --git a/src/main/java/guru/springframework/sfgrestdocsexample/web/model/BeerDto.java b/src/main/java/guru/springframework/sfgrestdocsexample/web/model/BeerDto.java index d2f1eac..939dc4b 100644 --- a/src/main/java/guru/springframework/sfgrestdocsexample/web/model/BeerDto.java +++ b/src/main/java/guru/springframework/sfgrestdocsexample/web/model/BeerDto.java @@ -5,10 +5,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Null; -import javax.validation.constraints.Positive; +import javax.validation.constraints.*; import java.math.BigDecimal; import java.time.OffsetDateTime; import java.util.UUID; @@ -36,6 +33,7 @@ public class BeerDto { private OffsetDateTime lastModifiedDate; @NotBlank + @Size(min = 3, max = 100) private String beerName; @NotNull @@ -49,6 +47,7 @@ public class BeerDto { @NotNull private BigDecimal price; + @Positive private Integer quantityOnHand; } diff --git a/src/test/java/guru/springframework/sfgrestdocsexample/web/controller/BeerControllerTest.java b/src/test/java/guru/springframework/sfgrestdocsexample/web/controller/BeerControllerTest.java index 66b26f1..b9fe4b5 100644 --- a/src/test/java/guru/springframework/sfgrestdocsexample/web/controller/BeerControllerTest.java +++ b/src/test/java/guru/springframework/sfgrestdocsexample/web/controller/BeerControllerTest.java @@ -14,7 +14,10 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.MediaType; import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.constraints.ConstraintDescriptions; +import org.springframework.restdocs.payload.FieldDescriptor; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.util.Optional; @@ -26,6 +29,7 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.docu import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; import static org.springframework.restdocs.payload.PayloadDocumentation.*; import static org.springframework.restdocs.request.RequestDocumentation.*; +import static org.springframework.restdocs.snippet.Attributes.key; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; //import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -78,21 +82,23 @@ class BeerControllerTest { BeerDto beerDto = getValidBeerDto(); String beerDtoJson = objectMapper.writeValueAsString(beerDto); + ConstrainedFields fields = new ConstrainedFields(BeerDto.class); + mockMvc.perform(post("/api/v1/beer/") .contentType(MediaType.APPLICATION_JSON) .content(beerDtoJson)) .andExpect(status().isCreated()) .andDo(document("v1/beer", requestFields( - fieldWithPath("id").ignored(), - fieldWithPath("version").ignored(), - fieldWithPath("createdDate").ignored(), - fieldWithPath("lastModifiedDate").ignored(), - fieldWithPath("beerName").description("Name of the beer"), - fieldWithPath("beerStyle").description("Style of Beer"), - fieldWithPath("upc").description("Beer UPC").attributes(), - fieldWithPath("price").description("Beer Price"), - fieldWithPath("quantityOnHand").ignored() + fields.withPath("id").ignored(), + fields.withPath("version").ignored(), + fields.withPath("createdDate").ignored(), + fields.withPath("lastModifiedDate").ignored(), + fields.withPath("beerName").description("Name of the beer"), + fields.withPath("beerStyle").description("Style of Beer"), + fields.withPath("upc").description("Beer UPC").attributes(), + fields.withPath("price").description("Beer Price"), + fields.withPath("quantityOnHand").ignored() ))); } @@ -117,4 +123,19 @@ class BeerControllerTest { } + private static class ConstrainedFields { + + private final ConstraintDescriptions constraintDescriptions; + + ConstrainedFields(Class input) { + this.constraintDescriptions = new ConstraintDescriptions(input); + } + + private FieldDescriptor withPath(String path) { + return fieldWithPath(path).attributes(key("constraints").value(StringUtils + .collectionToDelimitedString(this.constraintDescriptions + .descriptionsForProperty(path), ". "))); + } + } + } \ No newline at end of file diff --git a/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet b/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet new file mode 100644 index 0000000..5f83e8e --- /dev/null +++ b/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet @@ -0,0 +1,11 @@ + |=== + |Path|Type|Description|Constraints + + {{#fields}} + |{{path}} + |{{type}} + |{{description}} + |{{constraints}} + + {{/fields}} + |=== \ No newline at end of file