View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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 org.apache.juneau.*;
26  import org.junit.jupiter.api.*;
27  
28  /**
29   * Testcase for {@link Components}.
30   */
31  class Components_Test extends TestBase {
32  
33  	@Nested class A_basicTests extends TestBase {
34  
35  		private static final BeanTester<Components> TESTER =
36  			testBean(
37  				bean()
38  					.setCallbacks(map("a1", callback()))
39  					.setExamples(map("b1", example().setSummary("b2")))
40  					.setHeaders(map("c1", headerInfo(schemaInfo("c2"))))
41  					.setLinks(map("d1", link().setOperationId("d2")))
42  					.setParameters(map("e1", parameter("e2", "e3")))
43  					.setRequestBodies(map("f1", requestBodyInfo().setDescription("f2")))
44  					.setResponses(map("g1", response("g2")))
45  					.setSchemas(map("h1", schemaInfo().setType("h2")))
46  					.setSecuritySchemes(map("i1", securitySchemeInfo("i2")))
47  			)
48  			.props("callbacks{a1},examples{b1{summary}},headers{c1{schema{type}}},links{d1{operationId}},parameters{e1{in,name}},requestBodies{f1{description}},responses{g1{description}},schemas{h1{type}},securitySchemes{i1{type}}")
49  			.vals("{{}},{{b2}},{{{c2}}},{{d2}},{{e2,e3}},{{f2}},{{g2}},{{h2}},{{i2}}")
50  			.json("{callbacks:{a1:{}},examples:{b1:{summary:'b2'}},headers:{c1:{schema:{type:'c2'}}},links:{d1:{operationId:'d2'}},parameters:{e1:{'in':'e2',name:'e3'}},requestBodies:{f1:{description:'f2'}},responses:{g1:{description:'g2'}},schemas:{h1:{type:'h2'}},securitySchemes:{i1:{type:'i2'}}}")
51  			.string("{'callbacks':{'a1':{}},'examples':{'b1':{'summary':'b2'}},'headers':{'c1':{'schema':{'type':'c2'}}},'links':{'d1':{'operationId':'d2'}},'parameters':{'e1':{'in':'e2','name':'e3'}},'requestBodies':{'f1':{'description':'f2'}},'responses':{'g1':{'description':'g2'}},'schemas':{'h1':{'type':'h2'}},'securitySchemes':{'i1':{'type':'i2'}}}".replace('\'','"'))
52  		;
53  
54  		@Test void a01_gettersAndSetters() {
55  			TESTER.assertGettersAndSetters();
56  		}
57  
58  		@Test void a02_copy() {
59  			TESTER.assertCopy();
60  		}
61  
62  		@Test void a03_toJson() {
63  			TESTER.assertToJson();
64  		}
65  
66  		@Test void a04_fromJson() {
67  			TESTER.assertFromJson();
68  		}
69  
70  		@Test void a05_roundTrip() {
71  			TESTER.assertRoundTrip();
72  		}
73  
74  		@Test void a06_toString() {
75  			TESTER.assertToString();
76  		}
77  
78  		@Test void a07_keySet() {
79  			assertList(TESTER.bean().keySet(), "callbacks", "examples", "headers", "links", "parameters", "requestBodies", "responses", "schemas", "securitySchemes");
80  		}
81  
82  		@Test void a08_nullParameters() {
83  			var x = bean();
84  			assertThrows(IllegalArgumentException.class, () -> x.get(null, String.class));
85  			assertThrows(IllegalArgumentException.class, () -> x.set(null, "value"));
86  		}
87  
88  		@Test void a09_asMap() {
89  			assertBean(
90  				bean()
91  					.setSchemas(map("a1", schemaInfo("a2")))
92  					.set("x1", "x1a")
93  					.asMap(),
94  				"schemas{a1{type}},x1",
95  				"{{a2}},x1a"
96  			);
97  		}
98  
99  		@Test void a10_extraKeys() {
100 			var x = bean().set("x1", "x1a").set("x2", "x2a");
101 			assertList(x.extraKeys(), "x1", "x2");
102 			assertEmpty(bean().extraKeys());
103 		}
104 
105 		@Test void a11_strictMode() {
106 			assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
107 
108 			assertFalse(bean().isStrict());
109 			assertTrue(bean().strict().isStrict());
110 			assertFalse(bean().strict(false).isStrict());
111 
112 			assertDoesNotThrow(() -> bean().set("foo", "bar"));
113 		}
114 	}
115 
116 	@Nested class B_emptyTests extends TestBase {
117 
118 		private static final BeanTester<Components> TESTER =
119 			testBean(bean())
120 			.props("schemas,responses,parameters,examples,requestBodies,headers,securitySchemes,links,callbacks")
121 			.vals("<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>")
122 			.json("{}")
123 			.string("{}")
124 		;
125 
126 		@Test void b01_gettersAndSetters() {
127 			TESTER.assertGettersAndSetters();
128 		}
129 
130 		@Test void b02_copy() {
131 			TESTER.assertCopy();
132 		}
133 
134 		@Test void b03_toJson() {
135 			TESTER.assertToJson();
136 		}
137 
138 		@Test void b04_fromJson() {
139 			TESTER.assertFromJson();
140 		}
141 
142 		@Test void b05_roundTrip() {
143 			TESTER.assertRoundTrip();
144 		}
145 
146 		@Test void b06_toString() {
147 			TESTER.assertToString();
148 		}
149 
150 		@Test void b07_keySet() {
151 			assertEmpty(TESTER.bean().keySet());
152 		}
153 	}
154 
155 	@Nested class C_extraProperties extends TestBase {
156 		private static final BeanTester<Components> TESTER =
157 			testBean(
158 				bean()
159 					.set("callbacks", m("a1", callback()))
160 					.set("examples", m("b1", example().setSummary("b2")))
161 					.set("headers", m("c1", headerInfo(schemaInfo("c2"))))
162 					.set("links", m("d1", link().setOperationId("d2")))
163 					.set("parameters", m("e1", parameter("e2", "e3")))
164 					.set("requestBodies", m("f1", requestBodyInfo().setDescription("f2")))
165 					.set("responses", m("g1", response("g2")))
166 					.set("schemas", m("h1", schemaInfo().setType("h2")))
167 					.set("securitySchemes", m("i1", securitySchemeInfo("i2")))
168 					.set("x1", "x1a")
169 					.set("x2", null)
170 			)
171 			.props("callbacks{a1},examples{b1{summary}},headers{c1{schema{type}}},links{d1{operationId}},parameters{e1{in,name}},requestBodies{f1{description}},responses{g1{description}},schemas{h1{type}},securitySchemes{i1{type}},x1,x2")
172 			.vals("{{}},{{b2}},{{{c2}}},{{d2}},{{e2,e3}},{{f2}},{{g2}},{{h2}},{{i2}},x1a,<null>")
173 			.json("{callbacks:{a1:{}},examples:{b1:{summary:'b2'}},headers:{c1:{schema:{type:'c2'}}},links:{d1:{operationId:'d2'}},parameters:{e1:{'in':'e2',name:'e3'}},requestBodies:{f1:{description:'f2'}},responses:{g1:{description:'g2'}},schemas:{h1:{type:'h2'}},securitySchemes:{i1:{type:'i2'}},x1:'x1a'}")
174 			.string("{'callbacks':{'a1':{}},'examples':{'b1':{'summary':'b2'}},'headers':{'c1':{'schema':{'type':'c2'}}},'links':{'d1':{'operationId':'d2'}},'parameters':{'e1':{'in':'e2','name':'e3'}},'requestBodies':{'f1':{'description':'f2'}},'responses':{'g1':{'description':'g2'}},'schemas':{'h1':{'type':'h2'}},'securitySchemes':{'i1':{'type':'i2'}},'x1':'x1a'}".replace('\'','"'))
175 		;
176 
177 		@Test void c01_gettersAndSetters() {
178 			TESTER.assertGettersAndSetters();
179 		}
180 
181 		@Test void c02_copy() {
182 			TESTER.assertCopy();
183 		}
184 
185 		@Test void c03_toJson() {
186 			TESTER.assertToJson();
187 		}
188 
189 		@Test void c04_fromJson() {
190 			TESTER.assertFromJson();
191 		}
192 
193 		@Test void c05_roundTrip() {
194 			TESTER.assertRoundTrip();
195 		}
196 
197 		@Test void c06_toString() {
198 			TESTER.assertToString();
199 		}
200 
201 		@Test void c07_keySet() {
202 			assertList(TESTER.bean().keySet(), "callbacks", "examples", "headers", "links", "parameters", "requestBodies", "responses", "schemas", "securitySchemes", "x1", "x2");
203 		}
204 
205 		@Test void c08_get() {
206 			assertMapped(
207 				TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
208 				"callbacks{a1},examples{b1{summary}},headers{c1{schema{type}}},links{d1{operationId}},parameters{e1{in,name}},requestBodies{f1{description}},responses{g1{description}},schemas{h1{type}},securitySchemes{i1{type}},x1,x2",
209 				"{{}},{{b2}},{{{c2}}},{{d2}},{{e2,e3}},{{f2}},{{g2}},{{h2}},{{i2}},x1a,<null>"
210 			);
211 		}
212 
213 		@Test void c09_getTypes() {
214 			assertMapped(
215 				TESTER.bean(), (obj,prop) -> cns(obj.get(prop, Object.class)),
216 				"callbacks,examples,headers,links,parameters,requestBodies,responses,schemas,securitySchemes,x1,x2",
217 				"FilteredMap,FilteredMap,FilteredMap,FilteredMap,FilteredMap,FilteredMap,FilteredMap,FilteredMap,FilteredMap,String,<null>"
218 			);
219 		}
220 
221 		@Test void c10_nullPropertyValue() {
222 			assertThrows(IllegalArgumentException.class, ()->bean().get(null));
223 			assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
224 			assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
225 		}
226 	}
227 
228 	//---------------------------------------------------------------------------------------------
229 	// Helper methods
230 	//---------------------------------------------------------------------------------------------
231 
232 	private static Components bean() {
233 		return components();
234 	}
235 }