23
23
import java .util .Arrays ;
24
24
import java .util .Collection ;
25
25
import java .util .List ;
26
+ import java .util .function .Consumer ;
26
27
27
28
import org .assertj .core .api .AbstractCollectionAssert ;
28
29
import org .assertj .core .api .AbstractObjectAssert ;
29
30
import org .assertj .core .api .Assertions ;
30
31
import org .assertj .core .api .ObjectAssert ;
31
- import org .assertj .core .presentation .Representation ;
32
- import org .assertj .core .presentation .StandardRepresentation ;
33
32
34
33
import org .springframework .http .HttpHeaders ;
35
34
38
37
* {@link HttpHeaders}.
39
38
*
40
39
* @author Stephane Nicoll
40
+ * @author Simon Baslé
41
41
* @since 6.2
42
42
*/
43
43
public class HttpHeadersAssert extends AbstractObjectAssert <HttpHeadersAssert , HttpHeaders > {
@@ -50,15 +50,6 @@ public class HttpHeadersAssert extends AbstractObjectAssert<HttpHeadersAssert, H
50
50
public HttpHeadersAssert (HttpHeaders actual ) {
51
51
super (actual , HttpHeadersAssert .class );
52
52
as ("HTTP headers" );
53
- withRepresentation (new Representation () {
54
- @ Override
55
- public String toStringOf (Object object ) {
56
- if (object instanceof HttpHeaders headers ) {
57
- return headers .toString ();
58
- }
59
- return StandardRepresentation .STANDARD_REPRESENTATION .toStringOf (object );
60
- }
61
- });
62
53
this .namesAssert = Assertions .assertThat (actual .headerNames ())
63
54
.as ("HTTP header names" );
64
55
}
@@ -127,7 +118,23 @@ public HttpHeadersAssert doesNotContainHeaders(String... names) {
127
118
128
119
/**
129
120
* Verify that the actual HTTP headers contain a header with the given
130
- * {@code name} and {@link String} {@code value}.
121
+ * {@code name} that satisfies the given {@code valueRequirements}.
122
+ * @param name the name of an HTTP header that should not be present
123
+ * @param valueRequirements the group of assertions to run against the
124
+ * values of the header with the given name
125
+ */
126
+ @ SuppressWarnings ("unchecked" )
127
+ public HttpHeadersAssert hasHeaderSatisfying (String name , Consumer <List <String >> valueRequirements ) {
128
+ containsHeader (name );
129
+ Assertions .assertThat (this .actual .get (name ))
130
+ .as ("check primary value for HTTP header '%s'" , name )
131
+ .satisfies (values -> valueRequirements .accept ((List <String >) values ));
132
+ return this .myself ;
133
+ }
134
+
135
+ /**
136
+ * Verify that the actual HTTP headers contain a header with the given
137
+ * {@code name} and {@link String} primary {@code value}.
131
138
* @param name the name of the cookie
132
139
* @param value the expected value of the header
133
140
*/
@@ -141,7 +148,7 @@ public HttpHeadersAssert hasValue(String name, String value) {
141
148
142
149
/**
143
150
* Verify that the actual HTTP headers contain a header with the given
144
- * {@code name} and {@link Long} {@code value}.
151
+ * {@code name} and {@link Long} primary {@code value}.
145
152
* @param name the name of the cookie
146
153
* @param value the expected value of the header
147
154
*/
@@ -155,7 +162,7 @@ public HttpHeadersAssert hasValue(String name, long value) {
155
162
156
163
/**
157
164
* Verify that the actual HTTP headers contain a header with the given
158
- * {@code name} and {@link Instant} {@code value}.
165
+ * {@code name} and {@link Instant} primary {@code value}.
159
166
* @param name the name of the cookie
160
167
* @param value the expected value of the header
161
168
*/
@@ -167,6 +174,46 @@ public HttpHeadersAssert hasValue(String name, Instant value) {
167
174
return this .myself ;
168
175
}
169
176
177
+ /**
178
+ * Verify that the actual HTTP headers contain a header with the given
179
+ * {@code name} and {@link String} primary {@code value}.
180
+ * <p>This assertion fails if the header has secondary values.
181
+ * @param name the name of the cookie
182
+ * @param value the expected only value of the header
183
+ * @since 7.0
184
+ */
185
+ public HttpHeadersAssert hasSingleValue (String name , String value ) {
186
+ doesNotHaveSecondaryValues (name );
187
+ return hasValue (name , value );
188
+ }
189
+
190
+ /**
191
+ * Verify that the actual HTTP headers contain a header with the given
192
+ * {@code name} and {@link Long} primary {@code value}.
193
+ * <p>This assertion fails if the header has secondary values.
194
+ * @param name the name of the cookie
195
+ * @param value the expected value of the header
196
+ * @since 7.0
197
+ */
198
+ public HttpHeadersAssert hasSingleValue (String name , long value ) {
199
+ doesNotHaveSecondaryValues (name );
200
+ return hasValue (name , value );
201
+ }
202
+
203
+ /**
204
+ * Verify that the actual HTTP headers contain a header with the given
205
+ * {@code name} and {@link Instant} primary {@code value}.
206
+ * <p>This assertion fails if the header has secondary values.
207
+ * @param name the name of the cookie
208
+ * @param value the expected value of the header
209
+ * @since 7.0
210
+ */
211
+ public HttpHeadersAssert hasSingleValue (String name , Instant value ) {
212
+ doesNotHaveSecondaryValues (name );
213
+ return hasValue (name , value );
214
+ }
215
+
216
+
170
217
/**
171
218
* Verify that the given header has a full list of values exactly equal to
172
219
* the given list of values, and in the same order.
@@ -224,80 +271,13 @@ public HttpHeadersAssert isNotEmpty() {
224
271
*/
225
272
public HttpHeadersAssert hasSize (int expected ) {
226
273
this .namesAssert
227
- .as ("check headers have size '%i '" , expected )
274
+ .as ("check headers have size '%s '" , expected )
228
275
.hasSize (expected );
229
276
return this .myself ;
230
277
}
231
278
232
279
/**
233
- * Verify that the number of headers present is strictly greater than the
234
- * given boundary, when considering header names in a case-insensitive
235
- * manner.
236
- * @param boundary the given value to compare actual header size to
237
- */
238
- public HttpHeadersAssert hasSizeGreaterThan (int boundary ) {
239
- this .namesAssert
240
- .as ("check headers have size > '%i'" , boundary )
241
- .hasSizeGreaterThan (boundary );
242
- return this .myself ;
243
- }
244
-
245
- /**
246
- * Verify that the number of headers present is greater or equal to the
247
- * given boundary, when considering header names in a case-insensitive
248
- * manner.
249
- * @param boundary the given value to compare actual header size to
250
- */
251
- public HttpHeadersAssert hasSizeGreaterThanOrEqualTo (int boundary ) {
252
- this .namesAssert
253
- .as ("check headers have size >= '%i'" , boundary )
254
- .hasSizeGreaterThanOrEqualTo (boundary );
255
- return this .myself ;
256
- }
257
-
258
- /**
259
- * Verify that the number of headers present is strictly less than the
260
- * given boundary, when considering header names in a case-insensitive
261
- * manner.
262
- * @param boundary the given value to compare actual header size to
263
- */
264
- public HttpHeadersAssert hasSizeLessThan (int boundary ) {
265
- this .namesAssert
266
- .as ("check headers have size < '%i'" , boundary )
267
- .hasSizeLessThan (boundary );
268
- return this .myself ;
269
- }
270
-
271
- /**
272
- * Verify that the number of headers present is less than or equal to the
273
- * given boundary, when considering header names in a case-insensitive
274
- * manner.
275
- * @param boundary the given value to compare actual header size to
276
- */
277
- public HttpHeadersAssert hasSizeLessThanOrEqualTo (int boundary ) {
278
- this .namesAssert
279
- .as ("check headers have size <= '%i'" , boundary )
280
- .hasSizeLessThanOrEqualTo (boundary );
281
- return this .myself ;
282
- }
283
-
284
- /**
285
- * Verify that the number of headers present is between the given boundaries
286
- * (inclusive), when considering header names in a case-insensitive manner.
287
- * @param lowerBoundary the lower boundary compared to which actual size
288
- * should be greater than or equal to
289
- * @param higherBoundary the higher boundary compared to which actual size
290
- * should be less than or equal to
291
- */
292
- public HttpHeadersAssert hasSizeBetween (int lowerBoundary , int higherBoundary ) {
293
- this .namesAssert
294
- .as ("check headers have size between '%i' and '%i'" , lowerBoundary , higherBoundary )
295
- .hasSizeBetween (lowerBoundary , higherBoundary );
296
- return this .myself ;
297
- }
298
-
299
- /**
300
- * Verify that the number actual headers is the same as in the given
280
+ * Verify that the number of actual headers is the same as in the given
301
281
* {@code HttpHeaders}.
302
282
* @param other the {@code HttpHeaders} to compare size with
303
283
* @since 7.0
@@ -308,4 +288,17 @@ public HttpHeadersAssert hasSameSizeAs(HttpHeaders other) {
308
288
.hasSize (other .size ());
309
289
return this .myself ;
310
290
}
291
+
292
+
293
+ private HttpHeadersAssert doesNotHaveSecondaryValues (String name ) {
294
+ containsHeader (name );
295
+ List <String > values = this .actual .get (name );
296
+ int size = (values != null ) ? values .size () : 0 ;
297
+ Assertions .assertThat (size )
298
+ .withFailMessage ("Expected HTTP header '%s' to be present " +
299
+ "without secondary values, but found <%s> secondary values" , name , size - 1 )
300
+ .isOne ();
301
+ return this .myself ;
302
+ }
303
+
311
304
}
0 commit comments