Polish "Add support for documenting request part payload fields"

- Rebase on latest code, and make use of new support for the same
  TemplatedSnippet producing multiple snippets with different names
  from the same template
- Expand the documentation
- Apply code formatting
- Add support for relaxed documentation of a request part's fields

Closes gh-270
This commit is contained in:
Andy Wilkinson
2016-10-25 12:04:43 +01:00
parent 13e745a9a9
commit d2a5b38c83
12 changed files with 559 additions and 181 deletions

View File

@@ -415,7 +415,7 @@ include::{examples-dir}/com/example/mockmvc/RequestParameters.java[tags=request-
----
<1> Perform a `GET` request with two parameters, `page` and `per_page` in the query
string.
<2> Configure Spring REST Docs to produce a snippet describing the request's parameters.
<2> Configure Spring REST Docs to produce a snippet describing the request's parameters.
Uses the static `requestParameters` method on
`org.springframework.restdocs.request.RequestDocumentation`.
<3> Document the `page` parameter. Uses the static `parameterWithName` method on
@@ -575,12 +575,58 @@ prevent it from appearing in the generated snippet while avoiding the failure de
above.
[[documenting-your-api-request-parts]]
=== Request parts content
[[documenting-your-api-request-parts-payloads]]
=== Request part payloads
If you need to document the content of request part that holds Json data, you should use`requestPartsFields`.
It acts exactly as [[documenting-your-api-request-parts]] but in order to use it, you must specify the part name.
The payload of a request part can be documented in much the same way as the
<<documenting-your-api-request-response-payloads,payload of a request>>:
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/RequestPartPayload.java[tags=payload]
----
<1> Configure Spring REST docs to produce a snippet describing the fields in the payload
of the request part named `metadata`. Uses the static `requestPartFields` method on
`PayloadDocumentation`.
payload.
<2> Expect a field with the path `version`. Uses the static `fieldWithPath` method on
`org.springframework.restdocs.payload.PayloadDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestPartPayload.java[tags=payload]
----
<1> Configure Spring REST docs to produce a snippet describing the fields in the payload
of the request part named `metadata`. Uses the static `requestPartFields` method on
`PayloadDocumentation`.
<2> Expect a field with the path `version`. Uses the static `fieldWithPath` method on
`org.springframework.restdocs.payload.PayloadDocumentation`.
The result is a snippet that contains a table describing the part's fields. This snippet
is named `request-part-${part-name}-fields.adoc`. For example, documenting a part named
`metadata` will produce a snippet named `request-part-metadata-fields.adoc`.
When documenting fields, the test will fail if an undocumented field is found in the
payload of the part. Similarly, the test will also fail if a documented field is not found
in the payload of the part and the field has not been marked as optional. For payloads
with a hierarchical structure, documenting a field is sufficient for all of its
descendants to also be treated as having been documented.
If you do not want to document a field, you can mark it as ignored. This will prevent it
from appearing in the generated snippet while avoiding the failure described above.
Fields can also be documented in a relaxed mode where any undocumented fields will not
cause a test failure. To do so, use the `relaxedRequestPartFields` method on
`org.springframework.restdocs.payload.PayloadDocumentation`. This can be useful when
documenting a particular scenario where you only want to focus on a subset of the payload
of the part.
For further information on describing fields, documenting payloads that use XML,
and more please refer to the
<<documenting-your-api-request-response-payloads,section on documenting request and
response payloads>>.
[[documenting-your-api-http-headers]]
=== HTTP headers

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2014-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.mockmvc;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.fileUpload;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartFields;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
public class RequestPartPayload {
private MockMvc mockMvc;
public void response() throws Exception {
// tag::payload[]
MockMultipartFile image = new MockMultipartFile("image", "image.png", "image/png",
"<<png data>>".getBytes());
MockMultipartFile metadata = new MockMultipartFile("metadata", "",
"application/json", "{ \"version\": \"1.0\"}".getBytes());
this.mockMvc.perform(fileUpload("/images").file(image).file(metadata)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("image-upload", requestPartFields("metadata", // <1>
fieldWithPath("version").description("The version of the image")))); // <2>
// end::payload[]
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2014-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartFields;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class RequestPartPayload {
private RequestSpecification spec;
public void response() throws Exception {
// tag::payload[]
Map<String, String> metadata = new HashMap<>();
metadata.put("version", "1.0");
RestAssured.given(this.spec).accept("application/json")
.filter(document("image-upload", requestPartFields("metadata", // <1>
fieldWithPath("version").description("The version of the image")))) // <2>
.when().multiPart("image", new File("image.png"), "image/png")
.multiPart("metadata", metadata).post("images")
.then().assertThat().statusCode(is(200));
// end::payload[]
}
}