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