15
15
*/
16
16
package feign .http2client .test ;
17
17
18
+ import static feign .Util .UTF_8 ;
18
19
import static org .assertj .core .api .Assertions .assertThat ;
20
+ import static org .assertj .core .api .Assertions .entry ;
19
21
import static org .junit .jupiter .api .Assertions .assertThrows ;
20
22
21
- import feign .Body ;
22
- import feign .Feign ;
23
- import feign .FeignException ;
24
- import feign .Headers ;
25
- import feign .Request ;
26
- import feign .RequestLine ;
27
- import feign .Response ;
28
- import feign .Retryer ;
23
+ import feign .*;
24
+ import feign .assertj .MockWebServerAssertions ;
29
25
import feign .client .AbstractClientTest ;
30
26
import feign .http2client .Http2Client ;
27
+ import java .io .ByteArrayInputStream ;
31
28
import java .io .IOException ;
32
29
import java .net .http .HttpTimeoutException ;
30
+ import java .util .Arrays ;
31
+ import java .util .Collections ;
32
+ import java .util .List ;
33
33
import java .util .concurrent .TimeUnit ;
34
34
import okhttp3 .mockwebserver .MockResponse ;
35
- import org . junit . jupiter . api . Disabled ;
35
+ import okhttp3 . mockwebserver . RecordedRequest ;
36
36
import org .junit .jupiter .api .Test ;
37
37
38
38
/** Tests client-specific behavior, such as ensuring Content-Length is sent when specified. */
39
- @ Disabled
40
39
public class Http2ClientTest extends AbstractClientTest {
41
40
42
41
public interface TestInterface {
@@ -59,6 +58,24 @@ public interface TestInterface {
59
58
@ RequestLine ("DELETE /anything" )
60
59
@ Body ("some request body" )
61
60
String deleteWithBody ();
61
+
62
+ @ RequestLine ("POST /?foo=bar&foo=baz&qux=" )
63
+ @ Headers ({"Foo: Bar" , "Foo: Baz" , "Qux: " , "Content-Type: text/plain" })
64
+ Response post (String body );
65
+
66
+ @ RequestLine ("GET /" )
67
+ @ Headers ("Accept: text/plain" )
68
+ String get ();
69
+
70
+ @ RequestLine ("GET /?foo={multiFoo}" )
71
+ Response get (@ Param ("multiFoo" ) List <String > multiFoo );
72
+
73
+ @ Headers ({"Authorization: {authorization}" })
74
+ @ RequestLine ("GET /" )
75
+ Response getWithHeaders (@ Param ("authorization" ) String authorization );
76
+
77
+ @ RequestLine (value = "GET /?foo={multiFoo}" , collectionFormat = CollectionFormat .CSV )
78
+ Response getCSV (@ Param ("multiFoo" ) List <String > multiFoo );
62
79
}
63
80
64
81
@ Override
@@ -117,12 +134,13 @@ public void veryLongResponseNullLength() {
117
134
118
135
@ Test
119
136
void timeoutTest () {
120
- server .enqueue (new MockResponse ().setBody ("foo" ).setBodyDelay ( 30 , TimeUnit .SECONDS ));
137
+ server .enqueue (new MockResponse ().setBody ("foo" ).setHeadersDelay ( 1 , TimeUnit .SECONDS ));
121
138
122
139
final TestInterface api =
123
140
newBuilder ()
124
141
.retryer (Retryer .NEVER_RETRY )
125
- .options (new Request .Options (1 , TimeUnit .SECONDS , 1 , TimeUnit .SECONDS , true ))
142
+ .options (
143
+ new Request .Options (500 , TimeUnit .MILLISECONDS , 500 , TimeUnit .MILLISECONDS , true ))
126
144
.target (TestInterface .class , server .url ("/" ).toString ());
127
145
128
146
FeignException exception = assertThrows (FeignException .class , () -> api .timeout ());
@@ -145,6 +163,148 @@ void deleteWithRequestBody() {
145
163
assertThat (result ).contains ("\" data\" : \" some request body\" " );
146
164
}
147
165
166
+ @ Override
167
+ @ Test
168
+ public void parsesResponseMissingLength () throws IOException {
169
+ server .enqueue (new MockResponse ().setChunkedBody ("foo" , 1 ));
170
+
171
+ TestInterface api =
172
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
173
+
174
+ Response response = api .post ("testing" );
175
+ assertThat (response .status ()).isEqualTo (200 );
176
+ // assertThat(response.reason()).isEqualTo("OK");
177
+ assertThat (response .body ().length ()).isNull ();
178
+ assertThat (response .body ().asInputStream ())
179
+ .hasSameContentAs (new ByteArrayInputStream ("foo" .getBytes (UTF_8 )));
180
+ }
181
+
182
+ @ Override
183
+ @ Test
184
+ public void parsesErrorResponse () {
185
+
186
+ server .enqueue (new MockResponse ().setResponseCode (500 ).setBody ("ARGHH" ));
187
+
188
+ TestInterface api =
189
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
190
+
191
+ Throwable exception = assertThrows (FeignException .class , () -> api .get ());
192
+ assertThat (exception .getMessage ())
193
+ .contains (
194
+ "[500] during [GET] to [http://localhost:"
195
+ + server .getPort ()
196
+ + "/] [TestInterface#get()]: [ARGHH]" );
197
+ }
198
+
199
+ @ Override
200
+ @ Test
201
+ public void defaultCollectionFormat () throws Exception {
202
+ server .enqueue (new MockResponse ().setBody ("body" ));
203
+
204
+ TestInterface api =
205
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
206
+
207
+ Response response = api .get (Arrays .asList ("bar" , "baz" ));
208
+
209
+ assertThat (response .status ()).isEqualTo (200 );
210
+ // assertThat(response.reason()).isEqualTo("OK");
211
+
212
+ MockWebServerAssertions .assertThat (server .takeRequest ())
213
+ .hasMethod ("GET" )
214
+ .hasPath ("/?foo=bar&foo=baz" );
215
+ }
216
+
217
+ @ Override
218
+ @ Test
219
+ public void headersWithNotEmptyParams () throws InterruptedException {
220
+ server .enqueue (new MockResponse ().setBody ("body" ));
221
+
222
+ TestInterface api =
223
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
224
+
225
+ Response response = api .getWithHeaders ("token" );
226
+
227
+ assertThat (response .status ()).isEqualTo (200 );
228
+ // assertThat(response.reason()).isEqualTo("OK");
229
+
230
+ MockWebServerAssertions .assertThat (server .takeRequest ())
231
+ .hasMethod ("GET" )
232
+ .hasPath ("/" )
233
+ .hasHeaders (entry ("authorization" , Collections .singletonList ("token" )));
234
+ }
235
+
236
+ @ Override
237
+ @ Test
238
+ public void headersWithNullParams () throws InterruptedException {
239
+ server .enqueue (new MockResponse ().setBody ("body" ));
240
+
241
+ TestInterface api =
242
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
243
+
244
+ Response response = api .getWithHeaders (null );
245
+
246
+ assertThat (response .status ()).isEqualTo (200 );
247
+ // assertThat(response.reason()).isEqualTo("OK");
248
+
249
+ MockWebServerAssertions .assertThat (server .takeRequest ())
250
+ .hasMethod ("GET" )
251
+ .hasPath ("/" )
252
+ .hasNoHeaderNamed ("Authorization" );
253
+ }
254
+
255
+ @ Test
256
+ public void alternativeCollectionFormat () throws Exception {
257
+ server .enqueue (new MockResponse ().setBody ("body" ));
258
+
259
+ TestInterface api =
260
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
261
+
262
+ Response response = api .getCSV (Arrays .asList ("bar" , "baz" ));
263
+
264
+ assertThat (response .status ()).isEqualTo (200 );
265
+ // assertThat(response.reason()).isEqualTo("OK");
266
+
267
+ // Some HTTP libraries percent-encode commas in query parameters and others
268
+ // don't.
269
+ MockWebServerAssertions .assertThat (server .takeRequest ())
270
+ .hasMethod ("GET" )
271
+ .hasOneOfPath ("/?foo=bar,baz" , "/?foo=bar%2Cbaz" );
272
+ }
273
+
274
+ @ Override
275
+ @ Test
276
+ public void parsesRequestAndResponse () throws IOException , InterruptedException {
277
+ server .enqueue (new MockResponse ().setBody ("foo" ).addHeader ("Foo: Bar" ));
278
+
279
+ TestInterface api =
280
+ newBuilder ().target (TestInterface .class , "http://localhost:" + server .getPort ());
281
+
282
+ Response response = api .post ("foo" );
283
+
284
+ assertThat (response .status ()).isEqualTo (200 );
285
+ // assertThat(response.reason()).isEqualTo("OK");
286
+ assertThat (response .headers ())
287
+ .hasEntrySatisfying (
288
+ "Content-Length" ,
289
+ value -> {
290
+ assertThat (value ).contains ("3" );
291
+ })
292
+ .hasEntrySatisfying (
293
+ "Foo" ,
294
+ value -> {
295
+ assertThat (value ).contains ("Bar" );
296
+ });
297
+ assertThat (response .body ().asInputStream ())
298
+ .hasSameContentAs (new ByteArrayInputStream ("foo" .getBytes (UTF_8 )));
299
+
300
+ RecordedRequest recordedRequest = server .takeRequest ();
301
+ assertThat (recordedRequest .getMethod ()).isEqualToIgnoringCase ("POST" );
302
+ assertThat (recordedRequest .getHeader ("Foo" )).isEqualToIgnoringCase ("Bar, Baz" );
303
+ assertThat (recordedRequest .getHeader ("Accept" )).isEqualToIgnoringCase ("*/*" );
304
+ assertThat (recordedRequest .getHeader ("Content-Length" )).isEqualToIgnoringCase ("3" );
305
+ assertThat (recordedRequest .getBody ().readUtf8 ()).isEqualToIgnoringCase ("foo" );
306
+ }
307
+
148
308
@ Override
149
309
public Feign .Builder newBuilder () {
150
310
return Feign .builder ().client (new Http2Client ());
0 commit comments