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