1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.httppart;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.commons.utils.StringUtils.*;
22 import static org.apache.juneau.junit.bct.BctAssertions.*;
23 import static org.junit.jupiter.api.Assertions.*;
24
25 import java.util.*;
26
27 import org.apache.juneau.*;
28 import org.apache.juneau.annotation.*;
29 import org.apache.juneau.commons.reflect.*;
30 import org.apache.juneau.http.annotation.*;
31 import org.junit.jupiter.api.*;
32
33 class HttpPartSchema_Query_Test extends TestBase {
34
35
36
37
38 @Test void a01_basic() {
39 assertDoesNotThrow(()->HttpPartSchema.create().build());
40 }
41
42
43
44
45
46 @Query("x")
47 public static class A01 {}
48
49 @Test void a01_value() {
50 var s = HttpPartSchema.create().applyAll(Query.class, A01.class).build();
51 assertEquals("x", s.getName());
52 }
53
54 @Query("x")
55 @Schema(
56 t="number",
57 f="int32",
58 cf="csv",
59 max="1",
60 min="2",
61 mo="3",
62 p="4",
63 maxl=1,
64 minl=2,
65 maxi=3,
66 mini=4,
67 emax=true,
68 emin=true,
69 ui=true,
70 r=true,
71 sie=true,
72 d={"b1","b2"},
73 df={"c1","c2"},
74 items=@Items($ref="d1"),
75 e="e1,e2,e3"
76 )
77 public static class A02 {}
78
79 @Test void a02_basic_onClass() {
80 assertBean(
81 HttpPartSchema.create().applyAll(Query.class, A02.class).noValidate().build(),
82 "name,type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,required,skipIfEmpty,enum,default",
83 "x,NUMBER,INT32,CSV,1,2,3,4,1,2,3,4,true,true,true,true,true,[e1,e2,e3],c1\nc2"
84 );
85 }
86
87 public static class A03 {
88 public void a(
89 @Query("x")
90 @Schema(
91 t="number",
92 f="int32",
93 cf="csv",
94 max="1",
95 min="2",
96 mo="3",
97 p="4",
98 maxl=1,
99 minl=2,
100 maxi=3,
101 mini=4,
102 emax=true,
103 emin=true,
104 ui=true,
105 r=true,
106 sie=true,
107 d={"b1","b2"},
108 df={"c1","c2"},
109 items=@Items($ref="d1"),
110 e="e1,e2,e3"
111 )
112 String x
113 ) {
114
115 }
116 }
117
118 @Test void a03_basic_onParameter() throws Exception {
119 var mpi = MethodInfo.of(A03.class.getMethod("a", String.class)).getParameter(0);
120 assertBean(
121 HttpPartSchema.create().applyAll(Query.class, mpi).noValidate().build(),
122 "name,type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,required,skipIfEmpty,enum,default",
123 "x,NUMBER,INT32,CSV,1,2,3,4,1,2,3,4,true,true,true,true,true,[e1,e2,e3],c1\nc2"
124 );
125 }
126
127 public static class A04 {
128 public void a(
129 @Query("y")
130 @Schema(
131 t="integer",
132 f="int64",
133 cf="ssv",
134 max="5",
135 min="6",
136 mo="7",
137 p="8",
138 maxl=5,
139 minl=6,
140 maxi=7,
141 mini=8,
142 emax=false,
143 emin=false,
144 ui=false,
145 r=false,
146 sie=false,
147 d={"b3","b3"},
148 df={"c3","c4"},
149 items=@Items($ref="d2"),
150 e="e4,e5,e6"
151 )
152 A01 x
153 ) {
154
155 }
156 }
157
158 @Test void a04_basic_onParameterAndClass() throws Exception {
159 var mpi = MethodInfo.of(A04.class.getMethod("a", A01.class)).getParameter(0);
160 assertBean(
161 HttpPartSchema.create().applyAll(Query.class, mpi).noValidate().build(),
162 "name,type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,required,skipIfEmpty,enum,default",
163 "y,INTEGER,INT64,SSV,5,6,7,8,5,6,7,8,false,false,false,false,false,[e4,e5,e6],c3\nc4"
164 );
165 }
166
167 @Query("x")
168 @Schema(
169 items=@Items(
170 t="number",
171 f="int32",
172 cf="csv",
173 max="1",
174 min="2",
175 mo="3",
176 p="4",
177 maxl=1,
178 minl=2,
179 maxi=3,
180 mini=4,
181 emax=true,
182 emin=true,
183 ui=true,
184 df={"c1","c2"},
185 e="e1,e2",
186 items=@SubItems(
187 t="integer",
188 f="int64",
189 cf="ssv",
190 max="5",
191 min="6",
192 mo="7",
193 p="8",
194 maxl=5,
195 minl=6,
196 maxi=7,
197 mini=8,
198 emax=false,
199 emin=false,
200 ui=false,
201 df={"c3","c4"},
202 e="e3,e4",
203 items={
204 "type:'string',",
205 "format:'float',",
206 "collectionFormat:'tsv',",
207 "maximum:'9',",
208 "minimum:'10',",
209 "multipleOf:'11',",
210 "pattern:'12',",
211 "maxLength:9,",
212 "minLength:10,",
213 "maxItems:11,",
214 "minItems:12,",
215 "exclusiveMaximum:true,",
216 "exclusiveMinimum:true,",
217 "uniqueItems:true,",
218 "default:'c5\\nc6',",
219 "enum:['e5','e6'],",
220 "items:{",
221 "type:'array',",
222 "format:'double',",
223 "collectionFormat:'pipes',",
224 "maximum:'13',",
225 "minimum:'14',",
226 "multipleOf:'15',",
227 "pattern:'16',",
228 "maxLength:13,",
229 "minLength:14,",
230 "maxItems:15,",
231 "minItems:16,",
232 "exclusiveMaximum:false,",
233 "exclusiveMinimum:false,",
234 "uniqueItems:false,",
235 "default:'c7\\nc8',",
236 "enum:['e7','e8']",
237 "}"
238 }
239 )
240 )
241 )
242 public static class A05 {}
243
244 @Test void a05_basic_nestedItems_onClass() {
245 var s = HttpPartSchema.create().applyAll(Query.class, A05.class).noValidate().build();
246 assertEquals("x", s.getName());
247
248 var items = s.getItems();
249 assertBean(
250 items,
251 "type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,enum,default",
252 "NUMBER,INT32,CSV,1,2,3,4,1,2,3,4,true,true,true,[e1,e2],c1\nc2"
253 );
254
255 items = items.getItems();
256 assertBean(
257 items,
258 "type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,enum,default",
259 "INTEGER,INT64,SSV,5,6,7,8,5,6,7,8,false,false,false,[e3,e4],c3\nc4"
260 );
261
262 items = items.getItems();
263 assertBean(
264 items,
265 "type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,enum,default",
266 "STRING,FLOAT,TSV,9,10,11,12,9,10,11,12,true,true,true,[e5,e6],c5\nc6"
267 );
268
269 items = items.getItems();
270 assertBean(
271 items,
272 "type,format,collectionFormat,maximum,minimum,multipleOf,pattern,maxLength,minLength,maxItems,minItems,exclusiveMaximum,exclusiveMinimum,uniqueItems,enum,default",
273 "ARRAY,DOUBLE,PIPES,13,14,15,16,13,14,15,16,false,false,false,[e7,e8],c7\nc8"
274 );
275 }
276
277
278
279
280
281 @Query @Schema(r=true)
282 public static class B01a {}
283
284 @Test void b01a_required() throws Exception {
285 var s = HttpPartSchema.create().applyAll(Query.class, B01a.class).build();
286
287 s.validateInput("x");
288
289 assertThrowsWithMessage(SchemaValidationException.class, "No value specified.", ()->s.validateInput(null));
290 assertThrowsWithMessage(SchemaValidationException.class, "Empty value not allowed.", ()->s.validateInput(""));
291 }
292
293 @Query @Schema(aev=true)
294 public static class B01b {}
295
296 @Test void b01b_allowEmptyValue() throws Exception {
297 var s = HttpPartSchema.create().applyAll(Query.class, B01b.class).build();
298
299 s.validateInput("");
300 s.validateInput(null);
301 }
302
303 @Query @Schema(r=true,aev=true)
304 public static class B01c {}
305
306 @Test void b01b_required_allowEmptyValue() throws Exception {
307 var s = HttpPartSchema.create().applyAll(Query.class, B01c.class).build();
308
309 s.validateInput("");
310
311 assertThrowsWithMessage(SchemaValidationException.class, "No value specified.", ()->s.validateInput(null));
312 }
313
314 @Query @Schema(p="x.*")
315 public static class B02a {}
316
317 @Test void b02a_pattern() throws Exception {
318 var s = HttpPartSchema.create().applyAll(Query.class, B02a.class).build();
319 s.validateInput("x");
320 s.validateInput("xx");
321 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match expected pattern. Must match pattern: x.*", ()->s.validateInput("y"));
322 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match expected pattern. Must match pattern: x.*", ()->s.validateInput("yx"));
323 assertThrowsWithMessage(SchemaValidationException.class, "Empty value not allowed.", ()->s.validateInput(""));
324 }
325
326 @Query @Schema(minl=2, maxl=3)
327 public static class B03a {}
328
329 @Test void b03a_length() throws Exception {
330 var s = HttpPartSchema.create().applyAll(Query.class, B03a.class).build();
331 s.validateInput("12");
332 s.validateInput("123");
333 s.validateInput(null);
334 assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->s.validateInput("1"));
335 assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->s.validateInput("1234"));
336 }
337
338 @Query
339 @Schema(
340 items=@Items(
341 minl=2, maxl=3,
342 items=@SubItems(
343 minl=3, maxl=4,
344 items={
345 "minLength:4,maxLength:5,",
346 "items:{minLength:5,maxLength:6}"
347 }
348 )
349 )
350 )
351 public static class B03b {}
352
353 @Test void b03b_length_items() throws Exception {
354 var s = HttpPartSchema.create().applyAll(Query.class, B03b.class).build();
355
356 s.getItems().validateInput("12");
357 s.getItems().getItems().validateInput("123");
358 s.getItems().getItems().getItems().validateInput("1234");
359 s.getItems().getItems().getItems().getItems().validateInput("12345");
360
361 s.getItems().validateInput("123");
362 s.getItems().getItems().validateInput("1234");
363 s.getItems().getItems().getItems().validateInput("12345");
364 s.getItems().getItems().getItems().getItems().validateInput("123456");
365
366 s.getItems().validateInput(null);
367 s.getItems().getItems().validateInput(null);
368 s.getItems().getItems().getItems().validateInput(null);
369 s.getItems().getItems().getItems().getItems().validateInput(null);
370
371 assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->s.getItems().validateInput("1"));
372 assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->s.getItems().getItems().validateInput("12"));
373 assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->s.getItems().getItems().getItems().validateInput("123"));
374 assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->s.getItems().getItems().getItems().getItems().validateInput("1234"));
375
376 assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->s.getItems().validateInput("1234"));
377 assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->s.getItems().getItems().validateInput("12345"));
378 assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->s.getItems().getItems().getItems().validateInput("123456"));
379 assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->s.getItems().getItems().getItems().getItems().validateInput("1234567"));
380 }
381
382 @Query @Schema(e="X,Y")
383 public static class B04a {}
384
385 @Test void b04a_enum() throws Exception {
386 var s = HttpPartSchema.create().applyAll(Query.class, B04a.class).build();
387 s.validateInput("X");
388 s.validateInput("Y");
389 s.validateInput(null);
390 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: X, Y", ()->s.validateInput("Z"));
391 }
392
393 @Query @Schema(e=" X , Y ")
394 public static class B04b {}
395
396 @Test void b04b_enum() throws Exception {
397 var s = HttpPartSchema.create().applyAll(Query.class, B04b.class).build();
398 s.validateInput("X");
399 s.validateInput("Y");
400 s.validateInput(null);
401 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: X, Y", ()->s.validateInput("Z"));
402 }
403
404 @Query @Schema(e="X,Y")
405 public static class B04c {}
406
407 @Test void b04c_enum_json() throws Exception {
408 var s = HttpPartSchema.create().applyAll(Query.class, B04c.class).build();
409 s.validateInput("X");
410 s.validateInput("Y");
411 s.validateInput(null);
412 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: X, Y", ()->s.validateInput("Z"));
413 }
414
415 @Query
416 @Schema(
417 items=@Items(
418 e="W",
419 items=@SubItems(
420 e="X",
421 items={
422 "enum:['Y'],",
423 "items:{enum:['Z']}"
424 }
425 )
426 )
427 )
428 public static class B04d {}
429
430 @Test void b04d_enum_items() throws Exception {
431 var s = HttpPartSchema.create().applyAll(Query.class, B04d.class).build();
432
433 s.getItems().validateInput("W");
434 s.getItems().getItems().validateInput("X");
435 s.getItems().getItems().getItems().validateInput("Y");
436 s.getItems().getItems().getItems().getItems().validateInput("Z");
437
438 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: W", ()->s.getItems().validateInput("V"));
439 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: X", ()->s.getItems().getItems().validateInput("V"));
440 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: Y", ()->s.getItems().getItems().getItems().validateInput("V"));
441 assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values. Must be one of the following: Z", ()->s.getItems().getItems().getItems().getItems().validateInput("V"));
442 }
443
444
445
446
447
448 @Query @Schema(min="10", max="100")
449 public static class C01a {}
450
451 @Test void c01a_minmax_ints() throws Exception {
452 var s = HttpPartSchema.create().applyAll(Query.class, C01a.class).build();
453 s.validateOutput(10, BeanContext.DEFAULT);
454 s.validateOutput(100, BeanContext.DEFAULT);
455 s.validateOutput(null, BeanContext.DEFAULT);
456 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.validateOutput(9, BeanContext.DEFAULT));
457 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.validateOutput(101, BeanContext.DEFAULT));
458 }
459
460 @Query
461 @Schema(
462 items=@Items(
463 min="10", max="100",
464 items=@SubItems(
465 min="100", max="1000",
466 items={
467 "minimum:1000,maximum:10000,",
468 "items:{minimum:10000,maximum:100000}"
469 }
470 )
471 )
472 )
473 public static class C01b {}
474
475 @Test void c01b_minmax_ints_items() throws Exception {
476 var s = HttpPartSchema.create().applyAll(Query.class, C01b.class).build();
477
478 s.getItems().validateOutput(10, BeanContext.DEFAULT);
479 s.getItems().getItems().validateOutput(100, BeanContext.DEFAULT);
480 s.getItems().getItems().getItems().validateOutput(1000, BeanContext.DEFAULT);
481 s.getItems().getItems().getItems().getItems().validateOutput(10000, BeanContext.DEFAULT);
482
483 s.getItems().validateOutput(100, BeanContext.DEFAULT);
484 s.getItems().getItems().validateOutput(1000, BeanContext.DEFAULT);
485 s.getItems().getItems().getItems().validateOutput(10000, BeanContext.DEFAULT);
486 s.getItems().getItems().getItems().getItems().validateOutput(100000, BeanContext.DEFAULT);
487
488 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().validateOutput(9, BeanContext.DEFAULT));
489 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().validateOutput(99, BeanContext.DEFAULT));
490 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().validateOutput(999, BeanContext.DEFAULT));
491 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(9999, BeanContext.DEFAULT));
492
493 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().validateOutput(101, BeanContext.DEFAULT));
494 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().validateOutput(1001, BeanContext.DEFAULT));
495 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().validateOutput(10001, BeanContext.DEFAULT));
496 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().getItems().validateOutput(100001, BeanContext.DEFAULT));
497 }
498
499 @Query @Schema(min="10", max="100", emin=true, emax=true)
500 public static class C02a {}
501
502 @Test void c02a_minmax_exclusive() throws Exception {
503 var s = HttpPartSchema.create().applyAll(Query.class, C02a.class).build();
504 s.validateOutput(11, BeanContext.DEFAULT);
505 s.validateOutput(99, BeanContext.DEFAULT);
506 s.validateOutput(null, BeanContext.DEFAULT);
507 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.validateOutput(10, BeanContext.DEFAULT));
508 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.validateOutput(100, BeanContext.DEFAULT));
509 }
510
511 @Query
512 @Schema(
513 items=@Items(
514 min="10", max="100", emin=true, emax=true,
515 items=@SubItems(
516 min="100", max="1000", emin=true, emax=true,
517 items={
518 "minimum:1000,maximum:10000,exclusiveMinimum:true,exclusiveMaximum:true,",
519 "items:{minimum:10000,maximum:100000,exclusiveMinimum:true,exclusiveMaximum:true}"
520 }
521 )
522 )
523 )
524 public static class C02b {}
525
526 @Test void c02b_minmax_exclusive_items() throws Exception {
527 var s = HttpPartSchema.create().applyAll(Query.class, C02b.class).build();
528
529 s.getItems().validateOutput(11, BeanContext.DEFAULT);
530 s.getItems().getItems().validateOutput(101, BeanContext.DEFAULT);
531 s.getItems().getItems().getItems().validateOutput(1001, BeanContext.DEFAULT);
532 s.getItems().getItems().getItems().getItems().validateOutput(10001, BeanContext.DEFAULT);
533
534 s.getItems().validateOutput(99, BeanContext.DEFAULT);
535 s.getItems().getItems().validateOutput(999, BeanContext.DEFAULT);
536 s.getItems().getItems().getItems().validateOutput(9999, BeanContext.DEFAULT);
537 s.getItems().getItems().getItems().getItems().validateOutput(99999, BeanContext.DEFAULT);
538
539 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().validateOutput(10, BeanContext.DEFAULT));
540 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().validateOutput(100, BeanContext.DEFAULT));
541 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().validateOutput(1000, BeanContext.DEFAULT));
542 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(10000, BeanContext.DEFAULT));
543
544 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().validateOutput(100, BeanContext.DEFAULT));
545 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().validateOutput(1000, BeanContext.DEFAULT));
546 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().validateOutput(10000, BeanContext.DEFAULT));
547 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().getItems().validateOutput(100000, BeanContext.DEFAULT));
548 }
549
550 @Query @Schema(min="10.1", max="100.1")
551 public static class C03a {}
552
553 @Test void c03_minmax_floats() throws Exception {
554 var s = HttpPartSchema.create().applyAll(Query.class, C03a.class).build();
555 s.validateOutput(10.1f, BeanContext.DEFAULT);
556 s.validateOutput(100.1f, BeanContext.DEFAULT);
557 s.validateOutput(null, BeanContext.DEFAULT);
558 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.validateOutput(10f, BeanContext.DEFAULT));
559 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.validateOutput(100.2f, BeanContext.DEFAULT));
560 }
561
562 @Query
563 @Schema(
564 items=@Items(
565 min="10.1", max="100.1",
566 items=@SubItems(
567 min="100.1", max="1000.1",
568 items={
569 "minimum:1000.1,maximum:10000.1,",
570 "items:{minimum:10000.1,maximum:100000.1}"
571 }
572 )
573 )
574 )
575 public static class C03b {}
576
577 @Test void c03b_minmax_floats_items() throws Exception {
578 var s = HttpPartSchema.create().applyAll(Query.class, C03b.class).build();
579
580 s.getItems().validateOutput(10.1f, BeanContext.DEFAULT);
581 s.getItems().getItems().validateOutput(100.1f, BeanContext.DEFAULT);
582 s.getItems().getItems().getItems().validateOutput(1000.1f, BeanContext.DEFAULT);
583 s.getItems().getItems().getItems().getItems().validateOutput(10000.1f, BeanContext.DEFAULT);
584
585 s.getItems().validateOutput(100.1f, BeanContext.DEFAULT);
586 s.getItems().getItems().validateOutput(1000.1f, BeanContext.DEFAULT);
587 s.getItems().getItems().getItems().validateOutput(10000.1f, BeanContext.DEFAULT);
588 s.getItems().getItems().getItems().getItems().validateOutput(100000.1f, BeanContext.DEFAULT);
589
590 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().validateOutput(10f, BeanContext.DEFAULT));
591 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().validateOutput(100f, BeanContext.DEFAULT));
592 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().validateOutput(1000f, BeanContext.DEFAULT));
593 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(10000f, BeanContext.DEFAULT));
594
595 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().validateOutput(100.2f, BeanContext.DEFAULT));
596 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().validateOutput(1000.2f, BeanContext.DEFAULT));
597 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().validateOutput(10000.2f, BeanContext.DEFAULT));
598 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().getItems().validateOutput(100000.2f, BeanContext.DEFAULT));
599 }
600
601 @Query @Schema(min="10.1", max="100.1", emin=true, emax=true)
602 public static class C04a {}
603
604 @Test void c04a_minmax_floats_exclusive() throws Exception {
605 var s = HttpPartSchema.create().applyAll(Query.class, C04a.class).build();
606 s.validateOutput(10.2f, BeanContext.DEFAULT);
607 s.validateOutput(100f, BeanContext.DEFAULT);
608 s.validateOutput(null, BeanContext.DEFAULT);
609 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.validateOutput(10.1f, BeanContext.DEFAULT));
610 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.validateOutput(100.1f, BeanContext.DEFAULT));
611 }
612
613 @Query
614 @Schema(
615 items=@Items(
616 min="10.1", max="100.1", emin=true, emax=true,
617 items=@SubItems(
618 min="100.1", max="1000.1", emin=true, emax=true,
619 items={
620 "minimum:1000.1,maximum:10000.1,exclusiveMinimum:true,exclusiveMaximum:true,",
621 "items:{minimum:10000.1,maximum:100000.1,exclusiveMinimum:true,exclusiveMaximum:true}"
622 }
623 )
624 )
625 )
626 public static class C04b {}
627
628 @Test void c04b_minmax_floats_exclusive_items() throws Exception {
629 var s = HttpPartSchema.create().applyAll(Query.class, C04b.class).build();
630
631 s.getItems().validateOutput(10.2f, BeanContext.DEFAULT);
632 s.getItems().getItems().validateOutput(100.2f, BeanContext.DEFAULT);
633 s.getItems().getItems().getItems().validateOutput(1000.2f, BeanContext.DEFAULT);
634 s.getItems().getItems().getItems().getItems().validateOutput(10000.2f, BeanContext.DEFAULT);
635
636 s.getItems().validateOutput(100f, BeanContext.DEFAULT);
637 s.getItems().getItems().validateOutput(1000f, BeanContext.DEFAULT);
638 s.getItems().getItems().getItems().validateOutput(10000f, BeanContext.DEFAULT);
639 s.getItems().getItems().getItems().getItems().validateOutput(100000f, BeanContext.DEFAULT);
640
641 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().validateOutput(10.1f, BeanContext.DEFAULT));
642 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().validateOutput(100.1f, BeanContext.DEFAULT));
643 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().validateOutput(1000.1f, BeanContext.DEFAULT));
644 assertThrowsWithMessage(SchemaValidationException.class, "Minimum value not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(10000.1f, BeanContext.DEFAULT));
645
646 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().validateOutput(100.1f, BeanContext.DEFAULT));
647 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().validateOutput(1000.1f, BeanContext.DEFAULT));
648 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().validateOutput(10000.1f, BeanContext.DEFAULT));
649 assertThrowsWithMessage(SchemaValidationException.class, "Maximum value exceeded.", ()->s.getItems().getItems().getItems().getItems().validateOutput(100000.1f, BeanContext.DEFAULT));
650 }
651
652 @Query @Schema(mo="10")
653 public static class C05a {}
654
655 @Test void c05a_multipleOf() throws Exception {
656 var s = HttpPartSchema.create().applyAll(Query.class, C05a.class).build();
657 s.validateOutput(0, BeanContext.DEFAULT);
658 s.validateOutput(10, BeanContext.DEFAULT);
659 s.validateOutput(20, BeanContext.DEFAULT);
660 s.validateOutput(10f, BeanContext.DEFAULT);
661 s.validateOutput(20f, BeanContext.DEFAULT);
662 s.validateOutput(null, BeanContext.DEFAULT);
663 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.validateOutput(11, BeanContext.DEFAULT));
664 }
665
666 @Query
667 @Schema(
668 items=@Items(
669 mo="10",
670 items=@SubItems(
671 mo="100",
672 items={
673 "multipleOf:1000,",
674 "items:{multipleOf:10000}"
675 }
676 )
677 )
678 )
679 public static class C05b {}
680
681 @Test void c05b_multipleOf_items() throws Exception {
682 var s = HttpPartSchema.create().applyAll(Query.class, C05b.class).build();
683
684 s.getItems().validateOutput(0, BeanContext.DEFAULT);
685 s.getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
686 s.getItems().getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
687 s.getItems().getItems().getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
688
689 s.getItems().validateOutput(10, BeanContext.DEFAULT);
690 s.getItems().getItems().validateOutput(100, BeanContext.DEFAULT);
691 s.getItems().getItems().getItems().validateOutput(1000, BeanContext.DEFAULT);
692 s.getItems().getItems().getItems().getItems().validateOutput(10000, BeanContext.DEFAULT);
693
694 s.getItems().validateOutput(20, BeanContext.DEFAULT);
695 s.getItems().getItems().validateOutput(200, BeanContext.DEFAULT);
696 s.getItems().getItems().getItems().validateOutput(2000, BeanContext.DEFAULT);
697 s.getItems().getItems().getItems().getItems().validateOutput(20000, BeanContext.DEFAULT);
698
699 s.getItems().validateOutput(10f, BeanContext.DEFAULT);
700 s.getItems().getItems().validateOutput(100f, BeanContext.DEFAULT);
701 s.getItems().getItems().getItems().validateOutput(1000f, BeanContext.DEFAULT);
702 s.getItems().getItems().getItems().getItems().validateOutput(10000f, BeanContext.DEFAULT);
703
704 s.getItems().validateOutput(20f, BeanContext.DEFAULT);
705 s.getItems().getItems().validateOutput(200f, BeanContext.DEFAULT);
706 s.getItems().getItems().getItems().validateOutput(2000f, BeanContext.DEFAULT);
707 s.getItems().getItems().getItems().getItems().validateOutput(20000f, BeanContext.DEFAULT);
708
709 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().validateOutput(11, BeanContext.DEFAULT));
710 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().validateOutput(101, BeanContext.DEFAULT));
711 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().getItems().validateOutput(1001, BeanContext.DEFAULT));
712 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(10001, BeanContext.DEFAULT));
713 }
714
715 @Query @Schema(mo="10.1")
716 public static class C06a {}
717
718 @Test void c06a_multipleOf_floats() throws Exception {
719 var s = HttpPartSchema.create().applyAll(Query.class, C06a.class).build();
720 s.validateOutput(0, BeanContext.DEFAULT);
721 s.validateOutput(10.1f, BeanContext.DEFAULT);
722 s.validateOutput(20.2f, BeanContext.DEFAULT);
723 s.validateOutput(null, BeanContext.DEFAULT);
724 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.validateOutput(10.2f, BeanContext.DEFAULT));
725 }
726
727 @Query
728 @Schema(
729 items=@Items(
730 mo="10.1",
731 items=@SubItems(
732 mo="100.1",
733 items={
734 "multipleOf:1000.1,",
735 "items:{multipleOf:10000.1}"
736 }
737 )
738 )
739 )
740 public static class C06b {}
741
742 @Test void c06b_multipleOf_floats_items() throws Exception {
743 var s = HttpPartSchema.create().applyAll(Query.class, C06b.class).build();
744
745 s.getItems().validateOutput(0, BeanContext.DEFAULT);
746 s.getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
747 s.getItems().getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
748 s.getItems().getItems().getItems().getItems().validateOutput(0, BeanContext.DEFAULT);
749
750 s.getItems().validateOutput(10.1f, BeanContext.DEFAULT);
751 s.getItems().getItems().validateOutput(100.1f, BeanContext.DEFAULT);
752 s.getItems().getItems().getItems().validateOutput(1000.1f, BeanContext.DEFAULT);
753 s.getItems().getItems().getItems().getItems().validateOutput(10000.1f, BeanContext.DEFAULT);
754
755 s.getItems().validateOutput(20.2f, BeanContext.DEFAULT);
756 s.getItems().getItems().validateOutput(200.2f, BeanContext.DEFAULT);
757 s.getItems().getItems().getItems().validateOutput(2000.2f, BeanContext.DEFAULT);
758 s.getItems().getItems().getItems().getItems().validateOutput(20000.2f, BeanContext.DEFAULT);
759
760 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().validateOutput(10.2f, BeanContext.DEFAULT));
761 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().validateOutput(100.2f, BeanContext.DEFAULT));
762 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().getItems().validateOutput(1000.2f, BeanContext.DEFAULT));
763 assertThrowsWithMessage(SchemaValidationException.class, "Multiple-of not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(10000.2f, BeanContext.DEFAULT));
764 }
765
766
767
768
769
770 @Query
771 @Schema(
772 items=@Items(
773 ui=true,
774 items=@SubItems(
775 ui=true,
776 items={
777 "uniqueItems:true,",
778 "items:{uniqueItems:true}"
779 }
780 )
781 )
782
783 )
784 public static class D01 {}
785
786 @Test void d01a_uniqueItems_arrays() throws Exception {
787 var s = HttpPartSchema.create().applyAll(Query.class, D01.class).build();
788
789 var good = split("a,b");
790 var bad = split("a,a");
791
792 s.getItems().validateOutput(good, BeanContext.DEFAULT);
793 s.getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
794 s.getItems().getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
795 s.getItems().getItems().getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
796 s.getItems().validateOutput(null, BeanContext.DEFAULT);
797
798 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().validateOutput(bad, BeanContext.DEFAULT));
799 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
800 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
801 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
802 }
803
804 @Test void d01b_uniqueItems_collections() throws Exception {
805 var s = HttpPartSchema.create().applyAll(Query.class, D01.class).build();
806
807 List<String>
808 good = l("a","b"),
809 bad = l("a","a");
810
811 s.getItems().validateOutput(good, BeanContext.DEFAULT);
812 s.getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
813 s.getItems().getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
814 s.getItems().getItems().getItems().getItems().validateOutput(good, BeanContext.DEFAULT);
815 s.getItems().validateOutput(null, BeanContext.DEFAULT);
816
817 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().validateOutput(bad, BeanContext.DEFAULT));
818 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
819 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
820 assertThrowsWithMessage(SchemaValidationException.class, "Duplicate items not allowed.", ()->s.getItems().getItems().getItems().getItems().validateOutput(bad, BeanContext.DEFAULT));
821 }
822
823 @Query
824 @Schema(
825 items=@Items(
826 mini=1, maxi=2,
827 items=@SubItems(
828 mini=2, maxi=3,
829 items={
830 "minItems:3,maxItems:4,",
831 "items:{minItems:4,maxItems:5}"
832 }
833 )
834 )
835
836 )
837 public static class D02 {}
838
839 @Test void d02a_minMaxItems_arrays() throws Exception {
840 var s = HttpPartSchema.create().applyAll(Query.class, D02.class).build();
841
842 s.getItems().validateOutput(split("1"), BeanContext.DEFAULT);
843 s.getItems().getItems().validateOutput(split("1,2"), BeanContext.DEFAULT);
844 s.getItems().getItems().getItems().validateOutput(split("1,2,3"), BeanContext.DEFAULT);
845 s.getItems().getItems().getItems().getItems().validateOutput(split("1,2,3,4"), BeanContext.DEFAULT);
846
847 s.getItems().validateOutput(split("1,2"), BeanContext.DEFAULT);
848 s.getItems().getItems().validateOutput(split("1,2,3"), BeanContext.DEFAULT);
849 s.getItems().getItems().getItems().validateOutput(split("1,2,3,4"), BeanContext.DEFAULT);
850 s.getItems().getItems().getItems().getItems().validateOutput(split("1,2,3,4,5"), BeanContext.DEFAULT);
851
852 assertThrowsWithMessage(SchemaValidationException.class, "Minimum number of items not met.", ()->s.getItems().validateOutput(new String[0], BeanContext.DEFAULT));
853 assertThrowsWithMessage(SchemaValidationException.class, "Minimum number of items not met.", ()->s.getItems().getItems().validateOutput(split("1"), BeanContext.DEFAULT));
854 assertThrowsWithMessage(SchemaValidationException.class, "Minimum number of items not met.", ()->s.getItems().getItems().getItems().validateOutput(split("1,2"), BeanContext.DEFAULT));
855 assertThrowsWithMessage(SchemaValidationException.class, "Minimum number of items not met.", ()->s.getItems().getItems().getItems().getItems().validateOutput(split("1,2,3"), BeanContext.DEFAULT));
856
857 assertThrowsWithMessage(SchemaValidationException.class, "Maximum number of items exceeded.", ()->s.getItems().validateOutput(split("1,2,3"), BeanContext.DEFAULT));
858 assertThrowsWithMessage(SchemaValidationException.class, "Maximum number of items exceeded.", ()->s.getItems().getItems().validateOutput(split("1,2,3,4"), BeanContext.DEFAULT));
859 assertThrowsWithMessage(SchemaValidationException.class, "Maximum number of items exceeded.", ()->s.getItems().getItems().getItems().validateOutput(split("1,2,3,4,5"), BeanContext.DEFAULT));
860 assertThrowsWithMessage(SchemaValidationException.class, "Maximum number of items exceeded.", ()->s.getItems().getItems().getItems().getItems().validateOutput(split("1,2,3,4,5,6"), BeanContext.DEFAULT));
861 }
862 }