1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.bean.openapi3;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.bean.openapi3.OpenApiBuilder.*;
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.junit.jupiter.api.*;
29
30
31
32
33 class HeaderInfo_Test extends TestBase {
34
35 @Nested class A_basicTests extends TestBase {
36
37 private static final BeanTester<HeaderInfo> TESTER =
38 testBean(
39 bean()
40 .setAllowEmptyValue(true)
41 .setAllowReserved(true)
42 .setDeprecated(true)
43 .setDescription("a")
44 .setExample("b")
45 .setExamples(map("c1",example().setDescription("c2")))
46 .setExplode(true)
47 .setRef("c")
48 .setRequired(true)
49 .setSchema(schemaInfo().setType("d"))
50 )
51 .props("allowEmptyValue,allowReserved,deprecated,description,example,examples{c1{description}},explode,ref,required,schema{type}")
52 .vals("true,true,true,a,b,{{c2}},true,c,true,{d}")
53 .json("{'$ref':'c',allowEmptyValue:true,allowReserved:true,deprecated:true,description:'a',examples:{c1:{description:'c2'}},explode:true,required:true,schema:{type:'d'},'x-example':'b'}")
54 .string("{'$ref':'c','allowEmptyValue':true,'allowReserved':true,'deprecated':true,'description':'a','examples':{'c1':{'description':'c2'}},'explode':true,'required':true,'schema':{'type':'d'},'x-example':'b'}".replace('\'','"'))
55 ;
56
57 @Test void a01_gettersAndSetters() {
58 TESTER.assertGettersAndSetters();
59 }
60
61 @Test void a02_copy() {
62 TESTER.assertCopy();
63 }
64
65 @Test void a03_toJson() {
66 TESTER.assertToJson();
67 }
68
69 @Test void a04_fromJson() {
70 TESTER.assertFromJson();
71 }
72
73 @Test void a05_roundTrip() {
74 TESTER.assertRoundTrip();
75 }
76
77 @Test void a06_toString() {
78 TESTER.assertToString();
79 }
80
81 @Test void a07_keySet() {
82 assertList(TESTER.bean().keySet(), "$ref", "allowEmptyValue", "allowReserved", "deprecated", "description", "examples", "explode", "required", "schema", "x-example");
83 }
84
85 @Test void a08_nullParameters() {
86 var x = bean();
87 assertThrows(IllegalArgumentException.class, () -> x.get(null, String.class));
88 assertThrows(IllegalArgumentException.class, () -> x.set(null, "value"));
89 assertThrows(IllegalArgumentException.class, () -> x.addExample(null, example()));
90 assertThrows(IllegalArgumentException.class, () -> x.addExample("test", null));
91 }
92
93 @Test void a08b_getSetRef() {
94
95 var x = bean();
96 x.set("$ref", "#/components/headers/MyHeader");
97 assertEquals("#/components/headers/MyHeader", x.get("$ref", String.class));
98 assertEquals("#/components/headers/MyHeader", x.getRef());
99 }
100
101 @Test void a09_addMethods() {
102 assertBean(
103 bean()
104 .addExample("a1", example().setSummary("a2")),
105 "examples{a1{summary}}",
106 "{{a2}}"
107 );
108 }
109
110 @Test void a10_asMap() {
111 assertBean(
112 bean()
113 .setDescription("a")
114 .set("x1", "x1a")
115 .asMap(),
116 "description,x1",
117 "a,x1a"
118 );
119 }
120
121 @Test void a11_extraKeys() {
122 var x = bean().set("x1", "x1a").set("x2", "x2a");
123 assertList(x.extraKeys(), "x1", "x2");
124 assertEmpty(bean().extraKeys());
125 }
126
127 @Test void a12_strictMode() {
128 assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
129 assertDoesNotThrow(() -> bean().set("foo", "bar"));
130
131 assertFalse(bean().isStrict());
132 assertTrue(bean().strict().isStrict());
133 assertFalse(bean().strict(false).isStrict());
134 }
135 }
136
137 @Nested class B_emptyTests extends TestBase {
138
139 private static final BeanTester<HeaderInfo> TESTER =
140 testBean(bean())
141 .props("description,required,explode,deprecated,allowEmptyValue,allowReserved,ref,schema,example,examples")
142 .vals("<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>")
143 .json("{}")
144 .string("{}")
145 ;
146
147 @Test void b01_gettersAndSetters() {
148 TESTER.assertGettersAndSetters();
149 }
150
151 @Test void b02_copy() {
152 TESTER.assertCopy();
153 }
154
155 @Test void b03_toJson() {
156 TESTER.assertToJson();
157 }
158
159 @Test void b04_fromJson() {
160 TESTER.assertFromJson();
161 }
162
163 @Test void b05_roundTrip() {
164 TESTER.assertRoundTrip();
165 }
166
167 @Test void b06_toString() {
168 TESTER.assertToString();
169 }
170
171 @Test void b07_keySet() {
172 assertEmpty(TESTER.bean().keySet());
173 }
174 }
175
176 @Nested class C_extraProperties extends TestBase {
177 private static final BeanTester<HeaderInfo> TESTER =
178 testBean(
179 bean()
180 .set("allowEmptyValue", true)
181 .set("allowReserved", true)
182 .set("deprecated", true)
183 .set("description", "a")
184 .set("x-example", "b")
185 .set("examples", m("c1", example().setSummary("c2")))
186 .set("explode", true)
187 .set("required", true)
188 .set("schema", schemaInfo("d"))
189 .set("style", "e")
190 .set("x1", "x1a")
191 .set("x2", null)
192 )
193 .props("allowEmptyValue,allowReserved,deprecated,description,example,examples{c1{summary}},explode,required,schema{type},style,x1,x2")
194 .vals("true,true,true,a,b,{{c2}},true,true,{d},e,x1a,<null>")
195 .json("{allowEmptyValue:true,allowReserved:true,deprecated:true,description:'a',examples:{c1:{summary:'c2'}},explode:true,required:true,schema:{type:'d'},style:'e','x-example':'b',x1:'x1a'}")
196 .string("{'allowEmptyValue':true,'allowReserved':true,'deprecated':true,'description':'a','examples':{'c1':{'summary':'c2'}},'explode':true,'required':true,'schema':{'type':'d'},'style':'e','x-example':'b','x1':'x1a'}".replace('\'', '"'))
197 ;
198
199 @Test void c01_gettersAndSetters() {
200 TESTER.assertGettersAndSetters();
201 }
202
203 @Test void c02_copy() {
204 TESTER.assertCopy();
205 }
206
207 @Test void c03_toJson() {
208 TESTER.assertToJson();
209 }
210
211 @Test void c04_fromJson() {
212 TESTER.assertFromJson();
213 }
214
215 @Test void c05_roundTrip() {
216 TESTER.assertRoundTrip();
217 }
218
219 @Test void c06_toString() {
220 TESTER.assertToString();
221 }
222
223 @Test void c07_keySet() {
224 assertList(TESTER.bean().keySet(), "allowEmptyValue", "allowReserved", "deprecated", "description", "examples", "explode", "required", "schema", "x-example", "style", "x1", "x2");
225 }
226
227 @Test void c08_get() {
228 assertMapped(
229 TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
230 "allowEmptyValue,allowReserved,deprecated,description,x-example,examples{c1{summary}},explode,required,schema{type},style,x1,x2",
231 "true,true,true,a,b,{{c2}},true,true,{d},e,x1a,<null>"
232 );
233 }
234
235 @Test void c09_getTypes() {
236 assertMapped(
237 TESTER.bean(), (obj,prop) -> cns(obj.get(prop, Object.class)),
238 "allowEmptyValue,allowReserved,deprecated,description,x-example,examples,explode,required,schema,style,x1,x2",
239 "Boolean,Boolean,Boolean,String,String,LinkedHashMap,Boolean,Boolean,SchemaInfo,String,String,<null>"
240 );
241 }
242
243 @Test void c10_nullPropertyValue() {
244 assertThrows(IllegalArgumentException.class, ()->bean().get(null));
245 assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
246 assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
247 }
248 }
249
250 @Nested class D_refs extends TestBase {
251
252 @Test void d01_resolveRefs_basic() {
253 var openApi = openApi()
254 .setComponents(components().setSchemas(m(
255 "MyHeader", schemaInfo().setType("string").setDescription("My Header")
256 )));
257
258 assertBean(
259 headerInfo().setRef("#/components/schemas/MyHeader").resolveRefs(openApi, new ArrayDeque<>(), 10),
260 "type,description",
261 "string,My Header"
262 );
263
264
265 assertBean(
266 headerInfo().setRef("#/components/schemas/MyHeader").resolveRefs(openApi, new ArrayDeque<>(), 0),
267 "ref",
268 "#/components/schemas/MyHeader"
269 );
270 }
271
272 @Test void d04_resolveRefs_noRef() {
273
274 var openApi = openApi()
275 .setComponents(components().setSchemas(map("MyHeader", schemaInfo().setType("string"))));
276
277 var header = bean()
278 .setDescription("Test header")
279 .setRequired(true);
280
281 var result = header.resolveRefs(openApi, new ArrayDeque<>(), 10);
282
283
284 assertSame(header, result);
285 assertEquals("Test header", result.getDescription());
286 assertTrue(result.getRequired());
287 }
288
289 @Test void d05_resolveRefs_circularReference() {
290
291 var openApi = openApi()
292 .setComponents(components().setSchemas(map(
293 "Header1", schemaInfo().setRef("#/components/schemas/Header2"),
294 "Header2", schemaInfo().setRef("#/components/schemas/Header1")
295 )));
296
297 var refStack = new ArrayDeque<String>();
298 refStack.add("#/components/schemas/Header1");
299
300 var header = headerInfo().setRef("#/components/schemas/Header1");
301 var result = header.resolveRefs(openApi, refStack, 10);
302
303
304 assertSame(header, result);
305 assertEquals("#/components/schemas/Header1", result.getRef());
306 }
307
308 @Test void d06_resolveRefs_maxDepthDirect() {
309
310 var openApi = openApi()
311 .setComponents(components().setSchemas(map("MyHeader", schemaInfo().setType("string"))));
312
313
314 var refStack = new ArrayDeque<String>();
315 refStack.add("dummy1");
316 refStack.add("dummy2");
317 refStack.add("dummy3");
318
319 var header = headerInfo().setRef("#/components/schemas/MyHeader");
320 var result = header.resolveRefs(openApi, refStack, 3);
321
322
323 assertSame(header, result);
324 assertEquals("#/components/schemas/MyHeader", result.getRef());
325 }
326 }
327
328
329
330
331
332 private static HeaderInfo bean() {
333 return headerInfo();
334 }
335 }