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.junit.jupiter.api.Assertions.*;
22  
23  import org.apache.juneau.*;
24  import org.junit.jupiter.api.*;
25  
26  /**
27   * Testcase for {@link Response}.
28   */
29  class Response_Test extends TestBase {
30  
31  	@Nested class A_basicTests extends TestBase {
32  
33  		private static final BeanTester<Response> TESTER =
34  			testBean(
35  				bean()
36  					.setContent(map("a1", mediaType().setSchema(schemaInfo().setType("a2"))))
37  					.setDescription("b")
38  					.setHeaders(map("c1", headerInfo(schemaInfo().setType("c2"))))
39  					.setLinks(map("d1", link().setOperationId("d2")))
40  			)
41  			.props("content{a1{schema{type}}},description,headers{c1{schema{type}}},links{d1{operationId}}")
42  			.vals("{{{a2}}},b,{{{c2}}},{{d2}}")
43  			.json("{content:{a1:{schema:{type:'a2'}}},description:'b',headers:{c1:{schema:{type:'c2'}}},links:{d1:{operationId:'d2'}}}")
44  			.string("{'content':{'a1':{'schema':{'type':'a2'}}},'description':'b','headers':{'c1':{'schema':{'type':'c2'}}},'links':{'d1':{'operationId':'d2'}}}".replace('\'','"'))
45  		;
46  
47  		@Test void a01_gettersAndSetters() {
48  			TESTER.assertGettersAndSetters();
49  		}
50  
51  		@Test void a02_copy() {
52  			TESTER.assertCopy();
53  		}
54  
55  		@Test void a03_toJson() {
56  			TESTER.assertToJson();
57  		}
58  
59  		@Test void a04_fromJson() {
60  			TESTER.assertFromJson();
61  		}
62  
63  		@Test void a05_roundTrip() {
64  			TESTER.assertRoundTrip();
65  		}
66  
67  		@Test void a06_toString() {
68  			TESTER.assertToString();
69  		}
70  
71  		@Test void a07_keySet() {
72  			assertList(TESTER.bean().keySet(), "content", "description", "headers", "links");
73  		}
74  
75  		@Test void a08_otherGettersAndSetters() {
76  			// No Collection variants for Response setters
77  
78  			// Test special getters
79  			var x = bean()
80  				.setHeaders(map(
81  					"a1", headerInfo(schemaInfo("a2")),
82  					"a3", headerInfo(schemaInfo("a4"))
83  				))
84  				.setContent(map(
85  					"b1", mediaType().setSchema(schemaInfo("b2")),
86  					"b3", mediaType().setSchema(schemaInfo("b4"))
87  				))
88  				.setLinks(map(
89  					"c1", link().setOperationId("c2"),
90  					"c3", link().setOperationId("c4")
91  				));
92  
93  			assertBean(x.getHeader("a1"), "schema{type}", "{a2}");
94  			assertBean(x.getContent("b1"), "schema{type}", "{b2}");
95  			assertBean(x.getLink("c1"), "operationId", "c2");
96  		}
97  
98  		@Test void a09_nullParameters() {
99  			var x = bean();
100 
101 			assertThrows(IllegalArgumentException.class, ()->x.getHeader(null));
102 			assertThrows(IllegalArgumentException.class, ()->x.getContent(null));
103 			assertThrows(IllegalArgumentException.class, ()->x.getLink(null));
104 			assertThrows(IllegalArgumentException.class, ()->x.get(null, String.class));
105 			assertThrows(IllegalArgumentException.class, ()->x.set(null, "value"));
106 			assertThrows(IllegalArgumentException.class, ()->x.addHeader(null, headerInfo()));
107 			assertThrows(IllegalArgumentException.class, ()->x.addHeader("a", null));
108 			assertThrows(IllegalArgumentException.class, ()->x.addContent(null, mediaType()));
109 			assertThrows(IllegalArgumentException.class, ()->x.addContent("a", null));
110 			assertThrows(IllegalArgumentException.class, ()->x.addLink(null, link()));
111 			assertThrows(IllegalArgumentException.class, ()->x.addLink("a", null));
112 		}
113 
114 		@Test void a10_addMethods() {
115 			assertBean(
116 				bean()
117 					.addHeader("a1", headerInfo(schemaInfo("a2")))
118 					.addContent("b1", mediaType().setSchema(schemaInfo("b2")))
119 					.addLink("c1", link().setOperationId("c2")),
120 				"headers{a1{schema{type}}},content{b1{schema{type}}},links{c1{operationId}}",
121 				"{{{a2}}},{{{b2}}},{{c2}}"
122 			);
123 		}
124 
125 		@Test void a11_asMap() {
126 			assertBean(
127 				bean()
128 					.setDescription("a")
129 					.set("x1", "x1a")
130 					.asMap(),
131 				"description,x1",
132 				"a,x1a"
133 			);
134 		}
135 
136 		@Test void a12_extraKeys() {
137 			var x = bean().set("x1", "x1a").set("x2", "x2a");
138 			assertList(x.extraKeys(), "x1", "x2");
139 			assertEmpty(bean().extraKeys());
140 		}
141 
142 		@Test void a13_strictMode() {
143 			assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
144 			assertDoesNotThrow(() -> bean().set("foo", "bar"));
145 
146 			assertFalse(bean().isStrict());
147 			assertTrue(bean().strict().isStrict());
148 			assertFalse(bean().strict(false).isStrict());
149 		}
150 		
151 		@Test void a14_getHeader() {
152 			// Test getHeader with null headers map (covers the null check branch)
153 			var y = bean();
154 			assertNull(y.getHeader("nonexistent"));
155 
156 			// Test with headers set
157 			var x = bean()
158 				.setHeaders(map("header1", headerInfo().setDescription("Test header")));
159 
160 			assertNotNull(x.getHeader("header1"));
161 			assertEquals("Test header", x.getHeader("header1").getDescription());
162 			assertNull(x.getHeader("nonexistent"));
163 
164 			// Test null name parameter
165 			assertThrows(IllegalArgumentException.class, () -> x.getHeader(null));
166 		}
167 
168 		@Test void a15_getContent() {
169 			// Test getContent with null content map (covers the null check branch)
170 			var y = bean();
171 			assertNull(y.getContent("application/json"));
172 
173 			// Test with content set
174 			var x = bean()
175 				.setContent(map("application/json", mediaType().setSchema(schemaInfo().setType("object"))));
176 
177 			assertNotNull(x.getContent("application/json"));
178 			assertEquals("object", x.getContent("application/json").getSchema().getType());
179 			assertNull(x.getContent("application/xml"));
180 
181 			// Test null mediaType parameter
182 			assertThrows(IllegalArgumentException.class, () -> x.getContent(null));
183 		}
184 
185 		@Test void a16_getLink() {
186 			// Test getLink with null links map (covers the null check branch)
187 			var y = bean();
188 			assertNull(y.getLink("nonexistent"));
189 
190 			// Test with links set
191 			var x = bean()
192 				.setLinks(map("link1", link().setOperationId("getUser")));
193 
194 			assertNotNull(x.getLink("link1"));
195 			assertEquals("getUser", x.getLink("link1").getOperationId());
196 			assertNull(x.getLink("nonexistent"));
197 
198 			// Test null name parameter
199 			assertThrows(IllegalArgumentException.class, () -> x.getLink(null));
200 		}
201 	}
202 
203 	@Nested class B_emptyTests extends TestBase {
204 
205 		private static final BeanTester<Response> TESTER =
206 			testBean(bean())
207 			.props("description,headers,content,links")
208 			.vals("<null>,<null>,<null>,<null>")
209 			.json("{}")
210 			.string("{}")
211 		;
212 
213 		@Test void b01_gettersAndSetters() {
214 			TESTER.assertGettersAndSetters();
215 		}
216 
217 		@Test void b02_copy() {
218 			TESTER.assertCopy();
219 		}
220 
221 		@Test void b03_toJson() {
222 			TESTER.assertToJson();
223 		}
224 
225 		@Test void b04_fromJson() {
226 			TESTER.assertFromJson();
227 		}
228 
229 		@Test void b05_roundTrip() {
230 			TESTER.assertRoundTrip();
231 		}
232 
233 		@Test void b06_toString() {
234 			TESTER.assertToString();
235 		}
236 
237 		@Test void b07_keySet() {
238 			assertEmpty(TESTER.bean().keySet());
239 		}
240 	}
241 
242 	@Nested class C_extraProperties extends TestBase {
243 		private static final BeanTester<Response> TESTER =
244 			testBean(
245 				bean()
246 					.set("content", map("a1", mediaType().setSchema(schemaInfo("a2"))))
247 					.set("description", "b")
248 					.set("headers", map("c1", headerInfo(schemaInfo("c2"))))
249 					.set("links", map("d1", link().setOperationId("d2")))
250 					.set("x1", "x1a")
251 					.set("x2", null)
252 			)
253 			.props("content{a1{schema{type}}},description,headers{c1{schema{type}}},links{d1{operationId}},x1,x2")
254 			.vals("{{{a2}}},b,{{{c2}}},{{d2}},x1a,<null>")
255 			.json("{content:{a1:{schema:{type:'a2'}}},description:'b',headers:{c1:{schema:{type:'c2'}}},links:{d1:{operationId:'d2'}},x1:'x1a'}")
256 			.string("{'content':{'a1':{'schema':{'type':'a2'}}},'description':'b','headers':{'c1':{'schema':{'type':'c2'}}},'links':{'d1':{'operationId':'d2'}},'x1':'x1a'}".replace('\'', '"'))
257 		;
258 
259 		@Test void c01_gettersAndSetters() {
260 			TESTER.assertGettersAndSetters();
261 		}
262 
263 		@Test void c02_copy() {
264 			TESTER.assertCopy();
265 		}
266 
267 		@Test void c03_toJson() {
268 			TESTER.assertToJson();
269 		}
270 
271 		@Test void c04_fromJson() {
272 			TESTER.assertFromJson();
273 		}
274 
275 		@Test void c05_roundTrip() {
276 			TESTER.assertRoundTrip();
277 		}
278 
279 		@Test void c06_toString() {
280 			TESTER.assertToString();
281 		}
282 
283 		@Test void c07_keySet() {
284 			assertList(TESTER.bean().keySet(), "content", "description", "headers", "links", "x1", "x2");
285 		}
286 
287 		@Test void c08_get() {
288 			assertMapped(
289 				TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
290 				"content{a1{schema{type}}},description,headers{c1{schema{type}}},links{d1{operationId}},x1,x2",
291 				"{{{a2}}},b,{{{c2}}},{{d2}},x1a,<null>"
292 			);
293 		}
294 
295 		@Test void c09_getTypes() {
296 			assertMapped(
297 				TESTER.bean(), (obj,prop) -> simpleClassNameOf(obj.get(prop, Object.class)),
298 				"content,description,headers,links,x1,x2",
299 				"LinkedHashMap,String,LinkedHashMap,LinkedHashMap,String,<null>"
300 			);
301 		}
302 
303 		@Test void c10_nullPropertyValue() {
304 			assertThrows(IllegalArgumentException.class, ()->bean().get(null));
305 			assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
306 			assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
307 		}
308 	}
309 
310 	//---------------------------------------------------------------------------------------------
311 	// Helper methods
312 	//---------------------------------------------------------------------------------------------
313 
314 	private static Response bean() {
315 		return response();
316 	}
317 }