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