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