1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.bean.swagger;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.bean.swagger.SwaggerBuilder.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.util.*;
24
25 import org.apache.juneau.*;
26 import org.apache.juneau.collections.*;
27 import org.junit.jupiter.api.*;
28
29
30
31
32 class ParameterInfo_Test extends TestBase {
33
34 @Nested class A_basicTests extends TestBase {
35
36 private static final BeanTester<ParameterInfo> TESTER =
37 testBean(
38 bean()
39 .setAllowEmptyValue(true)
40 .setCollectionFormat("a")
41 .setDefault("b")
42 .setDescription("c")
43 .setEnum(set("d"))
44 .setExample("e")
45 .setExamples(map("f", "g"))
46 .setExclusiveMaximum(true)
47 .setExclusiveMinimum(true)
48 .setFormat("h")
49 .setIn("i")
50 .setItems(items().setType("j"))
51 .setMaximum(1)
52 .setMaxItems(2)
53 .setMaxLength(3)
54 .setMinimum(4)
55 .setMinItems(5)
56 .setMinLength(6)
57 .setMultipleOf(7)
58 .setName("k")
59 .setPattern("l")
60 .setRequired(true)
61 .setSchema(schemaInfo().setType("m"))
62 .setType("n")
63 .setUniqueItems(true)
64 )
65 .props("allowEmptyValue,collectionFormat,default,description,enum,example,examples,exclusiveMaximum,exclusiveMinimum,format,in,items{type},maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,name,pattern,required,schema{type},type,uniqueItems")
66 .vals("true,a,b,c,[d],e,{f=g},true,true,h,i,{j},1,2,3,4,5,6,7,k,l,true,{m},n,true")
67 .json("{allowEmptyValue:true,collectionFormat:'a','default':'b',description:'c','enum':['d'],example:'e',examples:{f:'g'},exclusiveMaximum:true,exclusiveMinimum:true,format:'h','in':'i',items:{type:'j'},maxItems:2,maxLength:3,maximum:1,minItems:5,minLength:6,minimum:4,multipleOf:7,name:'k',pattern:'l',required:true,schema:{type:'m'},type:'n',uniqueItems:true}")
68 .string("{'allowEmptyValue':true,'collectionFormat':'a','default':'b','description':'c','enum':['d'],'example':'e','examples':{'f':'g'},'exclusiveMaximum':true,'exclusiveMinimum':true,'format':'h','in':'i','items':{'type':'j'},'maxItems':2,'maxLength':3,'maximum':1,'minItems':5,'minLength':6,'minimum':4,'multipleOf':7,'name':'k','pattern':'l','required':true,'schema':{'type':'m'},'type':'n','uniqueItems':true}".replace('\'', '"'))
69 ;
70
71 @Test void a01_gettersAndSetters() {
72 TESTER.assertGettersAndSetters();
73 }
74
75 @Test void a02_copy() {
76 TESTER.assertCopy();
77 }
78
79 @Test void a03_toJson() {
80 TESTER.assertToJson();
81 }
82
83 @Test void a04_fromJson() {
84 TESTER.assertFromJson();
85 }
86
87 @Test void a05_roundTrip() {
88 TESTER.assertRoundTrip();
89 }
90
91 @Test void a06_toString() {
92 TESTER.assertToString();
93 }
94
95 @Test void a07_keySet() {
96 assertList(TESTER.bean().keySet(), "allowEmptyValue", "collectionFormat", "default", "description", "enum", "example", "examples", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "schema", "type", "uniqueItems");
97 }
98
99 @Test void a08_nullParameters() {
100 var x = bean();
101 assertThrows(IllegalArgumentException.class, () -> x.get(null, String.class));
102 assertThrows(IllegalArgumentException.class, () -> x.set(null, "value"));
103 }
104
105 @Test void a09_addMethods() {
106 var x = bean().addEnum("a1");
107 assertNotNull(x);
108 assertNotNull(x.getEnum());
109 }
110
111 @Test void a10_setEnumVarargs() {
112 var x = bean().setEnum("a", "b", "c");
113 assertBean(x, "enum", "[a,b,c]");
114 }
115
116 @Test void a11_setEnumVarargsEmpty() {
117 var x = bean().setEnum();
118 assertBean(x, "enum", "<null>");
119 }
120
121 @Test void a12_setEnumVarargsNull() {
122 var x = bean().setEnum((Object[])null);
123 assertBean(x, "enum", "<null>");
124 }
125
126 @Test void a13_asMap() {
127 assertBean(
128 bean()
129 .setDescription("a")
130 .setIn("b")
131 .setName("c")
132 .set("x1", "x1a")
133 .asMap(),
134 "description,in,name,x1",
135 "a,b,c,x1a"
136 );
137 }
138
139 @Test void a14_extraKeys() {
140 var x = bean().set("x1", "x1a").set("x2", "x2a");
141 assertList(x.extraKeys(), "x1", "x2");
142 assertEmpty(bean().extraKeys());
143 }
144
145 @Test void a15_copyFrom() {
146 var x = bean().setName("a").setIn("b");
147 var y = bean().copyFrom(x);
148 assertBean(y, "name,in", "a,b");
149
150 y = bean().setName("c").copyFrom(x);
151 assertBean(y, "name,in", "a,b");
152
153 y = bean().setName("c").copyFrom(null);
154 assertBean(y, "name", "c");
155 }
156
157 @Test void a16_setInPathSetsRequired() {
158 var x = bean().setIn("path");
159 assertBean(x, "in,required", "path,true");
160 }
161
162 @Test void a17_setInNonPathDoesNotSetRequired() {
163 var x = bean().setIn("query");
164 assertBean(x, "in,required", "query,<null>");
165 }
166
167 @Test void a18_setNameWithBodyInDoesNotSetName() {
168 var x = bean().setIn("body").setName("test");
169 assertBean(x, "in,name", "body,<null>");
170 }
171
172 @Test void a19_setNameWithNonBodyInSetsName() {
173 var x = bean().setIn("query").setName("test");
174 assertBean(x, "in,name", "query,test");
175 }
176
177 @Test void a20_copyFromAllProperties() {
178 var source = bean()
179 .setName("a")
180 .setIn("b")
181 .setDescription("c")
182 .setType("d")
183 .setFormat("e")
184 .setPattern("f")
185 .setCollectionFormat("g")
186 .setMaximum(1)
187 .setMinimum(2)
188 .setMultipleOf(3)
189 .setMaxLength(4)
190 .setMinLength(5)
191 .setMaxItems(6)
192 .setMinItems(7)
193 .setRequired(true)
194 .setAllowEmptyValue(true)
195 .setExclusiveMaximum(true)
196 .setExclusiveMinimum(true)
197 .setUniqueItems(true)
198 .setSchema(schemaInfo().setType("h"))
199 .setItems(items().setType("i"))
200 .setDefault("j")
201 .setEnum(set("k"))
202 .setExample("l")
203 .setExamples(map("m1","m2"));
204
205 var target = bean().copyFrom(source);
206 assertBean(target,
207 "name,in,description,type,format,pattern,collectionFormat,maximum,minimum,multipleOf,maxLength,minLength,maxItems,minItems,required,allowEmptyValue,exclusiveMaximum,exclusiveMinimum,uniqueItems,schema{type},items{type},default,enum,example,examples",
208 "a,b,c,d,e,f,g,1,2,3,4,5,6,7,true,true,true,true,true,{h},{i},j,[k],l,{m1=m2}"
209 );
210 }
211
212 @Test void a21_copyFromPartialProperties() {
213 var source = bean()
214 .setName("a")
215 .setIn("b")
216 .setDescription("c");
217
218
219 var target = bean()
220 .setType("d")
221 .setFormat("e")
222 .copyFrom(source);
223
224 assertBean(
225 target,
226 "name,in,description,type,format",
227 "a,b,c,d,e"
228 );
229
230
231 assertJson(
232 "{}",
233 bean().copyFrom(bean())
234 );
235 }
236
237 @Test void a22_strictMode() {
238 assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
239 assertDoesNotThrow(() -> bean().set("foo", "bar"));
240
241 assertFalse(bean().isStrict());
242 assertTrue(bean().strict().isStrict());
243 assertFalse(bean().strict(false).isStrict());
244
245 var x = bean().strict();
246 var y = bean();
247 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setCollectionFormat(String). Value='invalid', valid values=['csv','ssv','tsv','pipes','multi']", () -> x.setCollectionFormat("invalid"));
248 assertDoesNotThrow(() -> x.setCollectionFormat("csv"));
249 assertDoesNotThrow(() -> x.setCollectionFormat("ssv"));
250 assertDoesNotThrow(() -> x.setCollectionFormat("tsv"));
251 assertDoesNotThrow(() -> x.setCollectionFormat("pipes"));
252 assertDoesNotThrow(() -> x.setCollectionFormat("multi"));
253 assertDoesNotThrow(() -> y.setCollectionFormat("invalid"));
254
255 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setIn(String). Value='invalid', valid values=['query','header','path','formData','body']", () -> x.setIn("invalid"));
256 assertDoesNotThrow(() -> x.setIn("query"));
257 assertDoesNotThrow(() -> x.setIn("header"));
258 assertDoesNotThrow(() -> x.setIn("path"));
259 assertDoesNotThrow(() -> x.setIn("formData"));
260 assertDoesNotThrow(() -> x.setIn("body"));
261 assertDoesNotThrow(() -> y.setIn("invalid"));
262
263 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setType(String). Value='invalid', valid values=['string','number','integer','boolean','array','file']", () -> x.setType("invalid"));
264 assertDoesNotThrow(() -> x.setType("string"));
265 assertDoesNotThrow(() -> x.setType("number"));
266 assertDoesNotThrow(() -> x.setType("integer"));
267 assertDoesNotThrow(() -> x.setType("boolean"));
268 assertDoesNotThrow(() -> x.setType("array"));
269 assertDoesNotThrow(() -> x.setType("file"));
270 assertDoesNotThrow(() -> y.setType("invalid"));
271
272 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setCollectionFormat(String). Value='null', valid values=['csv','ssv','tsv','pipes','multi']", () -> x.setCollectionFormat(null));
273
274 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setIn(String). Value='null', valid values=['query','header','path','formData','body']", () -> x.setIn(null));
275
276 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setType(String). Value='null', valid values=['string','number','integer','boolean','array','file']", () -> x.setType(null));
277 }
278 }
279
280 @Nested class B_emptyTests extends TestBase {
281
282 private static final BeanTester<ParameterInfo> TESTER =
283 testBean(bean())
284 .props("description,in,name,required,schema,type,format,allowEmptyValue,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf")
285 .vals("<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>")
286 .json("{}")
287 .string("{}")
288 ;
289
290 @Test void b01_gettersAndSetters() {
291 TESTER.assertGettersAndSetters();
292 }
293
294 @Test void b02_copy() {
295 TESTER.assertCopy();
296 }
297
298 @Test void b03_toJson() {
299 TESTER.assertToJson();
300 }
301
302 @Test void b04_fromJson() {
303 TESTER.assertFromJson();
304 }
305
306 @Test void b05_roundTrip() {
307 TESTER.assertRoundTrip();
308 }
309
310 @Test void b06_toString() {
311 TESTER.assertToString();
312 }
313
314 @Test void b07_keySet() {
315 assertEmpty(TESTER.bean().keySet());
316 }
317 }
318
319 @Nested class C_extraProperties extends TestBase {
320
321 private static final BeanTester<ParameterInfo> TESTER =
322 testBean(
323 bean()
324 .set("allowEmptyValue", true)
325 .set("collectionFormat", "a")
326 .set("default", "b")
327 .set("description", "c")
328 .set("enum", set("d"))
329 .set("example", "e")
330 .set("examples", map("f", "g"))
331 .set("exclusiveMaximum", true)
332 .set("exclusiveMinimum", true)
333 .set("format", "h")
334 .set("in", "f")
335 .set("items", items().setType("g"))
336 .set("maximum", 1)
337 .set("maxItems", 2)
338 .set("maxLength", 3)
339 .set("minimum", 4)
340 .set("minItems", 5)
341 .set("minLength", 6)
342 .set("multipleOf", 7)
343 .set("name", "h")
344 .set("pattern", "i")
345 .set("required", true)
346 .set("schema", schemaInfo().setType("j"))
347 .set("type", "k")
348 .set("uniqueItems", true)
349 .set("x3", "x3a")
350 .set("x4", null)
351 )
352 .props("allowEmptyValue,collectionFormat,default,description,enum,example,examples,exclusiveMaximum,exclusiveMinimum,format,in,items{type},maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,name,pattern,required,schema{type},type,uniqueItems,x3,x4")
353 .vals("true,a,b,c,[d],e,{f=g},true,true,h,f,{g},1,2,3,4,5,6,7,h,i,true,{j},k,true,x3a,<null>")
354 .json("{allowEmptyValue:true,collectionFormat:'a','default':'b',description:'c','enum':['d'],example:'e',examples:{f:'g'},exclusiveMaximum:true,exclusiveMinimum:true,format:'h','in':'f',items:{type:'g'},maxItems:2,maxLength:3,maximum:1,minItems:5,minLength:6,minimum:4,multipleOf:7,name:'h',pattern:'i',required:true,schema:{type:'j'},type:'k',uniqueItems:true,x3:'x3a'}")
355 .string("{'allowEmptyValue':true,'collectionFormat':'a','default':'b','description':'c','enum':['d'],'example':'e','examples':{'f':'g'},'exclusiveMaximum':true,'exclusiveMinimum':true,'format':'h','in':'f','items':{'type':'g'},'maxItems':2,'maxLength':3,'maximum':1,'minItems':5,'minLength':6,'minimum':4,'multipleOf':7,'name':'h','pattern':'i','required':true,'schema':{'type':'j'},'type':'k','uniqueItems':true,'x3':'x3a'}".replace('\'', '"'))
356 ;
357
358 @Test void c01_gettersAndSetters() {
359 TESTER.assertGettersAndSetters();
360 }
361
362 @Test void c02_copy() {
363 TESTER.assertCopy();
364 }
365
366 @Test void c03_toJson() {
367 TESTER.assertToJson();
368 }
369
370 @Test void c04_fromJson() {
371 TESTER.assertFromJson();
372 }
373
374 @Test void c05_roundTrip() {
375 TESTER.assertRoundTrip();
376 }
377
378 @Test void c06_toString() {
379 TESTER.assertToString();
380 }
381
382 @Test void c07_keySet() {
383 assertList(TESTER.bean().keySet(), "allowEmptyValue", "collectionFormat", "default", "description", "enum", "example", "examples", "exclusiveMaximum", "exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern", "required", "schema", "type", "uniqueItems", "x3", "x4");
384 }
385
386 @Test void c08_get() {
387 assertMapped(
388 TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
389 "allowEmptyValue,collectionFormat,default,description,enum,example,examples,exclusiveMaximum,exclusiveMinimum,format,in,items{type},maxItems,maxLength,maximum,minItems,minLength,minimum,multipleOf,name,pattern,required,schema{type},type,uniqueItems,x3,x4",
390 "true,a,b,c,[d],e,{f=g},true,true,h,f,{g},2,3,1,5,6,4,7,h,i,true,{j},k,true,x3a,<null>"
391 );
392 }
393
394 @Test void c09_getTypes() {
395 assertMapped(
396 TESTER.bean(), (obj,prop) -> simpleClassNameOf(obj.get(prop, Object.class)),
397 "allowEmptyValue,collectionFormat,default,description,enum,example,examples,exclusiveMaximum,exclusiveMinimum,format,in,items,maxItems,maxLength,maximum,minItems,minLength,minimum,multipleOf,name,pattern,required,schema,type,uniqueItems,x3,x4",
398 "Boolean,String,String,String,LinkedHashSet,String,LinkedHashMap,Boolean,Boolean,String,String,Items,Integer,Integer,Integer,Integer,Integer,Integer,Integer,String,String,Boolean,SchemaInfo,String,Boolean,String,<null>"
399 );
400 }
401
402 @Test void c10_nullPropertyValue() {
403 assertThrows(IllegalArgumentException.class, ()->bean().get(null));
404 assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
405 assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
406 }
407 }
408
409 @Nested class D_refs extends TestBase {
410
411 @Test void d01_resolveRefs_schema() {
412 var swagger = swagger()
413 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
414
415 assertBean(
416 parameterInfo().setName("pet").setIn("body").setSchema(schemaInfo().setRef("#/definitions/Pet")).resolveRefs(swagger, new ArrayDeque<>(), 10),
417 "name,in,schema{type,title}",
418 "pet,body,{object,Pet}"
419 );
420 }
421
422 @Test void d02_resolveRefs_items() {
423 var swagger = swagger()
424 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
425
426 assertBean(
427 parameterInfo().setName("pets").setIn("query").setType("array").setItems(items().setRef("#/definitions/Pet")).resolveRefs(swagger, new ArrayDeque<>(), 10),
428 "name,in,type,items{type,title}",
429 "pets,query,array,{object,Pet}"
430 );
431 }
432
433 @Test void d03_resolveRefs_maxDepth() {
434 var swagger = swagger()
435 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
436
437 assertBean(
438 parameterInfo().setName("pet").setIn("body").setSchema(schemaInfo().setRef("#/definitions/Pet")).resolveRefs(swagger, new ArrayDeque<>(), 0),
439 "name,in,schema{ref}",
440 "pet,body,{#/definitions/Pet}"
441 );
442 }
443
444 @Test void d04_resolveRefs_nullSchema() {
445 var swagger = swagger()
446 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
447
448 assertBean(
449 parameterInfo().setName("pet").setIn("body").resolveRefs(swagger, new ArrayDeque<>(), 10),
450 "name,in,schema",
451 "pet,body,<null>"
452 );
453 }
454
455 @Test void d05_resolveRefs_nullItems() {
456 var swagger = swagger()
457 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
458
459 assertBean(
460 parameterInfo().setName("pets").setIn("query").setType("array").resolveRefs(swagger, new ArrayDeque<>(), 10),
461 "name,in,type,items",
462 "pets,query,array,<null>"
463 );
464 }
465
466 @Test void d06_resolveRefs_bothNull() {
467 var swagger = swagger()
468 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
469
470 assertBean(
471 parameterInfo().setName("test").setIn("query").resolveRefs(swagger, new ArrayDeque<>(), 10),
472 "name,in,schema,items",
473 "test,query,<null>,<null>"
474 );
475 }
476 }
477
478
479
480
481
482 private static ParameterInfo bean() {
483 return parameterInfo();
484 }
485
486 }