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.rest.annotation;
18  
19  import static org.junit.jupiter.api.Assertions.*;
20  
21  import java.util.*;
22  
23  import org.apache.juneau.*;
24  import org.apache.juneau.annotation.*;
25  import org.apache.juneau.collections.*;
26  import org.apache.juneau.http.annotation.*;
27  import org.apache.juneau.json.*;
28  import org.apache.juneau.rest.mock.*;
29  import org.apache.juneau.testutils.pojos.*;
30  import org.junit.jupiter.api.*;
31  
32  class Header_Test extends TestBase {
33  
34  	//------------------------------------------------------------------------------------------------------------------
35  	// Optional header parameter.
36  	//------------------------------------------------------------------------------------------------------------------
37  
38  	@Rest(serializers=Json5Serializer.class)
39  	public static class A {
40  		@RestGet
41  		public Object a(@Header("f1") Optional<Integer> f1) {
42  			assertNotNull(f1);
43  			return f1;
44  		}
45  		@RestGet
46  		public Object b(@Header("f1") Optional<ABean> f1) {
47  			assertNotNull(f1);
48  			return f1;
49  		}
50  		@RestGet
51  		public Object c(@Header("f1") Optional<List<ABean>> f1) {
52  			assertNotNull(f1);
53  			return f1;
54  		}
55  		@RestGet
56  		public Object d(@Header("f1") List<Optional<ABean>> f1) {
57  			return f1;
58  		}
59  	}
60  
61  	@Test void a01_optionalParams() throws Exception {
62  		var a = MockRestClient.buildJson(A.class);
63  
64  		a.get("/a").header("f1", 123)
65  			.run()
66  			.assertStatus(200)
67  			.assertContent("123");
68  		a.get("/a")
69  			.run()
70  			.assertStatus(200)
71  			.assertContent("null");
72  
73  		a.get("/b")
74  			.header("f1", "a=1,b=foo")
75  			.run()
76  			.assertStatus(200)
77  			.assertContent("{a:1,b:'foo'}");
78  		a.get("/b")
79  			.run()
80  			.assertStatus(200)
81  			.assertContent("null");
82  
83  		a.get("/c")
84  			.header("f1", "@((a=1,b=foo))")
85  			.run()
86  			.assertStatus(200)
87  			.assertContent("[{a:1,b:'foo'}]");
88  		a.get("/c")
89  			.run()
90  			.assertStatus(200)
91  			.assertContent("null");
92  
93  		a.get("/d")
94  			.header("f1", "@((a=1,b=foo))")
95  			.run()
96  			.assertStatus(200)
97  			.assertContent("[{a:1,b:'foo'}]");
98  		a.get("/d")
99  			.run()
100 			.assertStatus(200)
101 			.assertContent("null");
102 	}
103 
104 	//------------------------------------------------------------------------------------------------------------------
105 	// Default values - Annotated headers.
106 	//------------------------------------------------------------------------------------------------------------------
107 
108 	@Rest
109 	public static class B {
110 		@RestGet
111 		public JsonMap a(@Header(name="H1") String h1, @Header("H2") String h2, @Header("H3") String h3) {
112 			return JsonMap.create()
113 				.append("h1", h1)
114 				.append("h2", h2)
115 				.append("h3", h3);
116 		}
117 	}
118 
119 	@Test void b01_annotatedHeaders() throws Exception {
120 		var b = MockRestClient.build(B.class);
121 		b.get("/a").run().assertContent("{h1:null,h2:null,h3:null}");
122 		b.get("/a").header("H1",4).header("H2",5).header("H3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
123 		b.get("/a").header("h1",4).header("h2",5).header("h3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
124 	}
125 
126 	//------------------------------------------------------------------------------------------------------------------
127 	// Default values - Annotated headers, case-insensitive matching.
128 	//------------------------------------------------------------------------------------------------------------------
129 
130 	@Rest
131 	public static class C {
132 		@RestGet
133 		public JsonMap a(@Header("h1") String h1, @Header("h2") String h2, @Header("h3") String h3) {
134 			return JsonMap.create()
135 				.append("h1", h1)
136 				.append("h2", h2)
137 				.append("h3", h3);
138 		}
139 	}
140 
141 	@Test void c01_annotatedHeadersCaseInsensitive() throws Exception {
142 		var c = MockRestClient.build(C.class);
143 		c.get("/a").run().assertContent("{h1:null,h2:null,h3:null}");
144 		c.get("/a").header("H1",4).header("H2",5).header("H3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
145 		c.get("/a").header("h1",4).header("h2",5).header("h3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
146 	}
147 
148 	//------------------------------------------------------------------------------------------------------------------
149 	// Default values - Annotated headers with default values.
150 	//------------------------------------------------------------------------------------------------------------------
151 
152 	@Rest
153 	public static class D1 {
154 		@RestGet
155 		public JsonMap a(@Header(name="h1") @Schema(_default="1") String h1, @Header(name="h2") @Schema(_default="2") String h2, @Header(name="h3") @Schema(_default="3") String h3) {
156 			return JsonMap.create()
157 				.append("h1", h1)
158 				.append("h2", h2)
159 				.append("h3", h3);
160 		}
161 	}
162 
163 	@Test void d01_annotatedHeadersDefault() throws Exception {
164 		var d1 = MockRestClient.build(D1.class);
165 		d1.get("/a").run().assertContent("{h1:'1',h2:'2',h3:'3'}");
166 		d1.get("/a").header("H1",4).header("H2",5).header("H3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
167 		d1.get("/a").header("h1",4).header("h2",5).header("h3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
168 	}
169 
170 	@Rest
171 	public static class D2 {
172 		@RestGet
173 		public JsonMap a(@Header("h1") @Schema(_default="1") String h1, @Header("h2") @Schema(_default="2") String h2, @Header("h3") @Schema(_default="3") String h3) {
174 			return JsonMap.create()
175 				.append("h1", h1)
176 				.append("h2", h2)
177 				.append("h3", h3);
178 		}
179 	}
180 
181 	@Test void d02_annotatedHeadersDefault() throws Exception {
182 		var d2 = MockRestClient.build(D2.class);
183 		d2.get("/a").run().assertContent("{h1:'1',h2:'2',h3:'3'}");
184 		d2.get("/a").header("H1",4).header("H2",5).header("H3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
185 		d2.get("/a").header("h1",4).header("h2",5).header("h3",6).run().assertContent("{h1:'4',h2:'5',h3:'6'}");
186 	}
187 
188 	//------------------------------------------------------------------------------------------------------------------
189 	// Default values - Annotated headers with default values and default request headers.
190 	//------------------------------------------------------------------------------------------------------------------
191 
192 	@Rest
193 	public static class E {
194 		@RestGet(defaultRequestHeaders={"H1:1","H2=2"," H3 : 3 "})
195 		public JsonMap a(@Header("h1") @Schema(_default="4") String h1, @Header("h2") @Schema(_default="5") String h2, @Header("h3") @Schema(_default="6") String h3) {
196 			return JsonMap.create()
197 				.append("h1", h1)
198 				.append("h2", h2)
199 				.append("h3", h3);
200 		}
201 	}
202 
203 	@Test void e01_annotatedAndDefaultHeaders() throws Exception {
204 		var e = MockRestClient.build(E.class);
205 		e.get("/a").run().assertContent("{h1:'4',h2:'5',h3:'6'}");
206 		e.get("/a").header("H1",7).header("H2",8).header("H3",9).run().assertContent("{h1:'7',h2:'8',h3:'9'}");
207 		e.get("/a").header("h1",7).header("h2",8).header("h3",9).run().assertContent("{h1:'7',h2:'8',h3:'9'}");
208 	}
209 
210 	//------------------------------------------------------------------------------------------------------------------
211 	// Default parameters
212 	//------------------------------------------------------------------------------------------------------------------
213 
214 	@Rest(serializers=Json5Serializer.class)
215 	public static class F {
216 		@RestGet
217 		public Object a1(@Header(name="f1", def="1") Integer f1) {
218 			assertNotNull(f1);
219 			return f1;
220 		}
221 		@RestGet
222 		public Object a2(@Header(name="f1", def="1") Optional<Integer> f1) {
223 			assertNotNull(f1);
224 			return f1.get();
225 		}
226 		@RestGet
227 		public Object b1(@Header(name="f1", def="a=1,b=foo") ABean f1) {
228 			assertNotNull(f1);
229 			return f1;
230 		}
231 		@RestGet
232 		public Object b2(@Header(name="f1", def="a=1,b=foo") Optional<ABean> f1) {
233 			assertNotNull(f1);
234 			return f1.get();
235 		}
236 		@RestGet
237 		public Object c1(@Header(name="f1", def="@((a=1,b=foo))") List<ABean> f1) {
238 			assertNotNull(f1);
239 			return f1;
240 		}
241 		@RestGet
242 		public Object c2(@Header(name="f1", def="@((a=1,b=foo))") Optional<List<ABean>> f1) {
243 			assertNotNull(f1);
244 			return f1.get();
245 		}
246 		@RestGet
247 		public Object d(@Header(name="f1", def="@((a=1,b=foo))") List<Optional<ABean>> f1) {
248 			return f1;
249 		}
250 	}
251 
252 	@Test void f01_defaultHeaders() throws Exception {
253 		var f = MockRestClient.buildJson(F.class);
254 		f.get("/a1")
255 			.header("f1","123")
256 			.run()
257 			.assertStatus(200)
258 			.assertContent("123");
259 		f.get("/a1")
260 			.run()
261 			.assertStatus(200)
262 			.assertContent("1");
263 		f.get("/a2")
264 			.header("f1","123")
265 			.run()
266 			.assertStatus(200)
267 			.assertContent("123");
268 		f.get("/a2")
269 			.run()
270 			.assertStatus(200)
271 			.assertContent("1");
272 		f.get("/b1")
273 			.header("f1","a=2,b=bar")
274 			.run()
275 			.assertStatus(200)
276 			.assertContent("{a:2,b:'bar'}");
277 		f.get("/b1")
278 			.run()
279 			.assertStatus(200)
280 			.assertContent("{a:1,b:'foo'}");
281 		f.get("/b2")
282 			.header("f1","a=2,b=bar")
283 			.run()
284 			.assertStatus(200)
285 			.assertContent("{a:2,b:'bar'}");
286 		f.get("/b2")
287 			.run()
288 			.assertStatus(200)
289 			.assertContent("{a:1,b:'foo'}");
290 		f.get("/c1")
291 			.header("f1","@((a=2,b=bar))")
292 			.run()
293 			.assertStatus(200)
294 			.assertContent("[{a:2,b:'bar'}]");
295 		f.get("/c1")
296 			.run()
297 			.assertStatus(200)
298 			.assertContent("[{a:1,b:'foo'}]");
299 		f.get("/c2")
300 			.header("f1","@((a=2,b=bar))")
301 			.run()
302 			.assertStatus(200)
303 			.assertContent("[{a:2,b:'bar'}]");
304 		f.get("/c2")
305 			.run()
306 			.assertStatus(200)
307 			.assertContent("[{a:1,b:'foo'}]");
308 		f.get("/d")
309 			.header("f1","@((a=2,b=bar))")
310 			.run()
311 			.assertStatus(200)
312 			.assertContent("[{a:2,b:'bar'}]");
313 		f.get("/d")
314 			.run()
315 			.assertStatus(200)
316 			.assertContent("[{a:1,b:'foo'}]");
317 	}
318 }