Improve support for documenting PUT requests

Previously, no special consideration was given to PUT requests. This
meant that curl and HTTP request snippets would not include the
request’s parameters/query string and that HTTP request snippets would
not set the content type to application/x-www-form-urlencoded.

This commit addresses these limitations by updating both
HttpDocumentation and CurlDocumentation to treat PUT requests in the
same way as POST requests.

Closes gh-62
This commit is contained in:
Jonathan Pearlin
2015-04-28 16:21:38 -07:00
committed by Andy Wilkinson
parent e5f35c98f3
commit ca375c919c
5 changed files with 72 additions and 4 deletions

View File

@@ -34,6 +34,7 @@ import org.springframework.util.StringUtils;
* @author Andy Wilkinson
* @author Yann Le Guern
* @author Dmitriy Mayboroda
* @author Jonathan Pearlin
*/
public abstract class CurlDocumentation {
@@ -114,7 +115,7 @@ public abstract class CurlDocumentation {
this.writer
.print(String.format(" -d '%s'", request.getContentAsString()));
}
else if (request.isPostRequest()) {
else if (request.isPostRequest() || request.isPutRequest()) {
String queryString = request.getParameterMapAsQueryString();
if (StringUtils.hasText(queryString)) {
this.writer.print(String.format(" -d '%s'", queryString));

View File

@@ -34,6 +34,7 @@ import org.springframework.util.StringUtils;
* Static factory methods for documenting a RESTful API's HTTP requests.
*
* @author Andy Wilkinson
* @author Jonathan Pearlin
*/
public abstract class HttpDocumentation {
@@ -109,7 +110,7 @@ public abstract class HttpDocumentation {
if (request.getContentLength() > 0) {
this.writer.println(request.getContentAsString());
}
else if (request.isPostRequest()) {
else if (request.isPostRequest() || request.isPutRequest()) {
String queryString = request.getParameterMapAsQueryString();
if (StringUtils.hasText(queryString)) {
this.writer.println(queryString);
@@ -120,7 +121,7 @@ public abstract class HttpDocumentation {
private boolean requiresFormEncodingContentType(
DocumentableHttpServletRequest request) {
return request.getHeaders().getContentType() == null
&& request.isPostRequest()
&& (request.isPostRequest() || request.isPutRequest())
&& StringUtils.hasText(request.getParameterMapAsQueryString());
}
}

View File

@@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
* to help in the documentation of the request.
*
* @author Andy Wilkinson
*
* @author Jonathan Pearlin
*/
public class DocumentableHttpServletRequest {
@@ -73,6 +73,16 @@ public class DocumentableHttpServletRequest {
return RequestMethod.POST == RequestMethod.valueOf(this.delegate.getMethod());
}
/**
* Whether or not this request is a {@code PUT} request.
*
* @return {@code true} if it is a {@code PUT} request, otherwise {@code false}
* @see HttpServletRequest#getMethod()
*/
public boolean isPutRequest() {
return RequestMethod.PUT == RequestMethod.valueOf(this.delegate.getMethod());
}
/**
* Returns the request's headers. The headers are ordered based on the ordering of
* {@link HttpServletRequest#getHeaderNames()} and

View File

@@ -21,6 +21,7 @@ import static org.springframework.restdocs.test.SnippetMatchers.codeBlock;
import static org.springframework.restdocs.test.StubMvcResult.result;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import java.io.IOException;
@@ -36,6 +37,7 @@ import org.springframework.restdocs.test.ExpectedSnippet;
* @author Andy Wilkinson
* @author Yann Le Guern
* @author Dmitriy Mayboroda
* @author Jonathan Pearlin
*/
public class CurlDocumentationTests {
@@ -134,6 +136,36 @@ public class CurlDocumentationTests {
result(post("/foo").param("k1", "a&b")));
}
@Test
public void putRequestWithOneParameter() throws IOException {
this.snippet.expectCurlRequest("put-request-with-one-parameter").withContents(
codeBlock("bash").content(
"$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'"));
documentCurlRequest("put-request-with-one-parameter").handle(
result(put("/foo").param("k1", "v1")));
}
@Test
public void putRequestWithMultipleParameters() throws IOException {
this.snippet.expectCurlRequest("put-request-with-multiple-parameters")
.withContents(
codeBlock("bash").content(
"$ curl 'http://localhost/foo' -i -X PUT"
+ " -d 'k1=v1&k1=v1-bis&k2=v2'"));
documentCurlRequest("put-request-with-multiple-parameters").handle(
result(put("/foo").param("k1", "v1", "v1-bis").param("k2", "v2")));
}
@Test
public void putRequestWithUrlEncodedParameter() throws IOException {
this.snippet.expectCurlRequest("put-request-with-url-encoded-parameter")
.withContents(
codeBlock("bash").content(
"$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'"));
documentCurlRequest("put-request-with-url-encoded-parameter").handle(
result(put("/foo").param("k1", "a&b")));
}
@Test
public void requestWithHeaders() throws IOException {
this.snippet.expectCurlRequest("request-with-headers").withContents(

View File

@@ -25,8 +25,10 @@ import static org.springframework.restdocs.test.SnippetMatchers.httpResponse;
import static org.springframework.restdocs.test.StubMvcResult.result;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
import java.io.IOException;
@@ -40,6 +42,7 @@ import org.springframework.restdocs.test.ExpectedSnippet;
* Tests for {@link HttpDocumentation}
*
* @author Andy Wilkinson
* @author Jonathan Pearlin
*/
public class HttpDocumentationTests {
@@ -94,6 +97,27 @@ public class HttpDocumentationTests {
result(post("/foo").param("b&r", "baz").param("a", "alpha")));
}
@Test
public void putRequestWithContent() throws IOException {
this.snippet.expectHttpRequest("put-request-with-content").withContents(
httpRequest(PUT, "/foo") //
.content("Hello, world"));
documentHttpRequest("put-request-with-content").handle(
result(put("/foo").content("Hello, world")));
}
@Test
public void putRequestWithParameter() throws IOException {
this.snippet.expectHttpRequest("put-request-with-parameter").withContents(
httpRequest(PUT, "/foo") //
.header("Content-Type", "application/x-www-form-urlencoded") //
.content("b%26r=baz&a=alpha"));
documentHttpRequest("put-request-with-parameter").handle(
result(put("/foo").param("b&r", "baz").param("a", "alpha")));
}
@Test
public void basicResponse() throws IOException {
this.snippet.expectHttpResponse("basic-response").withContents(httpResponse(OK));