Include cookies in request snippets
Closes gh-336 See gh-302, gh-303, gh-304
This commit is contained in:
committed by
Andy Wilkinson
parent
0337160e80
commit
25bc6c37da
@@ -25,6 +25,8 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
@@ -125,6 +127,11 @@ final class CliOperationRequest implements OperationRequest {
|
||||
return this.delegate.getUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Cookie> getCookies() {
|
||||
return this.delegate.getCookies();
|
||||
}
|
||||
|
||||
private interface HeaderFilter {
|
||||
|
||||
boolean allow(String name, List<String> value);
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.restdocs.operation.Operation;
|
||||
import org.springframework.restdocs.operation.OperationRequest;
|
||||
@@ -92,12 +94,28 @@ public class CurlRequestSnippet extends TemplatedSnippet {
|
||||
writeUserOptionIfNecessary(request, printer);
|
||||
writeHttpMethodIfNecessary(request, printer);
|
||||
writeHeaders(request, printer);
|
||||
writeCookies(request, printer);
|
||||
writePartsIfNecessary(request, printer);
|
||||
writeContent(request, printer);
|
||||
|
||||
return command.toString();
|
||||
}
|
||||
|
||||
private void writeCookies(CliOperationRequest request, PrintWriter printer) {
|
||||
if (request.getCookies() != null && request.getCookies().size() > 0) {
|
||||
printer.print(" --cookie ");
|
||||
StringBuilder cookiesBuilder = new StringBuilder();
|
||||
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
cookiesBuilder.append(String.format("%s=%s;", cookie.getName(), cookie.getValue()));
|
||||
}
|
||||
|
||||
String cookiesHeader = cookiesBuilder.substring(0, cookiesBuilder.length() - 1); // remove trailing semicolon
|
||||
|
||||
printer.print(String.format("'%s'", cookiesHeader)); // add single quotes
|
||||
}
|
||||
}
|
||||
|
||||
private void writeIncludeHeadersInOutputOption(PrintWriter writer) {
|
||||
writer.print("-i");
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -160,6 +162,10 @@ public class HttpieRequestSnippet extends TemplatedSnippet {
|
||||
writer.print(String.format(" '%s:%s'", entry.getKey(), header));
|
||||
}
|
||||
}
|
||||
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
writer.print(String.format(" 'Cookie:%s=%s'", cookie.getName(), cookie.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeParametersIfNecessary(CliOperationRequest request,
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -35,6 +37,7 @@ import org.springframework.restdocs.snippet.Snippet;
|
||||
import org.springframework.restdocs.snippet.TemplatedSnippet;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link Snippet} that documents an HTTP request.
|
||||
*
|
||||
@@ -112,6 +115,11 @@ public class HttpRequestSnippet extends TemplatedSnippet {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
headers.add(header(HttpHeaders.COOKIE, String.format("%s=%s", cookie.getName(), cookie.getValue())));
|
||||
}
|
||||
|
||||
if (requiresFormEncodingContentTypeHeader(request)) {
|
||||
headers.add(header(HttpHeaders.CONTENT_TYPE,
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE));
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.restdocs.operation;
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
@@ -86,4 +88,11 @@ public interface OperationRequest {
|
||||
*/
|
||||
URI getUri();
|
||||
|
||||
/**
|
||||
* Returns cookies sent with the request.
|
||||
*
|
||||
* @return the cookies
|
||||
*/
|
||||
Collection<Cookie> getCookies();
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.restdocs.operation;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -29,6 +32,28 @@ import org.springframework.http.HttpMethod;
|
||||
*/
|
||||
public class OperationRequestFactory {
|
||||
|
||||
/**
|
||||
* Creates a new {@link OperationRequest}. The given {@code headers} will be augmented
|
||||
* to ensure that they always include a {@code Content-Length} header if the request
|
||||
* has any content and a {@code Host} header.
|
||||
*
|
||||
* @param uri the request's uri
|
||||
* @param method the request method
|
||||
* @param content the content of the request
|
||||
* @param headers the request's headers
|
||||
* @param parameters the request's parameters
|
||||
* @param parts the request's parts
|
||||
* @param cookies the request's cookies
|
||||
* @return the {@code OperationRequest}
|
||||
*/
|
||||
public OperationRequest create(URI uri, HttpMethod method, byte[] content,
|
||||
HttpHeaders headers, Parameters parameters,
|
||||
Collection<OperationRequestPart> parts,
|
||||
Collection<Cookie> cookies) {
|
||||
return new StandardOperationRequest(uri, method, content,
|
||||
augmentHeaders(headers, uri, content), parameters, parts, cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link OperationRequest}. The given {@code headers} will be augmented
|
||||
* to ensure that they always include a {@code Content-Length} header if the request
|
||||
@@ -45,8 +70,7 @@ public class OperationRequestFactory {
|
||||
public OperationRequest create(URI uri, HttpMethod method, byte[] content,
|
||||
HttpHeaders headers, Parameters parameters,
|
||||
Collection<OperationRequestPart> parts) {
|
||||
return new StandardOperationRequest(uri, method, content,
|
||||
augmentHeaders(headers, uri, content), parameters, parts);
|
||||
return create(uri, method, content, headers, parameters, parts, Collections.<Cookie>emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +86,7 @@ public class OperationRequestFactory {
|
||||
public OperationRequest createFrom(OperationRequest original, byte[] newContent) {
|
||||
return new StandardOperationRequest(original.getUri(), original.getMethod(),
|
||||
newContent, getUpdatedHeaders(original.getHeaders(), newContent),
|
||||
original.getParameters(), original.getParts());
|
||||
original.getParameters(), original.getParts(), original.getCookies());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +102,7 @@ public class OperationRequestFactory {
|
||||
HttpHeaders newHeaders) {
|
||||
return new StandardOperationRequest(original.getUri(), original.getMethod(),
|
||||
original.getContent(), newHeaders, original.getParameters(),
|
||||
original.getParts());
|
||||
original.getParts(), original.getCookies());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +118,7 @@ public class OperationRequestFactory {
|
||||
Parameters newParameters) {
|
||||
return new StandardOperationRequest(original.getUri(), original.getMethod(),
|
||||
original.getContent(), original.getHeaders(), newParameters,
|
||||
original.getParts());
|
||||
original.getParts(), original.getCookies());
|
||||
}
|
||||
|
||||
private HttpHeaders augmentHeaders(HttpHeaders originalHeaders, URI uri,
|
||||
|
||||
@@ -20,6 +20,8 @@ import java.net.URI;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
|
||||
@@ -39,6 +41,8 @@ class StandardOperationRequest extends AbstractOperationMessage
|
||||
|
||||
private URI uri;
|
||||
|
||||
private Collection<Cookie> cookies;
|
||||
|
||||
/**
|
||||
* Creates a new request with the given {@code uri} and {@code method}. The request
|
||||
* will have the given {@code headers}, {@code parameters}, and {@code parts}.
|
||||
@@ -52,12 +56,14 @@ class StandardOperationRequest extends AbstractOperationMessage
|
||||
*/
|
||||
StandardOperationRequest(URI uri, HttpMethod method, byte[] content,
|
||||
HttpHeaders headers, Parameters parameters,
|
||||
Collection<OperationRequestPart> parts) {
|
||||
Collection<OperationRequestPart> parts,
|
||||
Collection<Cookie> cookies) {
|
||||
super(content, headers);
|
||||
this.uri = uri;
|
||||
this.method = method;
|
||||
this.parameters = parameters;
|
||||
this.parts = parts;
|
||||
this.cookies = cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,4 +86,9 @@ class StandardOperationRequest extends AbstractOperationMessage
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Cookie> getCookies() {
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -251,6 +251,17 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests {
|
||||
.header("a", "alpha").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWithCookies() throws IOException {
|
||||
this.snippets.expectCurlRequest()
|
||||
.withContents(codeBlock("bash").content("$ curl 'http://localhost/foo' -i" +
|
||||
" --cookie 'name1=value1;name2=value2'"));
|
||||
new CurlRequestSnippet()
|
||||
.document(this.operationBuilder.request("http://localhost/foo")
|
||||
.cookie("name1", "value1")
|
||||
.cookie("name2", "value2").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipartPostWithNoSubmittedFileName() throws IOException {
|
||||
String expectedContent = "$ curl 'http://localhost/upload' -i -X POST -H "
|
||||
|
||||
@@ -252,6 +252,17 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests {
|
||||
.header("a", "alpha").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestWithCookies() throws IOException {
|
||||
this.snippets.expectHttpieRequest().withContents(
|
||||
codeBlock("bash").content("$ http GET 'http://localhost/foo'" +
|
||||
" 'Cookie:name1=value1' 'Cookie:name2=value2'"));
|
||||
new HttpieRequestSnippet()
|
||||
.document(this.operationBuilder.request("http://localhost/foo")
|
||||
.cookie("name1", "value1")
|
||||
.cookie("name2", "value2").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipartPostWithNoSubmittedFileName() throws IOException {
|
||||
String expectedContent = String
|
||||
|
||||
@@ -54,7 +54,7 @@ public class RequestHeadersSnippetTests extends AbstractSnippetTests {
|
||||
.row("`X-Test`", "one").row("`Accept`", "two")
|
||||
.row("`Accept-Encoding`", "three")
|
||||
.row("`Accept-Language`", "four").row("`Cache-Control`", "five")
|
||||
.row("`Connection`", "six"));
|
||||
.row("`Connection`", "six").row("`Cookie`", "seven"));
|
||||
new RequestHeadersSnippet(
|
||||
Arrays.asList(headerWithName("X-Test").description("one"),
|
||||
headerWithName("Accept").description("two"),
|
||||
@@ -63,7 +63,8 @@ public class RequestHeadersSnippetTests extends AbstractSnippetTests {
|
||||
headerWithName("Cache-Control").description("five"),
|
||||
headerWithName(
|
||||
"Connection")
|
||||
.description("six")))
|
||||
.description("six"),
|
||||
headerWithName("Cookie").description("seven")))
|
||||
.document(
|
||||
this.operationBuilder
|
||||
.request(
|
||||
@@ -78,6 +79,8 @@ public class RequestHeadersSnippetTests extends AbstractSnippetTests {
|
||||
"max-age=0")
|
||||
.header("Connection",
|
||||
"keep-alive")
|
||||
.header("Cookie",
|
||||
"cookie1=cookieVal1; cookie2=cookieVal2")
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,21 @@ public class HttpRequestSnippetTests extends AbstractSnippetTests {
|
||||
.request("http://localhost:8080/foo").header("Alpha", "a").build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestWithCookies() throws IOException {
|
||||
this.snippets.expectHttpRequest()
|
||||
.withContents(httpRequest(RequestMethod.GET, "/foo")
|
||||
.header(HttpHeaders.HOST, "localhost")
|
||||
.header(HttpHeaders.COOKIE, "name1=value1")
|
||||
.header(HttpHeaders.COOKIE, "name2=value2"));
|
||||
|
||||
new HttpRequestSnippet()
|
||||
.document(this.operationBuilder.request("http://localhost/foo")
|
||||
.cookie("name1", "value1")
|
||||
.cookie("name2", "value2")
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestWithQueryString() throws IOException {
|
||||
this.snippets.expectHttpRequest()
|
||||
|
||||
@@ -19,11 +19,14 @@ package org.springframework.restdocs.test;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -153,6 +156,8 @@ public class OperationBuilder extends OperationTestRule {
|
||||
|
||||
private List<OperationRequestPartBuilder> partBuilders = new ArrayList<>();
|
||||
|
||||
private Collection<Cookie> cookies = new ArrayList<>();
|
||||
|
||||
private OperationRequestBuilder(String uri) {
|
||||
this.requestUri = URI.create(uri);
|
||||
}
|
||||
@@ -163,7 +168,7 @@ public class OperationBuilder extends OperationTestRule {
|
||||
parts.add(builder.buildPart());
|
||||
}
|
||||
return new OperationRequestFactory().create(this.requestUri, this.method,
|
||||
this.content, this.headers, this.parameters, parts);
|
||||
this.content, this.headers, this.parameters, parts, this.cookies);
|
||||
}
|
||||
|
||||
public Operation build() {
|
||||
@@ -209,6 +214,11 @@ public class OperationBuilder extends OperationTestRule {
|
||||
return partBuilder;
|
||||
}
|
||||
|
||||
public OperationRequestBuilder cookie(String name, String value) {
|
||||
this.cookies.add(new Cookie(name, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic builder API for creating an {@link OperationRequestPart}.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user