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.client;
18  
19  import static java.time.format.DateTimeFormatter.*;
20  import static java.time.temporal.ChronoUnit.*;
21  import static org.apache.juneau.TestUtils.*;
22  import static org.apache.juneau.http.HttpHeaders.*;
23  import static org.junit.jupiter.api.Assertions.*;
24  
25  import java.time.*;
26  import java.util.*;
27  import java.util.regex.*;
28  
29  import org.apache.juneau.*;
30  import org.apache.juneau.http.header.*;
31  import org.apache.juneau.rest.annotation.*;
32  import org.apache.juneau.rest.httppart.*;
33  import org.apache.juneau.rest.mock.*;
34  import org.apache.juneau.rest.servlet.*;
35  import org.junit.jupiter.api.*;
36  
37  class RestClient_Response_Headers_Test extends TestBase {
38  
39  	@Rest
40  	public static class A extends BasicRestObject {
41  		@RestGet
42  		public String echo(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) {
43  			var c = req.getHeaderParam("Check").orElse(null);
44  			var h = req.getHeaders().getAll(c).stream().map(RequestHeader::getValue).toArray(String[]::new);
45  			if (h != null)
46  				for (var hh : h)
47  					res.addHeader(c, hh);
48  			return "ok";
49  		}
50  	}
51  
52  	private static final ZonedDateTime ZONEDDATETIME = ZonedDateTime.from(RFC_1123_DATE_TIME.parse("Sat, 29 Oct 1994 19:43:31 GMT")).truncatedTo(SECONDS);
53  
54  	@Test void a01_exists() throws Exception {
55  		assertFalse(checkFooClient().build().get("/echo").run().getHeader("Foo").isPresent());
56  		assertTrue(checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").isPresent());
57  	}
58  
59  	public static class A2 extends BasicHeader {
60  		private static final long serialVersionUID = 1L;
61  
62  		private A2(String name, Object value) {  // NOSONAR
63  			super(name, value);  // Never called.
64  		}
65  	}
66  
67  	@Test void a02_asHeader() throws Exception {
68  		var h = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asHeader(BasicStringHeader.class).assertName().is("Foo").assertStringValue().is("bar");
69  		assertTrue(h instanceof BasicStringHeader);
70  
71  		h = checkFooClient().build().get("/echo").header("Foo","\"bar\"").run().getHeader("Foo").asHeader(ETag.class).assertName().is("ETag").assertStringValue().is("\"bar\"");
72  		assertTrue(h instanceof ETag);
73  
74  		assertThrowsWithMessage(Exception.class, "Value 'bar' could not be parsed as an integer.", ()->checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asHeader(Age.class));
75  		assertThrowsWithMessage(Exception.class, "Could not determine a method to construct type", ()->checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asHeader(A2.class));
76  
77  		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asCsvHeader().assertName().is("Foo").assertStringValue().is("bar");
78  		checkFooClient().build().get("/echo").header("Foo","*").run().getHeader("Foo").asEntityTagsHeader().assertName().is("Foo").assertStringValue().is("*");
79  		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asStringRangesHeader().assertName().is("Foo").assertStringValue().is("bar");
80  		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asStringHeader().assertName().is("Foo").assertStringValue().is("bar");
81  		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asUriHeader().assertName().is("Foo").assertStringValue().is("bar");
82  	}
83  
84  	@Test void a03_asString() throws Exception {
85  		var s = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asString().orElse(null);
86  		assertEquals("bar", s);
87  
88  		var m = Value.<String>empty();
89  		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asString(m);
90  		assertEquals("bar", m.get());
91  
92  		var o = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asString();
93  		assertEquals("bar", o.get());
94  		o = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Bar").asString();
95  		assertFalse(o.isPresent());
96  
97  		s = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").asString().orElse("baz");
98  		assertEquals("bar", s);
99  		s = checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Bar").asString().orElse("baz");
100 		assertEquals("baz", s);
101 	}
102 
103 	@SuppressWarnings("unchecked")
104 	@Test void a04_asType() throws Exception {
105 		var i = checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Foo").as(Integer.class).orElse(null);
106 		assertEquals(123, i.intValue());
107 
108 		var m1 = Value.<Integer>empty();
109 		checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Foo").as(m1,Integer.class);
110 		assertEquals(123, m1.get().intValue());
111 
112 		var l = (List<Integer>) checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Foo").as(LinkedList.class,Integer.class).get();
113 		assertList(l, "1", "2");
114 
115 		var m2 = Value.empty();
116 		checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Foo").as(m2,LinkedList.class,Integer.class);
117 
118 		ClassMeta<LinkedList<Integer>> cm1 = BeanContext.DEFAULT.getClassMeta(LinkedList.class, Integer.class);
119 		var cm2 = BeanContext.DEFAULT.getClassMeta(Integer.class);
120 
121 		l = checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Foo").as(cm1).get();
122 		assertList(l, "1", "2");
123 
124 		Value<LinkedList<Integer>> m3 = Value.empty();
125 		checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Foo").as(m3,cm1);
126 		assertList(m3.get(), "1", "2");
127 
128 		assertThrowsWithMessage(Exception.class, "For input string:", ()->checkFooClient().build().get("/echo").header("Foo","foo").run().getHeader("Foo").as(m2,cm1));
129 
130 		Optional<List<Integer>> o1 = checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Foo").as(LinkedList.class,Integer.class);
131 		assertList(o1.get(), "1", "2");
132 		o1 = checkFooClient().build().get("/echo").header("Foo","1,2").run().getHeader("Bar").as(LinkedList.class,Integer.class);
133 		assertFalse(o1.isPresent());
134 
135 		var o2 = checkFooClient().build().get("/echo").header("Foo","1").run().getHeader("Foo").as(Integer.class);
136 		assertEquals(1, o2.get().intValue());
137 		o2 = checkFooClient().build().get("/echo").header("Foo","1").run().getHeader("Bar").as(Integer.class);
138 		assertFalse(o2.isPresent());
139 
140 		o2 = checkFooClient().build().get("/echo").header("Foo","1").run().getHeader("Foo").as(cm2);
141 		assertEquals(1, o2.get().intValue());
142 		o2 = checkFooClient().build().get("/echo").header("Foo","1").run().getHeader("Bar").as(cm2);
143 		assertFalse(o2.isPresent());
144 
145 		assertTrue(checkFooClient().build().get("/echo").header("Foo","foo").run().getHeader("Foo").asMatcher("foo").matches());
146 		assertFalse(checkFooClient().build().get("/echo").header("Foo","foo").run().getHeader("Bar").asMatcher("foo").matches());
147 		assertTrue(checkFooClient().build().get("/echo").header("Foo","foo").run().getHeader("Foo").asMatcher("FOO",Pattern.CASE_INSENSITIVE).matches());
148 		assertFalse(checkFooClient().build().get("/echo").header("Foo","foo").run().getHeader("Bar").asMatcher("FOO",Pattern.CASE_INSENSITIVE).matches());
149 	}
150 
151 	@Test void a05_toResponse() throws Exception {
152 		var r = checkFooClient().build().get("/echo").header("Foo","123").run();
153 		assertSame(r, r.getHeader("Foo").response());
154 	}
155 
156 	//------------------------------------------------------------------------------------------------------------------
157 	// Assertions.
158 	//------------------------------------------------------------------------------------------------------------------
159 
160 	@Test void b01_assertions() throws Exception {
161 		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Foo").assertValue().is("bar");
162 		checkFooClient().build().get("/echo").header("Foo","bar").run().getHeader("Bar").assertValue().isNull();
163 		checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Foo").assertValue().asInteger().is(123);
164 		checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Bar").assertValue().isNull();
165 		checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Foo").assertValue().asLong().is(123L);
166 		checkFooClient().build().get("/echo").header("Foo","123").run().getHeader("Bar").assertValue().asLong().isNull();
167 		checkFooClient().build().get("/echo").header(dateHeader("Foo",ZONEDDATETIME)).run().getHeader("Foo").assertValue().asZonedDateTime().isExists();
168 		checkFooClient().build().get("/echo").header(dateHeader("Foo",ZONEDDATETIME)).run().getHeader("Bar").assertValue().asZonedDateTime().isNull();
169 	}
170 
171 	//------------------------------------------------------------------------------------------------------------------
172 	// Header methods.
173 	//------------------------------------------------------------------------------------------------------------------
174 
175 	@Test void c01_getElements() throws Exception {
176 		var e = checkFooClient().build().get("/echo").header("Foo","bar=baz;qux=quux").run().getHeader("Foo").getElements();
177 		assertEquals("bar", e[0].getName());
178 		assertEquals("baz", e[0].getValue());
179 		assertEquals("quux", e[0].getParameterByName("qux").getValue());
180 
181 		e = checkFooClient().build().get("/echo").header("Foo","bar=baz;qux=quux").run().getHeader("Bar").getElements();
182 		assertEquals(0, e.length);
183 	}
184 
185 	//------------------------------------------------------------------------------------------------------------------
186 	// Helper methods.
187 	//------------------------------------------------------------------------------------------------------------------
188 
189 	private static RestClient.Builder checkFooClient() {
190 		return MockRestClient.create(A.class).json5().header("Check","Foo");
191 	}
192 }