1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.http.header;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.http.HttpHeaders.*;
22 import static org.apache.juneau.junit.bct.BctAssertions.*;
23 import static org.junit.jupiter.api.Assertions.*;
24
25 import java.util.*;
26 import java.util.concurrent.atomic.*;
27
28 import org.apache.http.*;
29 import org.apache.juneau.*;
30 import org.apache.juneau.httppart.*;
31 import org.apache.juneau.oapi.*;
32 import org.junit.jupiter.api.*;
33
34
35
36
37 class HeaderList_Test extends TestBase {
38
39 private static final Header
40 FOO_1 = header("Foo","1"),
41 FOO_2 = header("Foo","2"),
42 FOO_3 = header("Foo","3"),
43 FOO_4 = header("Foo","4"),
44 FOO_5 = header("Foo","5"),
45 FOO_6 = header("Foo","6"),
46 FOO_7 = header("Foo","7"),
47 BAR_1 = header("Bar","1"),
48 BAR_2 = header("Bar","2"),
49
50 X_x = header("X", "x");
51
52 @Test void a01_basic() {
53 var x = HeaderList.create();
54 assertEmpty(x);
55 assertList(x.append(FOO_1), "Foo: 1");
56 assertList(x.append(FOO_2), "Foo: 1", "Foo: 2");
57 assertList(x.append(HeaderList.of().getAll()), "Foo: 1", "Foo: 2");
58 assertList(x.append(HeaderList.of(FOO_3).getAll()), "Foo: 1", "Foo: 2", "Foo: 3");
59 assertList(x.append(HeaderList.of(FOO_4, FOO_5).getAll()), "Foo: 1", "Foo: 2", "Foo: 3", "Foo: 4", "Foo: 5");
60 assertList(x.append(HeaderList.of(FOO_6, FOO_7).getAll()), "Foo: 1", "Foo: 2", "Foo: 3", "Foo: 4", "Foo: 5", "Foo: 6", "Foo: 7");
61 assertList(x.append((Header)null), "Foo: 1", "Foo: 2", "Foo: 3", "Foo: 4", "Foo: 5", "Foo: 6", "Foo: 7");
62 assertList(x.append((List<Header>)null), "Foo: 1", "Foo: 2", "Foo: 3", "Foo: 4", "Foo: 5", "Foo: 6", "Foo: 7");
63 assertEmpty(new HeaderList.Void());
64 }
65
66 @Test void a02_creators() {
67 assertList(headerList(FOO_1, FOO_2, null), "Foo: 1", "Foo: 2");
68 assertList(headerList(l(FOO_1, FOO_2, null)), "Foo: 1", "Foo: 2");
69 assertList(headerList("Foo","1","Foo","2"), "Foo: 1", "Foo: 2");
70 assertThrowsWithMessage(IllegalArgumentException.class, "Odd number of parameters passed into HeaderList.ofPairs()", ()->headerList("Foo"));
71 assertEmpty(HeaderList.of((List<Header>)null));
72 assertEmpty(HeaderList.of(Collections.emptyList()));
73 assertList(HeaderList.of(l(FOO_1)), "Foo: 1");
74 assertEmpty(HeaderList.of((Header[])null));
75 assertEmpty(HeaderList.of());
76 assertList(HeaderList.of(FOO_1), "Foo: 1");
77 assertEmpty(HeaderList.ofPairs((String[])null));
78 assertEmpty(HeaderList.ofPairs());
79 }
80
81 @Test void a03_addMethods() {
82 var pname = "HeaderSupplierTest.x";
83
84 var x = HeaderList.create().resolving();
85 System.setProperty(pname, "y");
86
87 x.append("X1","bar");
88 x.append("X2","$S{"+pname+"}");
89 x.append("X3","bar");
90 x.append("X4",()->"$S{"+pname+"}");
91 x.append(SerializedHeader.of("X5","bar",openApiSession(),null,false));
92
93 assertList(x, "X1: bar", "X2: y", "X3: bar", "X4: y", "X5: bar");
94
95 System.setProperty(pname, "z");
96
97 assertList(x, "X1: bar", "X2: z", "X3: bar", "X4: z", "X5: bar");
98
99 System.clearProperty(pname);
100 }
101
102 @Test void a04_toArrayMethods() {
103 var x = HeaderList
104 .create()
105 .append("X1","1")
106 .append(headerList("X2","2").getAll());
107 assertList(x, "X1: 1", "X2: 2");
108 }
109
110 @Test void a05_copy() {
111 var x = HeaderList.of(FOO_1).copy();
112 assertList(x, "Foo: 1");
113 }
114
115 @Test void a06_getCondensed() {
116 var x = HeaderList.of(FOO_1);
117 assertEmpty(x.get((String)null));
118 assertString("Foo: 1", x.get("Foo"));
119 assertEmpty(x.get("Bar"));
120 x = HeaderList.of(FOO_1, FOO_2, FOO_3, X_x);
121 assertString("Foo: 1, 2, 3", x.get("Foo"));
122 assertEmpty(x.get("Bar"));
123 }
124
125 @org.apache.juneau.http.annotation.Header("Foo")
126 static class Foo extends BasicStringHeader {
127 private static final long serialVersionUID = 1L;
128
129 public Foo(String value) {
130 super("Foo", value);
131 }
132 }
133
134 @Test void a07_getCondensed_asType() {
135 var x = HeaderList.of(FOO_1);
136 assertEmpty(x.get(null, Allow.class));
137 assertString("Allow: 1", x.get("Foo", Allow.class));
138 assertEmpty(x.get("Bar", Allow.class));
139 x = HeaderList.of(FOO_1, FOO_2, FOO_3, X_x);
140 assertString("Allow: 1, 2, 3", x.get("Foo", Allow.class));
141 assertEmpty(x.get("Bar", Allow.class));
142 assertString("Foo: 1, 2, 3", x.get(Foo.class));
143 final var x2 = x;
144 assertThrowsWithMessage(IllegalArgumentException.class, "Header name could not be found on bean type 'java.lang.String'", ()->x2.get(String.class));
145 }
146
147 @Test void a08_get() {
148 var x = HeaderList.of(FOO_1, FOO_2, X_x);
149 assertEmpty(x.getAll(null));
150 assertList(x.getAll("Foo"), "Foo: 1", "Foo: 2");
151 assertList(x.getAll("FOO"), "Foo: 1", "Foo: 2");
152 assertEmpty(x.getAll("Bar"));
153 }
154
155 @Test void a09_getFirst() {
156 var x = HeaderList.of(FOO_1, FOO_2, X_x);
157 assertEmpty(x.getFirst(null));
158 assertString("Foo: 1", x.getFirst("Foo"));
159 assertString("Foo: 1", x.getFirst("FOO"));
160 assertEmpty(x.getFirst("Bar"));
161 }
162
163 @Test void a10_getLast() {
164 var x = HeaderList.of(FOO_1, FOO_2, X_x);
165 assertEmpty(x.getLast(null));
166 assertString("Foo: 2", x.getLast("Foo"));
167 assertString("Foo: 2", x.getLast("FOO"));
168 assertEmpty(x.getLast("Bar"));
169 }
170
171 @Test void a11_contains() {
172 var x = HeaderList.of(FOO_1, FOO_2, X_x);
173 assertFalse(x.contains(null));
174 assertTrue(x.contains("Foo"));
175 assertTrue(x.contains("FOO"));
176 assertFalse(x.contains("Bar"));
177 }
178
179 @Test void a12_headerIterator_all() {
180 assertFalse(HeaderList.of().headerIterator().hasNext());
181 assertTrue(HeaderList.of(FOO_1).headerIterator().hasNext());
182 }
183
184 @Test void a13_headerIterator_single() {
185 var x = HeaderList.of();
186 assertFalse(x.headerIterator("Foo").hasNext());
187 x = HeaderList.of(FOO_1);
188 assertTrue(x.headerIterator("Foo").hasNext());
189 assertTrue(x.headerIterator("FOO").hasNext());
190 }
191
192 @Test void a14_forEach_all() {
193 var x = HeaderList.of();
194
195 var i1 = new AtomicInteger();
196 x.forEach(h -> i1.incrementAndGet());
197 assertEquals(0, i1.get());
198
199 x = HeaderList.of(FOO_1, FOO_2);
200 var i2 = new AtomicInteger();
201 x.forEach(h -> i2.incrementAndGet());
202 assertEquals(2, i2.get());
203 }
204
205 @Test void a15_forEach_single() {
206 var x = HeaderList.of();
207
208 var i1 = new AtomicInteger();
209 x.forEach("FOO", h -> i1.incrementAndGet());
210 assertEquals(0, i1.get());
211
212 x = HeaderList.of(FOO_1, FOO_2, X_x);
213 var i2 = new AtomicInteger();
214 x.forEach("FOO", h -> i2.incrementAndGet());
215 assertEquals(2, i2.get());
216 }
217
218 @Test void a16_stream_all() {
219 var x = HeaderList.of();
220
221 var i1 = new AtomicInteger();
222 x.stream().forEach(h -> i1.incrementAndGet());
223 assertEquals(0, i1.get());
224
225 x = HeaderList.of(FOO_1, FOO_2);
226 var i2 = new AtomicInteger();
227 x.stream().forEach(h -> i2.incrementAndGet());
228 assertEquals(2, i2.get());
229 }
230
231 @Test void a17_stream_single() {
232 var x = HeaderList.of();
233
234 var i1 = new AtomicInteger();
235 x.stream("FOO").forEach(h -> i1.incrementAndGet());
236 assertEquals(0, i1.get());
237
238 x = HeaderList.of(FOO_1, FOO_2, X_x);
239 var i2 = new AtomicInteger();
240 x.stream("FOO").forEach(h -> i2.incrementAndGet());
241 assertEquals(2, i2.get());
242 }
243
244 @Test void a18_caseSensitive() {
245 var x = HeaderList.create().caseSensitive(true).append(FOO_1, FOO_2, X_x);
246 assertList(x.getAll("Foo"), "Foo: 1", "Foo: 2");
247 assertEmpty(x.getAll("FOO"));
248 }
249
250 @Test void a19_size() {
251 assertSize(1, HeaderList.of(FOO_1));
252 }
253
254
255
256
257
258 @Test void b01_builder_clear() {
259 var x = HeaderList.create().append(FOO_1);
260 x.clear();
261 assertEmpty(x);
262 }
263
264 @Test void b02_builder_append() {
265 var x1 = HeaderList.create().append(FOO_1);
266 var x2 = HeaderList
267 .create()
268 .append()
269 .append((HeaderList)null)
270 .append((Header)null)
271 .append((Header[])null)
272 .append(x1)
273 .append(FOO_2, FOO_3)
274 .append("Bar", "b1")
275 .append("Bar", ()->"b2")
276 .append((List<Header>)null)
277 .append(l(FOO_4));
278 assertList(x2, "Foo: 1", "Foo: 2", "Foo: 3", "Bar: b1", "Bar: b2", "Foo: 4");
279 }
280
281 @Test void b03_builder_prepend() {
282 var x1 = HeaderList.create().append(FOO_1);
283 var x2 = HeaderList
284 .create()
285 .prepend()
286 .prepend((HeaderList)null)
287 .prepend((Header)null)
288 .prepend((Header[])null)
289 .prepend(x1)
290 .prepend(FOO_2, FOO_3)
291 .prepend("Bar", "b1")
292 .prepend("Bar", ()->"b2")
293 .prepend((List<Header>)null)
294 .prepend(l(FOO_4));
295 assertList(x2, "Foo: 4", "Bar: b2", "Bar: b1", "Foo: 2", "Foo: 3", "Foo: 1");
296 }
297
298 @Test void b04_builder_remove() {
299 var x = HeaderList
300 .create()
301 .append(FOO_1,FOO_2,FOO_3,FOO_4,FOO_5,FOO_6,FOO_7)
302 .remove((HeaderList)null)
303 .remove((Header)null)
304 .remove(HeaderList.of(FOO_1))
305 .remove(FOO_2)
306 .remove(FOO_3, FOO_4)
307 .remove(l(FOO_5));
308 assertList(x, "Foo: 6", "Foo: 7");
309
310 x = HeaderList.create().append(FOO_1,FOO_2).remove((String[])null).remove("Bar","Foo");
311 assertEmpty(x);
312 }
313
314 @Test void b05_builder_set() {
315 var x = HeaderList
316 .create()
317 .append(FOO_1,FOO_2)
318 .set(FOO_3)
319 .set(BAR_1)
320 .set((Header)null)
321 .set((HeaderList)null);
322 assertList(x, "Foo: 3", "Bar: 1");
323
324 x = HeaderList
325 .create()
326 .append(BAR_1,FOO_1,FOO_2,BAR_2)
327 .set(FOO_3);
328 assertList(x, "Bar: 1", "Foo: 3", "Bar: 2");
329
330 x = HeaderList
331 .create()
332 .append(BAR_1,FOO_1,FOO_2,BAR_2)
333 .set((Header[])null)
334 .set(null,FOO_3,FOO_4,FOO_5);
335 assertList(x, "Bar: 1", "Bar: 2", "Foo: 3", "Foo: 4", "Foo: 5");
336
337 x = HeaderList
338 .create()
339 .append(BAR_1,FOO_1,FOO_2,BAR_2)
340 .set((List<Header>)null)
341 .set(l(null,FOO_3,FOO_4,FOO_5));
342 assertList(x, "Bar: 1", "Bar: 2", "Foo: 3", "Foo: 4", "Foo: 5");
343
344 x = HeaderList
345 .create()
346 .append(BAR_1,FOO_1,FOO_2,BAR_2)
347 .set("FOO", "x");
348 assertList(x, "Bar: 1", "FOO: x", "Bar: 2");
349
350 x = HeaderList
351 .create()
352 .append(BAR_1,FOO_1,FOO_2,BAR_2)
353 .set("FOO", ()->"x");
354 assertList(x, "Bar: 1", "FOO: x", "Bar: 2");
355
356 x = HeaderList
357 .create()
358 .caseSensitive(true)
359 .append(BAR_1,FOO_1,FOO_2,BAR_2)
360 .set("FOO", ()->"x");
361 assertList(x, "Bar: 1", "Foo: 1", "Foo: 2", "Bar: 2", "FOO: x");
362
363 x = HeaderList
364 .create()
365 .append(BAR_1,FOO_1,FOO_2,BAR_2)
366 .set(HeaderList.of(FOO_3,FOO_4));
367 assertList(x, "Bar: 1", "Bar: 2", "Foo: 3", "Foo: 4");
368 }
369
370
371
372
373
374 @Test void c01_iterators() {
375 var x = HeaderList.of(Accept.TEXT_XML,ContentType.TEXT_XML);
376
377 var i1 = x.headerIterator();
378 assertString("Accept: text/xml", i1.nextHeader());
379 assertString("Content-Type: text/xml", i1.nextHeader());
380 assertThrowsWithMessage(NoSuchElementException.class, "Iteration already finished.", i1::nextHeader);
381
382 var i2 = x.headerIterator();
383 assertString("Accept: text/xml", i2.next());
384 assertString("Content-Type: text/xml", i2.nextHeader());
385 assertThrowsWithMessage(NoSuchElementException.class, "Iteration already finished.", i2::next);
386
387 var i3 = x.headerIterator("accept");
388 assertString("Accept: text/xml", i3.nextHeader());
389 assertThrowsWithMessage(NoSuchElementException.class, "Iteration already finished.", i3::nextHeader);
390
391 var x2 = HeaderList.create().append(Accept.TEXT_XML,ContentType.TEXT_XML).caseSensitive(true);
392
393 var i4 = x2.headerIterator("Accept");
394 assertString("Accept: text/xml", i4.nextHeader());
395 assertThrowsWithMessage(NoSuchElementException.class, "Iteration already finished.", i4::nextHeader);
396
397 var i5 = x2.headerIterator("accept");
398 assertThrowsWithMessage(NoSuchElementException.class, "Iteration already finished.", i5::nextHeader);
399
400 assertThrowsWithMessage(UnsupportedOperationException.class, "Not supported.", i5::remove);
401 }
402
403
404
405
406
407 @Test void d01_defaultHeaders() {
408 var x1 = HeaderList.create().setDefault(Accept.TEXT_XML);
409 assertList(x1, "Accept: text/xml");
410
411 var x2 = HeaderList.create().set(Accept.TEXT_PLAIN).setDefault(Accept.TEXT_XML);
412 assertList(x2, "Accept: text/plain");
413
414 var x3 = HeaderList.create().set(ContentType.TEXT_XML,Accept.TEXT_PLAIN,ContentType.TEXT_XML).setDefault(Accept.TEXT_XML);
415 assertList(x3, "Content-Type: text/xml", "Accept: text/plain", "Content-Type: text/xml");
416
417 var x4 = HeaderList.create().set(ContentType.TEXT_XML,ContentType.TEXT_XML).setDefault(Accept.TEXT_XML);
418 assertList(x4, "Content-Type: text/xml", "Content-Type: text/xml", "Accept: text/xml");
419
420 var x5 = HeaderList.create().set(ContentType.TEXT_XML,ContentType.TEXT_XML).setDefault(Accept.TEXT_XML).setDefault(ContentType.TEXT_HTML);
421 assertList(x5, "Content-Type: text/xml", "Content-Type: text/xml", "Accept: text/xml");
422
423 var x6 = HeaderList.create().setDefault(Accept.TEXT_XML,Accept.TEXT_PLAIN);
424 assertList(x6, "Accept: text/xml");
425
426 var x7 = HeaderList.create().setDefault(Accept.TEXT_XML).setDefault(Accept.TEXT_PLAIN);
427 assertList(x7, "Accept: text/xml");
428
429 var x8 = HeaderList.create().setDefault(Accept.TEXT_XML,Accept.TEXT_HTML).setDefault(Accept.TEXT_PLAIN);
430 assertList(x8, "Accept: text/xml");
431
432 var x9 = HeaderList
433 .create()
434 .setDefault((Header)null)
435 .setDefault((HeaderList)null)
436 .setDefault((Header[])null)
437 .setDefault((List<Header>)null);
438 assertEmpty(x9);
439
440 var x10 = HeaderList.create().setDefault("Accept","text/xml");
441 assertList(x10, "Accept: text/xml");
442
443 var x11 = HeaderList.create().setDefault("Accept",()->"text/xml");
444 assertList(x11, "Accept: text/xml");
445
446 var x12 = HeaderList.create().set(ContentType.TEXT_XML,ContentType.TEXT_PLAIN).setDefault(l(Accept.TEXT_XML,ContentType.TEXT_HTML,null));
447 assertList(x12, "Content-Type: text/xml", "Content-Type: text/plain", "Accept: text/xml");
448
449 var x13 = HeaderList.create().set(ContentType.TEXT_XML,ContentType.TEXT_PLAIN).setDefault(HeaderList.of(Accept.TEXT_XML,ContentType.TEXT_HTML,null));
450 assertList(x13, "Content-Type: text/xml", "Content-Type: text/plain", "Accept: text/xml");
451
452 var x14 = HeaderList.create().set(ContentType.TEXT_XML,ContentType.TEXT_PLAIN)
453 .setDefault(l(Accept.TEXT_XML,ContentType.TEXT_HTML,null))
454 .setDefault(l(Accept.TEXT_HTML,ContentType.TEXT_XML,null))
455 .setDefault(l(Age.of(1)));
456 assertList(x14, "Content-Type: text/xml", "Content-Type: text/plain", "Accept: text/xml", "Age: 1");
457 }
458
459
460
461
462
463 private static Header header(String name, Object val) {
464 return basicHeader(name, val);
465 }
466
467 private static HttpPartSerializerSession openApiSession() {
468 return OpenApiSerializer.DEFAULT.getPartSession();
469 }
470 }