Skip to content

Commit 9808e82

Browse files
committed
Refactor CookieAssertions
Fixes gh-31275 Signed-off-by: Rob Worsnop <[email protected]>
1 parent d65f5d4 commit 9808e82

File tree

4 files changed

+267
-410
lines changed

4 files changed

+267
-410
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.test.web;
18+
19+
import java.time.Duration;
20+
import java.util.function.Consumer;
21+
22+
import org.hamcrest.Matcher;
23+
import org.hamcrest.MatcherAssert;
24+
25+
import org.springframework.http.ResponseCookie;
26+
import org.springframework.test.util.AssertionErrors;
27+
import org.springframework.util.MultiValueMap;
28+
29+
import static org.hamcrest.MatcherAssert.assertThat;
30+
import static org.springframework.test.util.AssertionErrors.assertEquals;
31+
import static org.springframework.test.util.AssertionErrors.fail;
32+
33+
/**
34+
* Assertions on cookies of the response.
35+
*
36+
* @author Rob Worsnop
37+
* @since 7.0
38+
* @param <E> the type of the exchange result
39+
* @param <R> the type of the response spec
40+
*/
41+
public abstract class AbstractCookieAssertions<E, R> {
42+
protected final E exchangeResult;
43+
private final R responseSpec;
44+
45+
protected AbstractCookieAssertions(E exchangeResult, R responseSpec) {
46+
this.exchangeResult = exchangeResult;
47+
this.responseSpec = responseSpec;
48+
}
49+
50+
/**
51+
* Expect a response cookie with the given name to match the specified value.
52+
*/
53+
public R valueEquals(String name, String value) {
54+
ResponseCookie cookie = getCookie(name);
55+
String cookieValue = cookie.getValue();
56+
assertWithDiagnostics(() -> {
57+
String message = getMessage(name);
58+
AssertionErrors.assertEquals(message, value, cookieValue);
59+
});
60+
return this.responseSpec;
61+
}
62+
63+
/**
64+
* Assert the value of the response cookie with the given name with a Hamcrest
65+
* {@link Matcher}.
66+
*/
67+
public R value(String name, Matcher<? super String> matcher) {
68+
String value = getCookie(name).getValue();
69+
assertWithDiagnostics(() -> {
70+
String message = getMessage(name);
71+
MatcherAssert.assertThat(message, value, matcher);
72+
});
73+
return this.responseSpec;
74+
}
75+
76+
/**
77+
* Consume the value of the response cookie with the given name.
78+
*/
79+
public R value(String name, Consumer<String> consumer) {
80+
String value = getCookie(name).getValue();
81+
assertWithDiagnostics(() -> consumer.accept(value));
82+
return this.responseSpec;
83+
}
84+
85+
/**
86+
* Expect that the cookie with the given name is present.
87+
*/
88+
public R exists(String name) {
89+
getCookie(name);
90+
return this.responseSpec;
91+
}
92+
93+
/**
94+
* Expect that the cookie with the given name is not present.
95+
*/
96+
public R doesNotExist(String name) {
97+
ResponseCookie cookie = getResponseCookies().getFirst(name);
98+
if (cookie != null) {
99+
String message = getMessage(name) + " exists with value=[" + cookie.getValue() + "]";
100+
assertWithDiagnostics(() -> fail(message));
101+
}
102+
return this.responseSpec;
103+
}
104+
105+
/**
106+
* Assert a cookie's "Max-Age" attribute.
107+
*/
108+
public R maxAge(String name, Duration expected) {
109+
Duration maxAge = getCookie(name).getMaxAge();
110+
assertWithDiagnostics(() -> {
111+
String message = getMessage(name) + " maxAge";
112+
assertEquals(message, expected, maxAge);
113+
});
114+
return this.responseSpec;
115+
}
116+
117+
/**
118+
* Assert a cookie's "Max-Age" attribute with a Hamcrest {@link Matcher}.
119+
*/
120+
public R maxAge(String name, Matcher<? super Long> matcher) {
121+
long maxAge = getCookie(name).getMaxAge().getSeconds();
122+
assertWithDiagnostics(() -> {
123+
String message = getMessage(name) + " maxAge";
124+
assertThat(message, maxAge, matcher);
125+
});
126+
return this.responseSpec;
127+
}
128+
129+
/**
130+
* Assert a cookie's "Path" attribute.
131+
*/
132+
public R path(String name, String expected) {
133+
String path = getCookie(name).getPath();
134+
assertWithDiagnostics(() -> {
135+
String message = getMessage(name) + " path";
136+
assertEquals(message, expected, path);
137+
});
138+
return this.responseSpec;
139+
}
140+
141+
142+
143+
/**
144+
* Assert a cookie's "Path" attribute with a Hamcrest {@link Matcher}.
145+
*/
146+
public R path(String name, Matcher<? super String> matcher) {
147+
String path = getCookie(name).getPath();
148+
assertWithDiagnostics(() -> {
149+
String message = getMessage(name) + " path";
150+
assertThat(message, path, matcher);
151+
});
152+
return this.responseSpec;
153+
}
154+
155+
/**
156+
* Assert a cookie's "Domain" attribute.
157+
*/
158+
public R domain(String name, String expected) {
159+
String path = getCookie(name).getDomain();
160+
assertWithDiagnostics(() -> {
161+
String message = getMessage(name) + " domain";
162+
assertEquals(message, expected, path);
163+
});
164+
return this.responseSpec;
165+
}
166+
167+
/**
168+
* Assert a cookie's "Domain" attribute with a Hamcrest {@link Matcher}.
169+
*/
170+
public R domain(String name, Matcher<? super String> matcher) {
171+
String domain = getCookie(name).getDomain();
172+
assertWithDiagnostics(() -> {
173+
String message = getMessage(name) + " domain";
174+
assertThat(message, domain, matcher);
175+
});
176+
return this.responseSpec;
177+
}
178+
179+
/**
180+
* Assert a cookie's "Secure" attribute.
181+
*/
182+
public R secure(String name, boolean expected) {
183+
boolean isSecure = getCookie(name).isSecure();
184+
assertWithDiagnostics(() -> {
185+
String message = getMessage(name) + " secure";
186+
assertEquals(message, expected, isSecure);
187+
});
188+
return this.responseSpec;
189+
}
190+
191+
/**
192+
* Assert a cookie's "HttpOnly" attribute.
193+
*/
194+
public R httpOnly(String name, boolean expected) {
195+
boolean isHttpOnly = getCookie(name).isHttpOnly();
196+
assertWithDiagnostics(() -> {
197+
String message = getMessage(name) + " httpOnly";
198+
assertEquals(message, expected, isHttpOnly);
199+
});
200+
return this.responseSpec;
201+
}
202+
203+
/**
204+
* Assert a cookie's "Partitioned" attribute.
205+
*/
206+
public R partitioned(String name, boolean expected) {
207+
boolean isPartitioned = getCookie(name).isPartitioned();
208+
assertWithDiagnostics(() -> {
209+
String message = getMessage(name) + " isPartitioned";
210+
assertEquals(message, expected, isPartitioned);
211+
});
212+
return this.responseSpec;
213+
}
214+
215+
/**
216+
* Assert a cookie's "SameSite" attribute.
217+
*/
218+
public R sameSite(String name, String expected) {
219+
String sameSite = getCookie(name).getSameSite();
220+
assertWithDiagnostics(() -> {
221+
String message = getMessage(name) + " sameSite";
222+
assertEquals(message, expected, sameSite);
223+
});
224+
return this.responseSpec;
225+
}
226+
227+
protected abstract void assertWithDiagnostics(Runnable assertion);
228+
229+
protected abstract MultiValueMap<String, ResponseCookie> getResponseCookies();
230+
231+
private ResponseCookie getCookie(String name) {
232+
ResponseCookie cookie = getResponseCookies().getFirst(name);
233+
if (cookie != null) {
234+
return cookie;
235+
}
236+
else {
237+
assertWithDiagnostics(() -> fail("No cookie with name '" + name + "'"));
238+
}
239+
throw new IllegalStateException("This code path should not be reachable");
240+
}
241+
242+
private static String getMessage(String cookie) {
243+
return "Response cookie '" + cookie + "'";
244+
}
245+
}

0 commit comments

Comments
 (0)