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 HeaderInfo_Test extends TestBase {
35
36 @Nested class A_basicTests extends TestBase {
37
38 private static final BeanTester<HeaderInfo> TESTER =
39 testBean(
40 bean()
41 .setCollectionFormat("a")
42 .setDefault("b")
43 .setDescription("c")
44 .setEnum("d")
45 .setExample("e")
46 .setExclusiveMaximum(true)
47 .setExclusiveMinimum(true)
48 .setFormat("f")
49 .setItems(items().setType("g"))
50 .setMaximum(1)
51 .setMaxItems(2)
52 .setMaxLength(3)
53 .setMinimum(4)
54 .setMinItems(5)
55 .setMinLength(6)
56 .setMultipleOf(7)
57 .setPattern("h")
58 .setRef("i")
59 .setType("j")
60 .setUniqueItems(true)
61 )
62 .props("collectionFormat,default,description,enum,example,exclusiveMaximum,exclusiveMinimum,format,items{type},maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,pattern,ref,type,uniqueItems")
63 .vals("a,b,c,[d],e,true,true,f,{g},1,2,3,4,5,6,7,h,i,j,true")
64 .json("{'$ref':'i',collectionFormat:'a','default':'b',description:'c','enum':['d'],example:'e',exclusiveMaximum:true,exclusiveMinimum:true,format:'f',items:{type:'g'},maxItems:2,maxLength:3,maximum:1,minItems:5,minLength:6,minimum:4,multipleOf:7,pattern:'h',type:'j',uniqueItems:true}")
65 .string("{'$ref':'i','collectionFormat':'a','default':'b','description':'c','enum':['d'],'example':'e','exclusiveMaximum':true,'exclusiveMinimum':true,'format':'f','items':{'type':'g'},'maxItems':2,'maxLength':3,'maximum':1,'minItems':5,'minLength':6,'minimum':4,'multipleOf':7,'pattern':'h','type':'j','uniqueItems':true}".replace('\'', '"'))
66 ;
67
68 @Test void a01_gettersAndSetters() {
69 TESTER.assertGettersAndSetters();
70 }
71
72 @Test void a02_copy() {
73 TESTER.assertCopy();
74 }
75
76 @Test void a03_toJson() {
77 TESTER.assertToJson();
78 }
79
80 @Test void a04_fromJson() {
81 TESTER.assertFromJson();
82 }
83
84 @Test void a05_roundTrip() {
85 TESTER.assertRoundTrip();
86 }
87
88 @Test void a06_toString() {
89 TESTER.assertToString();
90 }
91
92 @Test void a07_keySet() {
93 assertList(TESTER.bean().keySet(), "$ref", "collectionFormat", "default", "description", "enum", "example", "exclusiveMaximum", "exclusiveMinimum", "format", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "pattern", "type", "uniqueItems");
94 }
95
96 @Test void a08_nullParameters() {
97 var x = bean();
98 assertThrows(IllegalArgumentException.class, () -> x.get(null, String.class));
99 assertThrows(IllegalArgumentException.class, () -> x.set(null, "value"));
100 }
101
102 @Test void a09_addMethods() {
103 var x = bean().addEnum("a1");
104 assertNotNull(x);
105 assertNotNull(x.getEnum());
106 }
107
108 @Test void a10_asMap() {
109 assertBean(
110 bean()
111 .setDescription("a")
112 .setType("b")
113 .set("x1", "x1a")
114 .asMap(),
115 "description,type,x1",
116 "a,b,x1a"
117 );
118 }
119
120 @Test void a11_extraKeys() {
121 var x = bean().set("x1", "x1a").set("x2", "x2a");
122 assertList(x.extraKeys(), "x1", "x2");
123 assertEmpty(bean().extraKeys());
124 }
125
126 @Test void a12_strictMode() {
127 assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
128 assertDoesNotThrow(() -> bean().set("foo", "bar"));
129
130 assertFalse(bean().isStrict());
131 assertTrue(bean().strict().isStrict());
132 assertFalse(bean().strict(false).isStrict());
133
134 var x = bean().strict();
135 var y = bean();
136
137 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setCollectionFormat(String). Value='invalid', valid values=['csv','ssv','tsv','pipes','multi']", () -> x.setCollectionFormat("invalid"));
138 assertDoesNotThrow(() -> x.setCollectionFormat("csv"));
139 assertDoesNotThrow(() -> x.setCollectionFormat("ssv"));
140 assertDoesNotThrow(() -> x.setCollectionFormat("tsv"));
141 assertDoesNotThrow(() -> x.setCollectionFormat("pipes"));
142 assertDoesNotThrow(() -> x.setCollectionFormat("multi"));
143 assertDoesNotThrow(() -> y.setCollectionFormat("invalid"));
144
145 assertThrowsWithMessage(RuntimeException.class, "Invalid value passed in to setType(String). Value='invalid', valid values=['string','number','integer','boolean','array']", () -> x.setType("invalid"));
146 assertDoesNotThrow(() -> x.setType("string"));
147 assertDoesNotThrow(() -> x.setType("number"));
148 assertDoesNotThrow(() -> x.setType("integer"));
149 assertDoesNotThrow(() -> x.setType("boolean"));
150 assertDoesNotThrow(() -> x.setType("array"));
151 assertDoesNotThrow(() -> y.setType("invalid"));
152 }
153 }
154
155 @Nested class B_emptyTests extends TestBase {
156
157 private static final BeanTester<HeaderInfo> TESTER =
158 testBean(bean())
159 .props("description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf")
160 .vals("<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>")
161 .json("{}")
162 .string("{}")
163 ;
164
165 @Test void b01_gettersAndSetters() {
166 TESTER.assertGettersAndSetters();
167 }
168
169 @Test void b02_copy() {
170 TESTER.assertCopy();
171 }
172
173 @Test void b03_toJson() {
174 TESTER.assertToJson();
175 }
176
177 @Test void b04_fromJson() {
178 TESTER.assertFromJson();
179 }
180
181 @Test void b05_roundTrip() {
182 TESTER.assertRoundTrip();
183 }
184
185 @Test void b06_toString() {
186 TESTER.assertToString();
187 }
188
189 @Test void b07_keySet() {
190 assertEmpty(TESTER.bean().keySet());
191 }
192 }
193
194 @Nested class C_extraProperties extends TestBase {
195
196 private static final BeanTester<HeaderInfo> TESTER =
197 testBean(
198 bean()
199 .set("collectionFormat", "a")
200 .set("default", "b")
201 .set("description", "c")
202 .set("enum", set("d"))
203 .set("example", "e")
204 .set("exclusiveMaximum", true)
205 .set("exclusiveMinimum", true)
206 .set("format", "f")
207 .set("items", items().setType("g"))
208 .set("maximum", 1)
209 .set("maxItems", 2)
210 .set("maxLength", 3)
211 .set("minimum", 4)
212 .set("minItems", 5)
213 .set("minLength", 6)
214 .set("multipleOf", 7)
215 .set("pattern", "h")
216 .set("$ref", "i")
217 .set("type", "j")
218 .set("uniqueItems", true)
219 .set("x1", "x1a")
220 .set("x2", null)
221 )
222 .props("collectionFormat,default,description,enum,example,exclusiveMaximum,exclusiveMinimum,format,items{type},maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,pattern,ref,type,uniqueItems,x1,x2")
223 .vals("a,b,c,[d],e,true,true,f,{g},1,2,3,4,5,6,7,h,i,j,true,x1a,<null>")
224 .json("{'$ref':'i',collectionFormat:'a','default':'b',description:'c','enum':['d'],example:'e',exclusiveMaximum:true,exclusiveMinimum:true,format:'f',items:{type:'g'},maxItems:2,maxLength:3,maximum:1,minItems:5,minLength:6,minimum:4,multipleOf:7,pattern:'h',type:'j',uniqueItems:true,x1:'x1a'}")
225 .string("{'$ref':'i','collectionFormat':'a','default':'b','description':'c','enum':['d'],'example':'e','exclusiveMaximum':true,'exclusiveMinimum':true,'format':'f','items':{'type':'g'},'maxItems':2,'maxLength':3,'maximum':1,'minItems':5,'minLength':6,'minimum':4,'multipleOf':7,'pattern':'h','type':'j','uniqueItems':true,'x1':'x1a'}".replace('\'', '"'))
226 ;
227
228 @Test void c01_gettersAndSetters() {
229 TESTER.assertGettersAndSetters();
230 }
231
232 @Test void c02_copy() {
233 TESTER.assertCopy();
234 }
235
236 @Test void c03_toJson() {
237 TESTER.assertToJson();
238 }
239
240 @Test void c04_fromJson() {
241 TESTER.assertFromJson();
242 }
243
244 @Test void c05_roundTrip() {
245 TESTER.assertRoundTrip();
246 }
247
248 @Test void c06_toString() {
249 TESTER.assertToString();
250 }
251
252 @Test void c07_keySet() {
253 assertList(TESTER.bean().keySet(), "$ref", "collectionFormat", "default", "description", "enum", "example", "exclusiveMaximum", "exclusiveMinimum", "format", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf", "pattern", "type", "uniqueItems", "x1", "x2");
254 }
255
256 @Test void c08_get() {
257 assertMapped(
258 TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
259 "collectionFormat,default,description,enum,example,exclusiveMaximum,exclusiveMinimum,format,items{type},maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,pattern,$ref,type,uniqueItems,x1,x2",
260 "a,b,c,[d],e,true,true,f,{g},1,2,3,4,5,6,7,h,i,j,true,x1a,<null>"
261 );
262 }
263
264 @Test void c09_getTypes() {
265 assertMapped(
266 TESTER.bean(), (obj,prop) -> cns(obj.get(prop, Object.class)),
267 "collectionFormat,default,description,enum,example,exclusiveMaximum,exclusiveMinimum,format,items,maximum,maxItems,maxLength,minimum,minItems,minLength,multipleOf,pattern,$ref,type,uniqueItems,x1,x2",
268 "String,String,String,LinkedHashSet,String,Boolean,Boolean,String,Items,Integer,Integer,Integer,Integer,Integer,Integer,Integer,String,String,String,Boolean,String,<null>"
269 );
270 }
271
272 @Test void c10_nullPropertyValue() {
273 assertThrows(IllegalArgumentException.class, ()->bean().get(null));
274 assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
275 assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
276 }
277 }
278
279 @Nested class D_refs extends TestBase {
280
281 @Test void d01_resolveRefs_basic() {
282 var swagger = swagger()
283 .addDefinition("MyHeader", JsonMap.of("type", "string", "description", "My Header"));
284
285 assertBean(
286 headerInfo().setRef("#/definitions/MyHeader").resolveRefs(swagger, new ArrayDeque<>(), 10),
287 "type,description",
288 "string,My Header"
289 );
290 }
291
292 @Test void d02_resolveRefs_withItems() {
293 var swagger = swagger()
294 .addDefinition("MyItem", JsonMap.of("type", "string"))
295 .addDefinition("MyHeader", JsonMap.of("type", "array", "items", JsonMap.of("$ref", "#/definitions/MyItem")));
296
297 assertBean(
298 headerInfo().setRef("#/definitions/MyHeader").resolveRefs(swagger, new ArrayDeque<>(), 10),
299 "type,items{type}",
300 "array,{string}"
301 );
302 }
303
304 @Test void d03_resolveRefs_maxDepth() {
305 var swagger = swagger()
306 .addDefinition("MyItem", JsonMap.of("type", "string"))
307 .addDefinition("MyHeader", JsonMap.of("type", "array", "items", JsonMap.of("$ref", "#/definitions/MyItem")));
308
309 assertBean(headerInfo().setRef("#/definitions/MyHeader").resolveRefs(swagger, new ArrayDeque<>(), 1),
310 "type,items{ref}",
311 "array,{#/definitions/MyItem}"
312 );
313 }
314
315 @Test void d04_resolveRefs_noRefNoItems() {
316
317 var swagger = swagger();
318 var header = headerInfo()
319 .setType("string")
320 .setDescription("Test header");
321
322 var result = header.resolveRefs(swagger, new ArrayDeque<>(), 10);
323
324
325 assertSame(header, result);
326 assertEquals("string", result.getType());
327 assertEquals("Test header", result.getDescription());
328 }
329
330 @Test void d05_resolveRefs_noRefWithItems() {
331
332 var swagger = swagger()
333 .addDefinition("MyItem", JsonMap.of("type", "string"));
334
335 var header = headerInfo()
336 .setType("array")
337 .setItems(items().setRef("#/definitions/MyItem"));
338
339 var result = header.resolveRefs(swagger, new ArrayDeque<>(), 10);
340
341
342 assertSame(header, result);
343 assertEquals("array", result.getType());
344 assertNotNull(result.getItems());
345 assertEquals("string", result.getItems().getType());
346 assertNull(result.getItems().getRef());
347 }
348
349 @Test void d06_resolveRefs_circularReference() {
350
351 var swagger = swagger()
352 .addDefinition("Header1", JsonMap.of("$ref", "#/definitions/Header2"))
353 .addDefinition("Header2", JsonMap.of("$ref", "#/definitions/Header1"));
354
355 var refStack = new ArrayDeque<String>();
356 refStack.add("#/definitions/Header1");
357
358 var header = headerInfo().setRef("#/definitions/Header1");
359 var result = header.resolveRefs(swagger, refStack, 10);
360
361
362 assertSame(header, result);
363 assertEquals("#/definitions/Header1", result.getRef());
364 }
365
366 @Test void d07_resolveRefs_maxDepthDirect() {
367
368 var swagger = swagger()
369 .addDefinition("MyHeader", JsonMap.of("type", "string"));
370
371
372 var refStack = new ArrayDeque<String>();
373 refStack.add("dummy1");
374 refStack.add("dummy2");
375 refStack.add("dummy3");
376
377 var header = headerInfo().setRef("#/definitions/MyHeader");
378 var result = header.resolveRefs(swagger, refStack, 3);
379
380
381 assertSame(header, result);
382 assertEquals("#/definitions/MyHeader", result.getRef());
383 }
384 }
385
386
387
388
389
390 private static HeaderInfo bean() {
391 return headerInfo();
392 }
393 }