Polish "Add support for documenting request and response cookies"

See gh-592
This commit is contained in:
Andy Wilkinson
2022-03-24 17:32:42 +00:00
parent f72a9f1067
commit d5522f5335
26 changed files with 480 additions and 309 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2022 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.
@@ -17,13 +17,16 @@
package org.springframework.restdocs.cookies;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.snippet.SnippetException;
import org.springframework.restdocs.snippet.TemplatedSnippet;
import org.springframework.util.Assert;
@@ -31,17 +34,15 @@ import org.springframework.util.Assert;
* Abstract {@link TemplatedSnippet} subclass that provides a base for snippets that
* document a RESTful resource's request or response cookies.
*
* @author Andreas Evers
* @author Clyde Stubbs
* @since 2.1
* @author Andy Wilkinson
* @since 3.0
*/
public abstract class AbstractCookiesSnippet extends TemplatedSnippet {
private List<CookieDescriptor> cookieDescriptors;
private final Map<String, CookieDescriptor> descriptorsByName = new LinkedHashMap<>();
protected final boolean ignoreUndocumentedCookies;
private String type;
private final boolean ignoreUndocumentedCookies;
/**
* Creates a new {@code AbstractCookiesSnippet} that will produce a snippet named
@@ -57,58 +58,53 @@ public abstract class AbstractCookiesSnippet extends TemplatedSnippet {
boolean ignoreUndocumentedCookies) {
super(type + "-cookies", attributes);
for (CookieDescriptor descriptor : descriptors) {
Assert.notNull(descriptor.getName(), "The name of the cookie must not be null");
Assert.notNull(descriptor.getName(), "Cookie descriptors must have a name");
if (!descriptor.isIgnored()) {
Assert.notNull(descriptor.getDescription(), "The description of the cookie must not be null");
Assert.notNull(descriptor.getDescription(), "The descriptor for cookie '" + descriptor.getName()
+ "' must either have a description or be marked as ignored");
}
this.descriptorsByName.put(descriptor.getName(), descriptor);
}
this.cookieDescriptors = descriptors;
this.type = type;
this.ignoreUndocumentedCookies = ignoreUndocumentedCookies;
}
@Override
protected Map<String, Object> createModel(Operation operation) {
validateCookieDocumentation(operation);
verifyCookieDescriptors(operation);
Map<String, Object> model = new HashMap<>();
List<Map<String, Object>> cookies = new ArrayList<>();
model.put("cookies", cookies);
for (CookieDescriptor descriptor : this.cookieDescriptors) {
cookies.add(createModelForDescriptor(descriptor));
for (CookieDescriptor descriptor : this.descriptorsByName.values()) {
if (!descriptor.isIgnored()) {
cookies.add(createModelForDescriptor(descriptor));
}
}
model.put("cookies", cookies);
return model;
}
private void validateCookieDocumentation(Operation operation) {
List<CookieDescriptor> missingCookies = findMissingCookies(operation);
if (!missingCookies.isEmpty()) {
List<String> names = new ArrayList<>();
for (CookieDescriptor cookieDescriptor : missingCookies) {
names.add(cookieDescriptor.getName());
}
throw new SnippetException(
"Cookies with the following names were not found" + " in the " + this.type + ": " + names);
}
}
/**
* Finds the cookies that are missing from the operation. A cookie is missing if it is
* described by one of the {@code cookieDescriptors} but is not present in the
* operation.
* @param operation the operation
* @return descriptors for the cookies that are missing from the operation
*/
protected List<CookieDescriptor> findMissingCookies(Operation operation) {
List<CookieDescriptor> missingCookies = new ArrayList<>();
private void verifyCookieDescriptors(Operation operation) {
Set<String> actualCookies = extractActualCookies(operation);
for (CookieDescriptor cookieDescriptor : this.cookieDescriptors) {
if (!cookieDescriptor.isOptional() && !actualCookies.contains(cookieDescriptor.getName())) {
missingCookies.add(cookieDescriptor);
Set<String> expectedCookies = new HashSet<>();
for (Entry<String, CookieDescriptor> entry : this.descriptorsByName.entrySet()) {
if (!entry.getValue().isOptional()) {
expectedCookies.add(entry.getKey());
}
}
Set<String> undocumentedCookies;
if (this.ignoreUndocumentedCookies) {
undocumentedCookies = Collections.emptySet();
}
else {
undocumentedCookies = new HashSet<>(actualCookies);
undocumentedCookies.removeAll(this.descriptorsByName.keySet());
}
Set<String> missingCookies = new HashSet<>(expectedCookies);
missingCookies.removeAll(actualCookies);
return missingCookies;
if (!undocumentedCookies.isEmpty() || !missingCookies.isEmpty()) {
verificationFailed(undocumentedCookies, missingCookies);
}
}
/**
@@ -119,13 +115,30 @@ public abstract class AbstractCookiesSnippet extends TemplatedSnippet {
*/
protected abstract Set<String> extractActualCookies(Operation operation);
/**
* Called when the documented cookies do not match the actual cookies.
* @param undocumentedCookies the cookies that were found in the operation but were
* not documented
* @param missingCookies the cookies that were documented but were not found in the
* operation
*/
protected abstract void verificationFailed(Set<String> undocumentedCookies, Set<String> missingCookies);
/**
* Returns the list of {@link CookieDescriptor CookieDescriptors} that will be used to
* generate the documentation.
* @return the cookie descriptors
*/
protected final List<CookieDescriptor> getCookieDescriptors() {
return this.cookieDescriptors;
protected final Map<String, CookieDescriptor> getCookieDescriptors() {
return this.descriptorsByName;
}
/**
* Returns whether or not this snippet ignores undocumented cookies.
* @return {@code true} if undocumented cookies are ignored, otherwise {@code false}
*/
protected final boolean isIgnoreUndocumentedCookies() {
return this.ignoreUndocumentedCookies;
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2022 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.
@@ -21,9 +21,9 @@ import org.springframework.restdocs.snippet.IgnorableDescriptor;
/**
* A description of a cookie found in a request or response.
*
* @author Andreas Evers
* @author Clyde Stubbs
* @since 2.1
* @author Andy Wilkinson
* @since 3.0
* @see CookieDocumentation#cookieWithName(String)
*/
public class CookieDescriptor extends IgnorableDescriptor<CookieDescriptor> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2022 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.
@@ -25,11 +25,9 @@ import org.springframework.restdocs.snippet.Snippet;
/**
* Static factory methods for documenting a RESTful API's request and response cookies.
*
* @author Andreas Evers
* @author Andy Wilkinson
* @author Marcel Overdijk
* @author Clyde Stubbs
* @since 2.1
* @author Andy Wilkinson
* @since 3.0
*/
public abstract class CookieDocumentation {
@@ -51,8 +49,10 @@ public abstract class CookieDocumentation {
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* request. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur.
* If a cookie is present in the request, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the request,
* a failure will also occur.
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
* @see #cookieWithName(String)
@@ -65,8 +65,10 @@ public abstract class CookieDocumentation {
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* request. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur.
* If a cookie is present in the request, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the request,
* a failure will also occur.
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
* @see #cookieWithName(String)
@@ -75,13 +77,43 @@ public abstract class CookieDocumentation {
return new RequestCookiesSnippet(descriptors);
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* request. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur. Any undocumented cookies will be ignored.
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
* @see #cookieWithName(String)
*/
public static RequestCookiesSnippet relaxedRequestCookies(CookieDescriptor... descriptors) {
return relaxedRequestCookies(Arrays.asList(descriptors));
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* request. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur. Any undocumented cookies will be ignored.
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
* @see #cookieWithName(String)
*/
public static RequestCookiesSnippet relaxedRequestCookies(List<CookieDescriptor> descriptors) {
return new RequestCookiesSnippet(descriptors, true);
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API
* operations's request. The given {@code attributes} will be available during snippet
* generation and the cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur.
* If a cookie is present in the request, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the request,
* a failure will also occur.
* @param attributes the attributes
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
@@ -97,9 +129,10 @@ public abstract class CookieDocumentation {
* operations's request. The given {@code attributes} will be available during snippet
* generation and the cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur. Any cookies present in the request that are not
* documented will result in an error.
* If a cookie is present in the request, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the request,
* a failure will also occur.
* @param attributes the attributes
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
@@ -107,7 +140,7 @@ public abstract class CookieDocumentation {
*/
public static RequestCookiesSnippet requestCookies(Map<String, Object> attributes,
List<CookieDescriptor> descriptors) {
return new RequestCookiesSnippet(descriptors, attributes, false);
return new RequestCookiesSnippet(descriptors, attributes);
}
/**
@@ -116,8 +149,24 @@ public abstract class CookieDocumentation {
* generation and the cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur. An undocumented cookie in the request will not
* generate an error.
* request, a failure will occur. Any undocumented cookies will be ignored.
* @param attributes the attributes
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
* @see #cookieWithName(String)
*/
public static RequestCookiesSnippet relaxedRequestCookies(Map<String, Object> attributes,
CookieDescriptor... descriptors) {
return relaxedRequestCookies(attributes, Arrays.asList(descriptors));
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API
* operations's request. The given {@code attributes} will be available during snippet
* generation and the cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* request, a failure will occur. Any undocumented cookies will be ignored.
* @param attributes the attributes
* @param descriptors the descriptions of the request's cookies
* @return the snippet that will document the request cookies
@@ -132,8 +181,10 @@ public abstract class CookieDocumentation {
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* response. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional or ignored, and is not present
* in the request, a failure will occur.
* If a cookie is present in the response, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the
* response, a failure will also occur.
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
* @see #cookieWithName(String)
@@ -146,9 +197,10 @@ public abstract class CookieDocumentation {
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* response. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional or ignored, and is not present
* in the request, a failure will occur. If a cookie is present in the response but is
* undocumented a failure will occur.
* If a cookie is present in the response, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the
* response, a failure will also occur.
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
* @see #cookieWithName(String)
@@ -161,15 +213,28 @@ public abstract class CookieDocumentation {
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* response. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional or ignored, and is not present
* in the request, a failure will occur. No failure will occur if a cookie is present
* but undocumented.
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. Any undocumented cookies will be ignored.
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
* @see #cookieWithName(String)
*/
public static ResponseCookiesSnippet relaxedResponseCookies(CookieDescriptor... descriptors) {
return relaxedResponseCookies(Arrays.asList(descriptors));
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API operation's
* response. The cookies will be documented using the given {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. Any undocumented cookies will be ignored.
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
* @see #cookieWithName(String)
*/
public static ResponseCookiesSnippet relaxedResponseCookies(List<CookieDescriptor> descriptors) {
return new ResponseCookiesSnippet(descriptors, null, true);
return new ResponseCookiesSnippet(descriptors, true);
}
/**
@@ -178,9 +243,10 @@ public abstract class CookieDocumentation {
* snippet generation and the cookies will be documented using the given
* {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. If a cookie is present in the response but is
* undocumented a failure will occur.
* If a cookie is present in the response, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the
* response, a failure will also occur.
* @param attributes the attributes
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
@@ -197,9 +263,10 @@ public abstract class CookieDocumentation {
* snippet generation and the cookies will be documented using the given
* {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. If a cookie is present in the response but is
* undocumented a failure will occur.
* If a cookie is present in the response, but is not documented by one of the
* descriptors, a failure will occur when the snippet is invoked. Similarly, if a
* cookie is documented, is not marked as optional, and is not present in the
* response, a failure will also occur.
* @param attributes the attributes
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
@@ -207,7 +274,7 @@ public abstract class CookieDocumentation {
*/
public static ResponseCookiesSnippet responseCookies(Map<String, Object> attributes,
List<CookieDescriptor> descriptors) {
return new ResponseCookiesSnippet(descriptors, attributes, false);
return new ResponseCookiesSnippet(descriptors, attributes);
}
/**
@@ -217,8 +284,25 @@ public abstract class CookieDocumentation {
* {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. No failure will occur if a cookie is present but
* undocumented.
* response, a failure will occur. Any undocumented cookies will be ignored.
* @param attributes the attributes
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies
* @see #cookieWithName(String)
*/
public static ResponseCookiesSnippet relaxedResponseCookies(Map<String, Object> attributes,
CookieDescriptor... descriptors) {
return relaxedResponseCookies(attributes, Arrays.asList(descriptors));
}
/**
* Returns a new {@link Snippet} that will document the cookies of the API
* operations's response. The given {@code attributes} will be available during
* snippet generation and the cookies will be documented using the given
* {@code descriptors}.
* <p>
* If a cookie is documented, is not marked as optional, and is not present in the
* response, a failure will occur. Any undocumented cookies will be ignored.
* @param attributes the attributes
* @param descriptors the descriptions of the response's cookies
* @return the snippet that will document the response cookies

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2022 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.
@@ -26,14 +26,14 @@ import java.util.Set;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.operation.RequestCookie;
import org.springframework.restdocs.snippet.Snippet;
import org.springframework.restdocs.snippet.SnippetException;
/**
* A {@link Snippet} that documents the cookies in a request.
*
* @author Andreas Evers
* @author Andy Wilkinson
* @author Clyde Stubbs
* @since 2.1
* @author Andy Wilkinson
* @since 3.0
* @see CookieDocumentation#requestCookies(CookieDescriptor...)
* @see CookieDocumentation#requestCookies(Map, CookieDescriptor...)
*/
@@ -50,15 +50,14 @@ public class RequestCookiesSnippet extends AbstractCookiesSnippet {
/**
* Creates a new {@code RequestCookiesSnippet} that will document the cookies in the
* request using the given {@code descriptors}. The given {@code attributes} will be
* included in the model during template rendering.
* request using the given {@code descriptors}. If {@code ignoreUndocumentedCookies}
* is {@code true}, undocumented cookies will be ignored and will not trigger a
* failure.
* @param descriptors the descriptors
* @param attributes the additional attributes
* @param ignoreUndocumentedCookies if set undocumented cookies will be ignored
* @param ignoreUndocumentedCookies whether undocumented cookies should be ignored
*/
protected RequestCookiesSnippet(List<CookieDescriptor> descriptors, Map<String, Object> attributes,
boolean ignoreUndocumentedCookies) {
super("request", descriptors, attributes, ignoreUndocumentedCookies);
protected RequestCookiesSnippet(List<CookieDescriptor> descriptors, boolean ignoreUndocumentedCookies) {
this(descriptors, null, ignoreUndocumentedCookies);
}
/**
@@ -70,7 +69,20 @@ public class RequestCookiesSnippet extends AbstractCookiesSnippet {
* @param attributes the additional attributes
*/
protected RequestCookiesSnippet(List<CookieDescriptor> descriptors, Map<String, Object> attributes) {
super("request", descriptors, attributes, false);
this(descriptors, attributes, false);
}
/**
* Creates a new {@code RequestCookiesSnippet} that will document the cookies in the
* request using the given {@code descriptors}. The given {@code attributes} will be
* included in the model during template rendering.
* @param descriptors the descriptors
* @param attributes the additional attributes
* @param ignoreUndocumentedCookies whether undocumented cookies should be ignored
*/
protected RequestCookiesSnippet(List<CookieDescriptor> descriptors, Map<String, Object> attributes,
boolean ignoreUndocumentedCookies) {
super("request", descriptors, attributes, ignoreUndocumentedCookies);
}
@Override
@@ -82,6 +94,21 @@ public class RequestCookiesSnippet extends AbstractCookiesSnippet {
return actualCookies;
}
@Override
protected void verificationFailed(Set<String> undocumentedCookies, Set<String> missingCookies) {
String message = "";
if (!undocumentedCookies.isEmpty()) {
message += "Cookies with the following names were not documented: " + undocumentedCookies;
}
if (!missingCookies.isEmpty()) {
if (message.length() > 0) {
message += ". ";
}
message += "Cookies with the following names were not found in the request: " + missingCookies;
}
throw new SnippetException(message);
}
/**
* Returns a new {@code RequestCookiesSnippet} configured with this snippet's
* attributes and its descriptors combined with the given
@@ -101,9 +128,9 @@ public class RequestCookiesSnippet extends AbstractCookiesSnippet {
* @return the new snippet
*/
public final RequestCookiesSnippet and(List<CookieDescriptor> additionalDescriptors) {
List<CookieDescriptor> combinedDescriptors = new ArrayList<>(this.getCookieDescriptors());
List<CookieDescriptor> combinedDescriptors = new ArrayList<>(this.getCookieDescriptors().values());
combinedDescriptors.addAll(additionalDescriptors);
return new RequestCookiesSnippet(combinedDescriptors, getAttributes(), false);
return new RequestCookiesSnippet(combinedDescriptors, getAttributes(), isIgnoreUndocumentedCookies());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2022 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.
@@ -26,14 +26,14 @@ import java.util.stream.Collectors;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.operation.ResponseCookie;
import org.springframework.restdocs.snippet.Snippet;
import org.springframework.restdocs.snippet.SnippetException;
/**
* A {@link Snippet} that documents the cookies in a response.
*
* @author Andreas Evers
* @author Andy Wilkinson
* @author Clyde Stubbs
* @since 2.1
* @author Andy Wilkinson
* @since 3.0
* @see CookieDocumentation#responseCookies(CookieDescriptor...)
* @see CookieDocumentation#responseCookies(Map, CookieDescriptor...)
*/
@@ -50,14 +50,26 @@ public class ResponseCookiesSnippet extends AbstractCookiesSnippet {
/**
* Creates a new {@code ResponseCookiesSnippet} that will document the cookies in the
* response using the given {@code descriptors}. The given {@code attributes} will be
* included in the model during template rendering. Undocumented cookies will cause a
* response using the given {@code descriptors}. If {@code ignoreUndocumentedCookies}
* is {@code true}, undocumented cookies will be ignored and will not trigger a
* failure.
* @param descriptors the descriptors
* @param ignoreUndocumentedCookies whether undocumented cookies should be ignored
*/
protected ResponseCookiesSnippet(List<CookieDescriptor> descriptors, boolean ignoreUndocumentedCookies) {
this(descriptors, null, ignoreUndocumentedCookies);
}
/**
* Creates a new {@code ResponseCookiesSnippet} that will document the cookies in the
* response using the given {@code descriptors}. The given {@code attributes} will be
* included in the model during template rendering. Undocumented cookies will not be
* ignored.
* @param descriptors the descriptors
* @param attributes the additional attributes
*/
protected ResponseCookiesSnippet(List<CookieDescriptor> descriptors, Map<String, Object> attributes) {
super("response", descriptors, attributes, false);
this(descriptors, attributes, false);
}
/**
@@ -66,7 +78,7 @@ public class ResponseCookiesSnippet extends AbstractCookiesSnippet {
* included in the model during template rendering.
* @param descriptors the descriptors
* @param attributes the additional attributes
* @param ignoreUndocumentedCookies ignore any cookies that are undocumented
* @param ignoreUndocumentedCookies whether undocumented cookies should be ignored
*/
protected ResponseCookiesSnippet(List<CookieDescriptor> descriptors, Map<String, Object> attributes,
boolean ignoreUndocumentedCookies) {
@@ -78,6 +90,21 @@ public class ResponseCookiesSnippet extends AbstractCookiesSnippet {
return operation.getResponse().getCookies().stream().map(ResponseCookie::getName).collect(Collectors.toSet());
}
@Override
protected void verificationFailed(Set<String> undocumentedCookies, Set<String> missingCookies) {
String message = "";
if (!undocumentedCookies.isEmpty()) {
message += "Cookies with the following names were not documented: " + undocumentedCookies;
}
if (!missingCookies.isEmpty()) {
if (message.length() > 0) {
message += ". ";
}
message += "Cookies with the following names were not found in the response: " + missingCookies;
}
throw new SnippetException(message);
}
/**
* Returns a new {@code ResponseCookiesSnippet} configured with this snippet's
* attributes and its descriptors combined with the given
@@ -97,9 +124,9 @@ public class ResponseCookiesSnippet extends AbstractCookiesSnippet {
* @return the new snippet
*/
public final ResponseCookiesSnippet and(List<CookieDescriptor> additionalDescriptors) {
List<CookieDescriptor> combinedDescriptors = new ArrayList<>(this.getCookieDescriptors());
List<CookieDescriptor> combinedDescriptors = new ArrayList<>(this.getCookieDescriptors().values());
combinedDescriptors.addAll(additionalDescriptors);
return new ResponseCookiesSnippet(combinedDescriptors, getAttributes(), this.ignoreUndocumentedCookies);
return new ResponseCookiesSnippet(combinedDescriptors, getAttributes(), isIgnoreUndocumentedCookies());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2022 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2022 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.
@@ -71,7 +71,7 @@ public interface OperationResponse {
* Returns the {@link ResponseCookie cookies} returned with the response. If no
* cookies were returned an empty collection is returned.
* @return the cookies, never {@code null}
* @since 2.1
* @since 3.0
*/
Collection<ResponseCookie> getCookies();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2022 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.
@@ -20,7 +20,7 @@ package org.springframework.restdocs.operation;
* A representation of a Cookie returned in a response.
*
* @author Clyde Stubbs
* @since 2.1
* @since 3.0
*/
public final class ResponseCookie {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2022 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.