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  
28  import org.apache.http.*;
29  import org.apache.http.Header;
30  import org.apache.http.entity.*;
31  import org.apache.http.message.*;
32  import org.apache.http.params.*;
33  import org.apache.juneau.*;
34  import org.apache.juneau.http.annotation.*;
35  import org.apache.juneau.parser.*;
36  import org.apache.juneau.rest.annotation.*;
37  import org.apache.juneau.rest.mock.*;
38  import org.apache.juneau.rest.servlet.*;
39  import org.junit.jupiter.api.*;
40  
41  class RestClient_Response_Test extends TestBase {
42  
43  	public static class ABean {
44  		public int f;
45  		static ABean get() {
46  			var x = new ABean();
47  			x.f = 1;
48  			return x;
49  		}
50  	}
51  
52  	private static ABean bean = ABean.get();
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  	@Rest
57  	public static class A extends BasicRestObject {
58  		@RestGet
59  		public ABean bean() {
60  			return bean;
61  		}
62  	}
63  
64  	public static class A1 extends MockRestClient {
65  		public A1(MockRestClient.Builder b) {
66  			super(b);
67  		}
68  		@Override
69  		protected MockRestResponse createResponse(RestRequest request, HttpResponse httpResponse, Parser parser) throws RestCallException {
70  			return new MockRestResponse(this, request, null, parser);
71  		}
72  	}
73  
74  	@Test void a01_getStatusLine() throws RestCallException {
75  		assertEquals(200,client().build().get("/bean").run().getStatusLine().getStatusCode());
76  		assertThrowsWithMessage(Exception.class, "caused response code '0, null'", ()->client().build(A1.class).get("/bean").run());
77  		assertEquals(0,client().ignoreErrors().build(A1.class).get("/bean").run().getStatusLine().getStatusCode());
78  	}
79  
80  	@Test void a03_getStatusCode() throws RestCallException {
81  		assertEquals(200,client().build().get("/bean").run().getStatusCode());
82  	}
83  
84  	@Test void a05_getReasonPhrase() throws RestCallException {
85  		assertNull(client().build().get("/bean").run().getReasonPhrase());
86  	}
87  
88  	@Test void a07_setStatusLine() throws RestCallException {
89  		var sl = new BasicStatusLine(new ProtocolVersion("http",9,8),299,"foo");
90  		var r = client().build().get("/bean").run();
91  		r.setStatusLine(sl);
92  		r
93  			.assertStatus(299)
94  			.assertStatus().asCode().is(299)
95  			.assertStatus().asProtocol().is("http")
96  			.assertStatus().asMajor().is(9)
97  			.assertStatus().asMinor().is(8)
98  			.assertStatus().asReason().is("foo");
99  
100 		r.setStatusCode(298);
101 		r.assertStatus(298);
102 		r.setReasonPhrase("bar");
103 		r.setStatusLine(new ProtocolVersion("http",9,8),297);
104 		r.assertStatus(297);
105 		r.setStatusLine(new ProtocolVersion("http",9,8),296,"foo");
106 		r.assertStatus(296);
107 
108 		assertEquals(9, r.getProtocolVersion().getMajor());
109 	}
110 
111 	@Test void a08_setLocale() throws RestCallException {
112 		var r = client().build().get("/bean").run();
113 		r.setLocale(Locale.JAPAN);
114 		assertEquals(Locale.JAPAN, r.getLocale());
115 	}
116 
117 	//------------------------------------------------------------------------------------------------------------------
118 	// Response header methods.
119 	//------------------------------------------------------------------------------------------------------------------
120 
121 	@Rest
122 	public static class C extends BasicRestObject {
123 		@RestGet(path="/")
124 		public String getHeader(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) {
125 			var n = req.getHeaderParam("Check").orElse(null);
126 			var v = req.getHeaderParam(n).orElse(null);
127 			res.setHeader(n,v);
128 			return v;
129 		}
130 	}
131 
132 	@Test void c01_response_getStringHeader() throws Exception {
133 		var x = checkFooClient(C.class).build().get().json().header("Foo","bar").run();
134 		assertEquals("bar", x.getStringHeader("Foo").orElse(null));
135 		assertEquals("bar", x.getStringHeader("Foo").orElse("baz"));
136 		assertEquals("baz", x.getStringHeader("Bar").orElse("baz"));
137 	}
138 
139 	@Test void c02_response_getCharacterEncoding() throws Exception {
140 		assertEquals("iso-8859-1", checkClient(C.class,"Content-Type").build().get().json().header("Content-Type","application/json;charset=iso-8859-1").run().getCharacterEncoding());
141 		assertEquals("utf-8", checkClient(C.class,"Content-Type").build().get().json().header("Content-Type","application/json").run().getCharacterEncoding());
142 	}
143 
144 	@Test void c03_response_headerAssertions() throws Exception {
145 		checkFooClient(C.class).build().get().json().header("Foo","123").run().assertHeader("Foo").asInteger().is(123);
146 		checkFooClient(C.class).build().get().json().header("Foo","123").run().assertHeader("Foo").asLong().is(123L);
147 		checkFooClient(C.class).build().get().json().header(dateHeader("Foo",ZONEDDATETIME)).run().assertHeader("Foo").asZonedDateTime().is(ZONEDDATETIME);
148 		checkClient(C.class,"Content-Type").build().get().json().header("Content-Type","application/json;charset=iso-8859-1").run().assertCharset().is("iso-8859-1");
149 		checkClient(C.class,"Content-Type").build().get().json().header("Content-Type","application/json;charset=iso-8859-1").run().assertHeader("Content-Type").is("application/json;charset=iso-8859-1");
150 	}
151 
152 	@Test void c04_response_containsHeader() throws Exception {
153 		var r = checkFooClient(C.class).build().get().json().header("Foo","bar").run();
154 		assertTrue(r.containsHeader("Foo"));
155 		assertFalse(r.containsHeader("Bar"));
156 	}
157 
158 	@Test void c05_response_getHeaders() throws Exception {
159 		var r = checkFooClient(C.class).build().get().json().run();
160 		r.setHeader("Foo","bar");
161 		r.addHeader("Foo","baz");
162 		r.addHeader(stringHeader("Foo","qux"));
163 		assertEquals(3, r.getHeaders("Foo").length);
164 		assertEquals(0, r.getHeaders("Bar").length);
165 		r.getFirstHeader("Foo").assertValue().is("bar");
166 		assertFalse(r.getFirstHeader("Bar").isPresent());
167 		r.getHeader("Foo").assertValue().is("bar, baz, qux");
168 		assertFalse(r.getHeader("Bar").isPresent());
169 
170 		r.setHeaders(new Header[]{basicHeader("Foo", "quux")});
171 		r.getFirstHeader("Foo").assertValue().is("quux");
172 		r.getLastHeader("Foo").assertValue().is("quux");
173 
174 		r.removeHeader(basicHeader("Foo","bar"));
175 		r.getFirstHeader("Foo").assertValue().is("quux");
176 		r.getLastHeader("Foo").assertValue().is("quux");
177 
178 		var i = r.headerIterator();
179 		assertEquals("quux", i.nextHeader().getValue());
180 
181 		i = r.headerIterator("Foo");
182 		assertEquals("quux", i.nextHeader().getValue());
183 
184 		r.removeHeader(basicHeader("Foo","quux"));
185 		assertFalse(r.getFirstHeader("Foo").isPresent());
186 
187 		r.setHeader(basicHeader("Foo","quuux"));
188 		r.getHeader("Foo").assertValue().is("quuux");
189 	}
190 
191 	//------------------------------------------------------------------------------------------------------------------
192 	// Response body methods.
193 	//------------------------------------------------------------------------------------------------------------------
194 
195 	@Rest
196 	public static class D extends BasicRestObject {
197 		@RestPost
198 		public ABean bean(@Content ABean bean) {
199 			return bean;
200 		}
201 	}
202 
203 	@Test void d01_response_assertBody() throws Exception {
204 		client(D.class).build().post("/bean",bean).run().assertContent().as(ABean.class).asJson().is("{f:1}");
205 	}
206 
207 	@Test void d02_response_setEntity() throws Exception {
208 		var x = client(D.class).build().post("/bean",bean).run();
209 		x.setEntity(new StringEntity("{f:2}"));
210 		x.assertContent().as(ABean.class).asJson().is("{f:2}");
211 	}
212 
213 	//------------------------------------------------------------------------------------------------------------------
214 	// Other.
215 	//------------------------------------------------------------------------------------------------------------------
216 
217 	@SuppressWarnings("deprecation")
218 	@Test void e01_response_getParams_setParams() throws Exception {
219 		var x = client(D.class).build().post("/bean",bean).run();
220 		var p = new BasicHttpParams();
221 		x.setParams(p);
222 		assertSame(x.getParams(), p);
223 	}
224 
225 	//------------------------------------------------------------------------------------------------------------------
226 	// Helper methods.
227 	//------------------------------------------------------------------------------------------------------------------
228 
229 	private static RestClient.Builder client() {
230 		return MockRestClient.create(A.class).json5();
231 	}
232 
233 	private static RestClient.Builder client(Class<?> c) {
234 		return MockRestClient.create(c).json5();
235 	}
236 
237 	private static RestClient.Builder checkFooClient(Class<?> c) {
238 		return MockRestClient.create(c).json5().header("Check","Foo");
239 	}
240 
241 	private static RestClient.Builder checkClient(Class<?> c, String headerToCheck) {
242 		return MockRestClient.create(c).json5().header("Check",headerToCheck);
243 	}
244 }