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 org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.http.HttpEntities.*;
21  import static org.apache.juneau.http.HttpHeaders.*;
22  import static org.apache.juneau.http.HttpResources.*;
23  
24  import java.io.*;
25  
26  import org.apache.http.*;
27  import org.apache.juneau.*;
28  import org.apache.juneau.json.*;
29  import org.apache.juneau.rest.annotation.*;
30  import org.apache.juneau.rest.mock.*;
31  import org.apache.juneau.rest.servlet.*;
32  import org.apache.juneau.testutils.pojos.*;
33  import org.junit.jupiter.api.*;
34  
35  class RestClient_Body_Test extends TestBase {
36  
37  	@Rest
38  	public static class A extends BasicRestObject {
39  		@RestPost
40  		public Reader post(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) throws IOException {
41  			for (var e : req.getHeaders())
42  				res.addHeader("X-" + e.getName(), e.getValue());
43  			return req.getReader();
44  		}
45  	}
46  
47  	//------------------------------------------------------------------------------------------------------------------
48  	// Method tests
49  	//------------------------------------------------------------------------------------------------------------------
50  
51  	@Test void a01_BasicHttpResource() throws Exception {
52  		var x1 = stringResource("foo");
53  		client().build().post("/", x1).run()
54  			.assertHeader("X-Content-Length").asInteger().is(3)
55  			.assertHeader("X-Content-Encoding").isNull()
56  			.assertHeader("X-Content-Type").isNull()
57  			.assertHeader("X-Transfer-Encoding").isNull()
58  		;
59  
60  		var x2 = stringResource("foo").setContentType("text/plain").setContentEncoding("identity");
61  		client().build().post("/",x2).run()
62  			.assertHeader("X-Content-Length").asInteger().is(3)
63  			.assertHeader("X-Content-Encoding").is("identity")
64  			.assertHeader("X-Content-Type").is("text/plain")
65  			.assertHeader("X-Transfer-Encoding").isNull()
66  		;
67  
68  		var x3 = stringResource("foo").setContentType(contentType("text/plain")).setContentEncoding(contentEncoding("identity")).setChunked();
69  		client().build().post("/",x3).run()
70  			.assertHeader("X-Content-Length").isNull()  // Missing when chunked.
71  			.assertHeader("X-Content-Encoding").is("identity")
72  			.assertHeader("X-Content-Type").is("text/plain")
73  			.assertHeader("X-Transfer-Encoding").is("chunked")
74  		;
75  
76  		var x4 = stringResource("foo", contentType("text/plain")).setContentEncoding("identity");
77  		client().build().post("/",x4).run()
78  			.assertHeader("X-Content-Length").asInteger().is(3)
79  			.assertHeader("X-Content-Encoding").is("identity")
80  			.assertHeader("X-Content-Type").is("text/plain")
81  			.assertHeader("X-Transfer-Encoding").isNull()
82  		;
83  
84  		var x5 = stringResource("foo").setHeader("Foo","bar").setHeaders(header("Baz","qux"));
85  		client().build().post("/",x5).run()
86  			.assertHeader("X-Foo").is("bar")
87  			.assertHeader("X-Baz").is("qux")
88  		;
89  
90  		var x6 = stringResource("foo").addHeaders(header("Foo","bar"),header("Baz","qux"));
91  		client().build().post("/",x6).run()
92  			.assertHeader("X-Foo").is("bar")
93  			.assertHeader("X-Baz").is("qux")
94  		;
95  
96  		var x7 = readerResource(reader("foo"));
97  		client().build().post("/",x7).run().assertContent("foo");
98  
99  		var x8 = readerResource(reader("foo")).setCached();
100 		client().build().post("/",x8).run().assertContent("foo");
101 		client().build().post("/",x8).run().assertContent("foo");
102 	}
103 
104 	@Test void a02_StringEntity() throws Exception {
105 		var x1 = stringEntity("foo");
106 		client().build().post("/", x1).run()
107 			.assertHeader("X-Content-Length").asInteger().is(3)
108 			.assertHeader("X-Content-Encoding").isNull()
109 			.assertHeader("X-Content-Type").isNull()
110 			.assertHeader("X-Transfer-Encoding").isNull()
111 		;
112 
113 		var x2 = stringEntity("foo").setContentType("text/plain").setContentEncoding("identity");
114 		client().build().post("/",x2).run()
115 			.assertHeader("X-Content-Length").asInteger().is(3)
116 			.assertHeader("X-Content-Encoding").is("identity")
117 			.assertHeader("X-Content-Type").is("text/plain")
118 			.assertHeader("X-Transfer-Encoding").isNull()
119 		;
120 
121 		var x3 = stringEntity("foo").setContentType(contentType("text/plain")).setContentEncoding(contentEncoding("identity")).setChunked();
122 		client().build().post("/",x3).run()
123 			.assertHeader("X-Content-Length").isNull()  // Missing when chunked.
124 			.assertHeader("X-Content-Encoding").is("identity")
125 			.assertHeader("X-Content-Type").is("text/plain")
126 			.assertHeader("X-Transfer-Encoding").is("chunked")
127 		;
128 
129 		var x4 = stringEntity("foo", contentType("text/plain")).setContentEncoding("identity");
130 		client().build().post("/",x4).run()
131 			.assertHeader("X-Content-Length").asInteger().is(3)
132 			.assertHeader("X-Content-Encoding").is("identity")
133 			.assertHeader("X-Content-Type").is("text/plain")
134 			.assertHeader("X-Transfer-Encoding").isNull()
135 		;
136 
137 		var x7 = readerEntity(reader("foo"));
138 		client().build().post("/",x7).run().assertContent("foo");
139 
140 		var x8 = readerEntity(reader("foo")).setCached();
141 		client().build().post("/",x8).run().assertContent("foo");
142 		client().build().post("/",x8).run().assertContent("foo");
143 
144 		var x12 = stringEntity("foo");
145 		x12.assertString().is("foo");
146 		x12.assertBytes().asString().is("foo");
147 	}
148 
149 	@Test void a03_SerializedHttpEntity() throws Exception {
150 		var js = JsonSerializer.DEFAULT;
151 
152 		var x1 = serializedEntity(ABean.get(),null,null);
153 		client().build().post("/",x1).run()
154 			.assertHeader("X-Content-Length").isNull()
155 			.assertHeader("X-Content-Encoding").isNull()
156 			.assertHeader("X-Content-Type").is("application/json5")
157 			.assertHeader("X-Transfer-Encoding").is("chunked")  // Because content length is -1.
158 		;
159 
160 		var x2 = serializedEntity(ABean.get(),js,null);
161 		client().build().post("/",x2).run()
162 			.assertHeader("X-Content-Length").isNull()
163 			.assertHeader("X-Content-Encoding").isNull()
164 			.assertHeader("X-Content-Type").is("application/json")
165 			.assertContent().as(ABean.class).asJson().is("{a:1,b:'foo'}");
166 
167 		var x3 = serializedEntity(ABean::get,js,null);
168 		client().build().post("/",x3).run()
169 			.assertHeader("X-Content-Length").isNull()
170 			.assertHeader("X-Content-Encoding").isNull()
171 			.assertHeader("X-Content-Type").is("application/json")
172 			.assertContent().as(ABean.class).asJson().is("{a:1,b:'foo'}");
173 	}
174 
175 	//------------------------------------------------------------------------------------------------------------------
176 	// Helper methods.
177 	//------------------------------------------------------------------------------------------------------------------
178 
179 	private static RestClient.Builder client() {
180 		return MockRestClient.create(A.class).json5();
181 	}
182 
183 	private static Header header(String name, Object val) {
184 		return basicHeader(name, val);
185 	}
186 }