• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.http;
17 
18 import static java.util.Collections.emptyMap;
19 import static java.util.Collections.singletonList;
20 import static java.util.Collections.singletonMap;
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
23 import static org.assertj.core.api.Assertions.assertThatThrownBy;
24 
25 import java.net.URI;
26 import java.util.AbstractMap;
27 import java.util.Arrays;
28 import java.util.LinkedHashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.function.Consumer;
32 import java.util.function.Supplier;
33 import org.junit.jupiter.api.Test;
34 
35 /**
36  * Verify that {@link DefaultSdkHttpFullRequest} and {@link DefaultSdkHttpFullResponse} properly fulfill the contracts in their
37  * interfaces.
38  */
39 public class SdkHttpRequestResponseTest {
40     @Test
optionalValuesAreOptional()41     public void optionalValuesAreOptional() {
42         assertThat(validRequest().contentStreamProvider()).isNotPresent();
43         assertThat(validResponse().content()).isNotPresent();
44         assertThat(validResponse().statusText()).isNotPresent();
45     }
46 
47     @Test
requestHeaderMapsAreCopiedWhenModified()48     public void requestHeaderMapsAreCopiedWhenModified() {
49         assertRequestHeaderMapsAreCopied(b -> b.putHeader("foo", "bar"));
50         assertRequestHeaderMapsAreCopied(b -> b.putHeader("foo", singletonList("bar")));
51         assertRequestHeaderMapsAreCopied(b -> b.appendHeader("foo", "bar"));
52         assertRequestHeaderMapsAreCopied(b -> b.headers(emptyMap()));
53         assertRequestHeaderMapsAreCopied(b -> b.clearHeaders());
54         assertRequestHeaderMapsAreCopied(b -> b.removeHeader("Accept"));
55     }
56 
57     @Test
requestQueryStringMapsAreCopiedWhenModified()58     public void requestQueryStringMapsAreCopiedWhenModified() {
59         assertRequestQueryStringMapsAreCopied(b -> b.putRawQueryParameter("foo", "bar"));
60         assertRequestQueryStringMapsAreCopied(b -> b.putRawQueryParameter("foo", singletonList("bar")));
61         assertRequestQueryStringMapsAreCopied(b -> b.appendRawQueryParameter("foo", "bar"));
62         assertRequestQueryStringMapsAreCopied(b -> b.rawQueryParameters(emptyMap()));
63         assertRequestQueryStringMapsAreCopied(b -> b.clearQueryParameters());
64         assertRequestQueryStringMapsAreCopied(b -> b.removeQueryParameter("Accept"));
65     }
66 
67     @Test
responseHeaderMapsAreCopiedWhenModified()68     public void responseHeaderMapsAreCopiedWhenModified() {
69         assertResponseHeaderMapsAreCopied(b -> b.putHeader("foo", "bar"));
70         assertResponseHeaderMapsAreCopied(b -> b.putHeader("foo", singletonList("bar")));
71         assertResponseHeaderMapsAreCopied(b -> b.appendHeader("foo", "bar"));
72         assertResponseHeaderMapsAreCopied(b -> b.headers(emptyMap()));
73         assertResponseHeaderMapsAreCopied(b -> b.clearHeaders());
74         assertResponseHeaderMapsAreCopied(b -> b.removeHeader("Accept"));
75     }
76 
assertRequestHeaderMapsAreCopied(Consumer<SdkHttpRequest.Builder> mutation)77     private void assertRequestHeaderMapsAreCopied(Consumer<SdkHttpRequest.Builder> mutation) {
78         SdkHttpFullRequest request = validRequestWithMaps();
79         Map<String, List<String>> originalQuery = new LinkedHashMap<>(request.headers());
80         SdkHttpFullRequest.Builder builder = request.toBuilder();
81 
82         assertThat(request.headers()).isEqualTo(builder.headers());
83 
84         builder.applyMutation(mutation);
85         SdkHttpFullRequest request2 = builder.build();
86 
87         assertThat(request.headers()).isEqualTo(originalQuery);
88         assertThat(request.headers()).isNotEqualTo(request2.headers());
89     }
90 
assertRequestQueryStringMapsAreCopied(Consumer<SdkHttpRequest.Builder> mutation)91     private void assertRequestQueryStringMapsAreCopied(Consumer<SdkHttpRequest.Builder> mutation) {
92         SdkHttpFullRequest request = validRequestWithMaps();
93         Map<String, List<String>> originalQuery = new LinkedHashMap<>(request.rawQueryParameters());
94         SdkHttpFullRequest.Builder builder = request.toBuilder();
95 
96         assertThat(request.rawQueryParameters()).isEqualTo(builder.rawQueryParameters());
97 
98         builder.applyMutation(mutation);
99         SdkHttpFullRequest request2 = builder.build();
100 
101         assertThat(request.rawQueryParameters()).isEqualTo(originalQuery);
102         assertThat(request.rawQueryParameters()).isNotEqualTo(request2.rawQueryParameters());
103     }
104 
assertResponseHeaderMapsAreCopied(Consumer<SdkHttpResponse.Builder> mutation)105     private void assertResponseHeaderMapsAreCopied(Consumer<SdkHttpResponse.Builder> mutation) {
106         SdkHttpResponse response = validResponseWithMaps();
107         Map<String, List<String>> originalQuery = new LinkedHashMap<>(response.headers());
108         SdkHttpResponse.Builder builder = response.toBuilder();
109 
110         assertThat(response.headers()).isEqualTo(builder.headers());
111 
112         builder.applyMutation(mutation);
113         SdkHttpResponse response2 = builder.build();
114 
115         assertThat(response.headers()).isEqualTo(originalQuery);
116         assertThat(response.headers()).isNotEqualTo(response2.headers());
117     }
118 
119     @Test
headersAreUnmodifiable()120     public void headersAreUnmodifiable() {
121         assertThatThrownBy(() -> validRequest().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
122         assertThatThrownBy(() -> validResponse().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
123         assertThatThrownBy(() -> validRequest().toBuilder().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
124         assertThatThrownBy(() -> validResponse().toBuilder().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
125         assertThatThrownBy(() -> validRequest().toBuilder().build().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
126         assertThatThrownBy(() -> validResponse().toBuilder().build().headers().clear()).isInstanceOf(UnsupportedOperationException.class);
127     }
128 
129     @Test
queryStringsAreUnmodifiable()130     public void queryStringsAreUnmodifiable() {
131         assertThatThrownBy(() -> validRequest().rawQueryParameters().clear()).isInstanceOf(UnsupportedOperationException.class);
132         assertThatThrownBy(() -> validRequest().toBuilder().rawQueryParameters().clear()).isInstanceOf(UnsupportedOperationException.class);
133         assertThatThrownBy(() -> validRequest().toBuilder().build().rawQueryParameters().clear()).isInstanceOf(UnsupportedOperationException.class);
134     }
135 
136     @Test
uriConversionIsCorrect()137     public void uriConversionIsCorrect() {
138         assertThat(normalizedUri(b -> b.protocol("http").host("localhost"))).isEqualTo("http://localhost");
139         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80))).isEqualTo("http://localhost");
140         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(8080))).isEqualTo("http://localhost:8080");
141         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(443))).isEqualTo("http://localhost:443");
142         assertThat(normalizedUri(b -> b.protocol("https").host("localhost").port(443))).isEqualTo("https://localhost");
143         assertThat(normalizedUri(b -> b.protocol("https").host("localhost").port(8443))).isEqualTo("https://localhost:8443");
144         assertThat(normalizedUri(b -> b.protocol("https").host("localhost").port(80))).isEqualTo("https://localhost:80");
145         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("foo")))
146                 .isEqualTo("http://localhost/foo");
147         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("/foo")))
148                 .isEqualTo("http://localhost/foo");
149         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("foo/")))
150                 .isEqualTo("http://localhost/foo/");
151         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("/foo/")))
152                 .isEqualTo("http://localhost/foo/");
153         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).putRawQueryParameter("foo", "bar ")))
154                 .isEqualTo("http://localhost?foo=bar%20");
155         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("/foo").putRawQueryParameter("foo", "bar")))
156                 .isEqualTo("http://localhost/foo?foo=bar");
157         assertThat(normalizedUri(b -> b.protocol("http").host("localhost").port(80).encodedPath("foo/").putRawQueryParameter("foo", "bar")))
158                 .isEqualTo("http://localhost/foo/?foo=bar");
159     }
160 
normalizedUri(Consumer<SdkHttpRequest.Builder> builderMutator)161     private String normalizedUri(Consumer<SdkHttpRequest.Builder> builderMutator) {
162         return validRequestBuilder().applyMutation(builderMutator).build().getUri().toString();
163     }
164 
165     @Test
protocolNormalizationIsCorrect()166     public void protocolNormalizationIsCorrect() {
167         assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> normalizedProtocol(null));
168         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> normalizedProtocol("foo"));
169         assertThat(normalizedProtocol("http")).isEqualTo("http");
170         assertThat(normalizedProtocol("https")).isEqualTo("https");
171         assertThat(normalizedProtocol("HtTp")).isEqualTo("http");
172         assertThat(normalizedProtocol("HtTpS")).isEqualTo("https");
173     }
174 
normalizedProtocol(String protocol)175     private String normalizedProtocol(String protocol) {
176         return validRequestBuilder().protocol(protocol).build().protocol();
177     }
178 
179     @Test
hostNormalizationIsCorrect()180     public void hostNormalizationIsCorrect() {
181         assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> normalizedHost(null));
182         assertThat(normalizedHost("foo")).isEqualTo("foo");
183     }
184 
normalizedHost(String host)185     private String normalizedHost(String host) {
186         return validRequestBuilder().host(host).build().host();
187     }
188 
189     @Test
portNormalizationIsCorrect()190     public void portNormalizationIsCorrect() {
191         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> normalizedPort("http", -2));
192         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> normalizedPort("https", -2));
193         assertThat(normalizedPort("http", -1)).isEqualTo(80);
194         assertThat(normalizedPort("http", null)).isEqualTo(80);
195         assertThat(normalizedPort("https", -1)).isEqualTo(443);
196         assertThat(normalizedPort("https", null)).isEqualTo(443);
197         assertThat(normalizedPort("http", 8080)).isEqualTo(8080);
198         assertThat(normalizedPort("https", 8443)).isEqualTo(8443);
199     }
200 
normalizedPort(String protocol, Integer port)201     private int normalizedPort(String protocol, Integer port) {
202         return validRequestBuilder().protocol(protocol).port(port).build().port();
203     }
204 
205     @Test
requestPathNormalizationIsCorrect()206     public void requestPathNormalizationIsCorrect() {
207         assertThat(normalizedPath(null)).isEqualTo("");
208         assertThat(normalizedPath("/")).isEqualTo("/");
209         assertThat(normalizedPath(" ")).isEqualTo("/ ");
210         assertThat(normalizedPath(" /")).isEqualTo("/ /");
211         assertThat(normalizedPath("/ ")).isEqualTo("/ ");
212         assertThat(normalizedPath("/ /")).isEqualTo("/ /");
213         assertThat(normalizedPath(" / ")).isEqualTo("/ / ");
214         assertThat(normalizedPath("/Foo/")).isEqualTo("/Foo/");
215         assertThat(normalizedPath("Foo/")).isEqualTo("/Foo/");
216         assertThat(normalizedPath("Foo")).isEqualTo("/Foo");
217         assertThat(normalizedPath("/Foo/bar/")).isEqualTo("/Foo/bar/");
218         assertThat(normalizedPath("Foo/bar/")).isEqualTo("/Foo/bar/");
219         assertThat(normalizedPath("/Foo/bar")).isEqualTo("/Foo/bar");
220         assertThat(normalizedPath("Foo/bar")).isEqualTo("/Foo/bar");
221         assertThat(normalizedPath("%2F")).isEqualTo("/%2F");
222     }
223 
normalizedPath(String path)224     private String normalizedPath(String path) {
225         return validRequestBuilder().encodedPath(path).build().encodedPath();
226     }
227 
228     @Test
requestMethodNormalizationIsCorrect()229     public void requestMethodNormalizationIsCorrect() {
230         assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> normalizedMethod(null));
231         assertThat(normalizedMethod(SdkHttpMethod.POST)).isEqualTo(SdkHttpMethod.POST);
232     }
233 
normalizedMethod(SdkHttpMethod method)234     private SdkHttpMethod normalizedMethod(SdkHttpMethod method) {
235         return validRequestBuilder().method(method).build().method();
236     }
237 
238     @Test
requestQueryParamNormalizationIsCorrect()239     public void requestQueryParamNormalizationIsCorrect() {
240         headerOrQueryStringNormalizationIsCorrect(() -> new BuilderProxy() {
241             private final SdkHttpRequest.Builder builder = validRequestBuilder();
242 
243             @Override
244             public BuilderProxy setValue(String key, String value) {
245                 builder.putRawQueryParameter(key, value);
246                 return this;
247             }
248 
249             @Override
250             public BuilderProxy appendValue(String key, String value) {
251                 builder.appendRawQueryParameter(key, value);
252                 return this;
253             }
254 
255             @Override
256             public BuilderProxy setValues(String key, List<String> values) {
257                 builder.putRawQueryParameter(key, values);
258                 return this;
259             }
260 
261             @Override
262             public BuilderProxy removeValue(String key) {
263                 builder.removeQueryParameter(key);
264                 return this;
265             }
266 
267             @Override
268             public BuilderProxy clearValues() {
269                 builder.clearQueryParameters();
270                 return this;
271             }
272 
273             @Override
274             public BuilderProxy setMap(Map<String, List<String>> map) {
275                 builder.rawQueryParameters(map);
276                 return this;
277             }
278 
279             @Override
280             public Map<String, List<String>> getMap() {
281                 return builder.build().rawQueryParameters();
282             }
283         });
284     }
285 
286     @Test
requestHeaderNormalizationIsCorrect()287     public void requestHeaderNormalizationIsCorrect() {
288         headerOrQueryStringNormalizationIsCorrect(() -> new BuilderProxy() {
289             private final SdkHttpRequest.Builder builder = validRequestBuilder();
290 
291             @Override
292             public BuilderProxy setValue(String key, String value) {
293                 builder.putHeader(key, value);
294                 return this;
295             }
296 
297             @Override
298             public BuilderProxy appendValue(String key, String value) {
299                 builder.appendHeader(key, value);
300                 return this;
301             }
302 
303             @Override
304             public BuilderProxy setValues(String key, List<String> values) {
305                 builder.putHeader(key, values);
306                 return this;
307             }
308 
309             @Override
310             public BuilderProxy removeValue(String key) {
311                 builder.removeHeader(key);
312                 return this;
313             }
314 
315             @Override
316             public BuilderProxy clearValues() {
317                 builder.clearHeaders();
318                 return this;
319             }
320 
321             @Override
322             public BuilderProxy setMap(Map<String, List<String>> map) {
323                 builder.headers(map);
324                 return this;
325             }
326 
327             @Override
328             public Map<String, List<String>> getMap() {
329                 return builder.build().headers();
330             }
331         });
332     }
333 
334     @Test
responseStatusCodeNormalizationIsCorrect()335     public void responseStatusCodeNormalizationIsCorrect() {
336         assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> normalizedStatusCode(-1));
337         assertThat(normalizedStatusCode(200)).isEqualTo(200);
338     }
339 
normalizedStatusCode(int statusCode)340     private int normalizedStatusCode(int statusCode) {
341         return validResponseBuilder().statusCode(statusCode).build().statusCode();
342     }
343 
344     @Test
responseHeaderNormalizationIsCorrect()345     public void responseHeaderNormalizationIsCorrect() {
346         headerOrQueryStringNormalizationIsCorrect(() -> new BuilderProxy() {
347             private final SdkHttpFullResponse.Builder builder = validResponseBuilder();
348 
349             @Override
350             public BuilderProxy setValue(String key, String value) {
351                 builder.putHeader(key, value);
352                 return this;
353             }
354 
355             @Override
356             public BuilderProxy appendValue(String key, String value) {
357                 builder.appendHeader(key, value);
358                 return this;
359             }
360 
361             @Override
362             public BuilderProxy setValues(String key, List<String> values) {
363                 builder.putHeader(key, values);
364                 return this;
365             }
366 
367             @Override
368             public BuilderProxy removeValue(String key) {
369                 builder.removeHeader(key);
370                 return this;
371             }
372 
373             @Override
374             public BuilderProxy clearValues() {
375                 builder.clearHeaders();
376                 return this;
377             }
378 
379             @Override
380             public BuilderProxy setMap(Map<String, List<String>> map) {
381                 builder.headers(map);
382                 return this;
383             }
384 
385             @Override
386             public Map<String, List<String>> getMap() {
387                 return builder.build().headers();
388             }
389         });
390     }
391 
392     @Test
testSdkHttpFullRequestBuilderNoQueryParams()393     public void testSdkHttpFullRequestBuilderNoQueryParams() {
394         URI uri = URI.create("https://github.com/aws/aws-sdk-java-v2/issues/2034");
395         final SdkHttpFullRequest sdkHttpFullRequest = SdkHttpFullRequest.builder().method(SdkHttpMethod.POST).uri(uri).build();
396         assertThat(sdkHttpFullRequest.getUri().getQuery()).isNullOrEmpty();
397     }
398 
399     @Test
testSdkHttpFullRequestBuilderUriWithQueryParams()400     public void testSdkHttpFullRequestBuilderUriWithQueryParams() {
401         URI uri = URI.create("https://github.com/aws/aws-sdk-java-v2/issues/2034?reqParam=1234&oParam=3456%26reqParam%3D5678");
402         final SdkHttpFullRequest sdkHttpFullRequest =
403             SdkHttpFullRequest.builder().method(SdkHttpMethod.POST).uri(uri).build();
404         assertThat(sdkHttpFullRequest.getUri().getQuery()).contains("reqParam=1234", "oParam=3456&reqParam=5678");
405     }
406 
407     @Test
testSdkHttpFullRequestBuilderUriWithQueryParamWithoutValue()408     public void testSdkHttpFullRequestBuilderUriWithQueryParamWithoutValue() {
409         final String expected = "https://github.com/aws/aws-sdk-for-java-v2?foo";
410         URI myUri = URI.create(expected);
411         SdkHttpFullRequest actual = SdkHttpFullRequest.builder().method(SdkHttpMethod.POST).uri(myUri).build();
412         assertThat(actual.getUri()).hasToString(expected);
413     }
414 
415     @Test
testSdkHttpRequestBuilderNoQueryParams()416     public void testSdkHttpRequestBuilderNoQueryParams() {
417         URI uri = URI.create("https://github.com/aws/aws-sdk-java-v2/issues/2034");
418         final SdkHttpRequest sdkHttpRequest = SdkHttpRequest.builder().method(SdkHttpMethod.POST).uri(uri).build();
419         assertThat(sdkHttpRequest.getUri().getQuery()).isNullOrEmpty();
420     }
421 
422     @Test
testSdkHttpRequestBuilderUriWithQueryParams()423     public void testSdkHttpRequestBuilderUriWithQueryParams() {
424         URI uri = URI.create("https://github.com/aws/aws-sdk-java-v2/issues/2034?reqParam=1234&oParam=3456%26reqParam%3D5678");
425         final SdkHttpRequest sdkHttpRequest =
426             SdkHttpRequest.builder().method(SdkHttpMethod.POST).uri(uri).build();
427         assertThat(sdkHttpRequest.getUri().getQuery()).contains("reqParam=1234", "oParam=3456&reqParam=5678");
428     }
429 
430     @Test
testSdkHttpRequestBuilderUriWithQueryParamsIgnoreOtherQueryParams()431     public void testSdkHttpRequestBuilderUriWithQueryParamsIgnoreOtherQueryParams() {
432         URI uri = URI.create("https://github.com/aws/aws-sdk-java-v2/issues/2034?reqParam=1234&oParam=3456%26reqParam%3D5678");
433         final SdkHttpRequest sdkHttpRequest =
434             SdkHttpRequest.builder().method(SdkHttpMethod.POST).appendRawQueryParameter("clean", "up").uri(uri).build();
435         assertThat(sdkHttpRequest.getUri().getQuery()).contains("reqParam=1234", "oParam=3456&reqParam=5678")
436                                                       .doesNotContain("clean");
437     }
438 
439     @Test
testSdkHttpRequestBuilderUriWithQueryParamWithoutValue()440     public void testSdkHttpRequestBuilderUriWithQueryParamWithoutValue() {
441         final String expected = "https://github.com/aws/aws-sdk-for-java-v2?foo";
442         URI myUri = URI.create(expected);
443         SdkHttpRequest actual = SdkHttpRequest.builder().method(SdkHttpMethod.POST).uri(myUri).build();
444         assertThat(actual.getUri()).hasToString(expected);
445     }
446 
447     private interface BuilderProxy {
setValue(String key, String value)448         BuilderProxy setValue(String key, String value);
449 
appendValue(String key, String value)450         BuilderProxy appendValue(String key, String value);
451 
setValues(String key, List<String> values)452         BuilderProxy setValues(String key, List<String> values);
453 
removeValue(String key)454         BuilderProxy removeValue(String key);
455 
clearValues()456         BuilderProxy clearValues();
457 
setMap(Map<String, List<String>> map)458         BuilderProxy setMap(Map<String, List<String>> map);
459 
getMap()460         Map<String, List<String>> getMap();
461     }
462 
headerOrQueryStringNormalizationIsCorrect(Supplier<BuilderProxy> builderFactory)463     private void headerOrQueryStringNormalizationIsCorrect(Supplier<BuilderProxy> builderFactory) {
464         assertMapIsInitiallyEmpty(builderFactory);
465 
466         setValue_SetsSingleValueCorrectly(builderFactory);
467 
468         setValue_SettingMultipleKeysAppendsToMap(builderFactory);
469 
470         setValue_OverwritesExistingValue(builderFactory);
471 
472         setValues_SetsAllValuesCorrectly(builderFactory);
473 
474         setValue_OverwritesAllExistingValues(builderFactory);
475 
476         removeValue_OnlyRemovesThatKey(builderFactory);
477 
478         clearValues_RemovesAllExistingValues(builderFactory);
479 
480         setMap_OverwritesAllExistingValues(builderFactory);
481 
482         appendWithExistingValues_AddsValueToList(builderFactory);
483 
484         appendWithNoValues_AddsSingleElementToList(builderFactory);
485     }
486 
assertMapIsInitiallyEmpty(Supplier<BuilderProxy> builderFactory)487     private void assertMapIsInitiallyEmpty(Supplier<BuilderProxy> builderFactory) {
488         assertThat(builderFactory.get().setMap(emptyMap()).getMap()).isEmpty();
489     }
490 
setValue_SetsSingleValueCorrectly(Supplier<BuilderProxy> builderFactory)491     private void setValue_SetsSingleValueCorrectly(Supplier<BuilderProxy> builderFactory) {
492         assertThat(builderFactory.get().setValue("Foo", "Bar").getMap()).satisfies(params -> {
493             assertThat(params).containsOnlyKeys("Foo");
494             assertThat(params.get("Foo")).containsExactly("Bar");
495         });
496     }
497 
setValue_SettingMultipleKeysAppendsToMap(Supplier<BuilderProxy> builderFactory)498     private void setValue_SettingMultipleKeysAppendsToMap(Supplier<BuilderProxy> builderFactory) {
499         assertThat(builderFactory.get().setValue("Foo", "Bar").setValue("Foo2", "Bar2").getMap()).satisfies(params -> {
500             assertThat(params).containsOnlyKeys("Foo", "Foo2");
501             assertThat(params.get("Foo")).containsExactly("Bar");
502             assertThat(params.get("Foo2")).containsExactly("Bar2");
503         });
504     }
505 
setValue_OverwritesExistingValue(Supplier<BuilderProxy> builderFactory)506     private void setValue_OverwritesExistingValue(Supplier<BuilderProxy> builderFactory) {
507         assertThat(builderFactory.get().setValue("Foo", "Bar").setValue("Foo", "Bar2").getMap()).satisfies(params -> {
508             assertThat(params).containsOnlyKeys("Foo");
509             assertThat(params.get("Foo")).containsExactly("Bar2");
510         });
511     }
512 
setValues_SetsAllValuesCorrectly(Supplier<BuilderProxy> builderFactory)513     private void setValues_SetsAllValuesCorrectly(Supplier<BuilderProxy> builderFactory) {
514         assertThat(builderFactory.get().setValues("Foo", Arrays.asList("Bar", "Baz")).getMap()).satisfies(params -> {
515             assertThat(params).containsOnlyKeys("Foo");
516             assertThat(params.get("Foo")).containsExactly("Bar", "Baz");
517         });
518     }
519 
setValue_OverwritesAllExistingValues(Supplier<BuilderProxy> builderFactory)520     private void setValue_OverwritesAllExistingValues(Supplier<BuilderProxy> builderFactory) {
521         assertThat(builderFactory.get().setValues("Foo", Arrays.asList("Bar", "Baz")).setValue("Foo", "Bar").getMap())
522                 .satisfies(params -> {
523             assertThat(params).containsOnlyKeys("Foo");
524             assertThat(params.get("Foo")).containsExactly("Bar");
525         });
526     }
527 
removeValue_OnlyRemovesThatKey(Supplier<BuilderProxy> builderFactory)528     private void removeValue_OnlyRemovesThatKey(Supplier<BuilderProxy> builderFactory) {
529         assertThat(builderFactory.get().setValues("Foo", Arrays.asList("Bar", "Baz"))
530                                  .setValues("Foo2", Arrays.asList("Bar", "Baz"))
531                                  .removeValue("Foo").getMap())
532         .satisfies(params -> {
533             assertThat(params).doesNotContainKeys("Foo");
534             assertThat(params.get("Foo2")).containsExactly("Bar", "Baz");
535         });
536     }
537 
clearValues_RemovesAllExistingValues(Supplier<BuilderProxy> builderFactory)538     private void clearValues_RemovesAllExistingValues(Supplier<BuilderProxy> builderFactory) {
539         assertThat(builderFactory.get().setValues("Foo", Arrays.asList("Bar", "Baz")).clearValues().getMap())
540                 .doesNotContainKeys("Foo");
541     }
542 
setMap_OverwritesAllExistingValues(Supplier<BuilderProxy> builderFactory)543     private void setMap_OverwritesAllExistingValues(Supplier<BuilderProxy> builderFactory) {
544         assertThat(builderFactory.get().setValues("Foo", Arrays.asList("Bar", "Baz"))
545                                  .setMap(singletonMap("Foo2", singletonList("Baz2"))).getMap())
546                 .satisfies(params -> {
547             assertThat(params).containsOnlyKeys("Foo2");
548             assertThat(params.get("Foo2")).containsExactly("Baz2");
549         });
550     }
551 
appendWithExistingValues_AddsValueToList(Supplier<BuilderProxy> builderFactory)552     private void appendWithExistingValues_AddsValueToList(Supplier<BuilderProxy> builderFactory) {
553         assertThat(builderFactory.get().setValues("Key", Arrays.asList("Foo", "Bar"))
554                                  .appendValue("Key", "Baz").getMap())
555             .satisfies(params -> {
556                 assertThat(params).containsOnly(new AbstractMap.SimpleEntry<>("Key", Arrays.asList("Foo", "Bar", "Baz")));
557             });
558     }
559 
appendWithNoValues_AddsSingleElementToList(Supplier<BuilderProxy> builderFactory)560     private void appendWithNoValues_AddsSingleElementToList(Supplier<BuilderProxy> builderFactory) {
561         assertThat(builderFactory.get().appendValue("AppendNotExists", "Baz").getMap())
562             .satisfies(params -> {
563                 assertThat(params).containsOnly(new AbstractMap.SimpleEntry<>("AppendNotExists", Arrays.asList("Baz")));
564             });
565     }
566 
validRequestWithMaps()567     private SdkHttpFullRequest validRequestWithMaps() {
568         return validRequestWithMapsBuilder().build();
569     }
570 
validRequestWithMapsBuilder()571     private SdkHttpFullRequest.Builder validRequestWithMapsBuilder() {
572         return validRequestBuilder().putHeader("Accept", "*/*")
573                                     .putRawQueryParameter("Accept", "*/*");
574     }
575 
validRequest()576     private SdkHttpFullRequest validRequest() {
577         return validRequestBuilder().build();
578     }
579 
validRequestBuilder()580     private SdkHttpFullRequest.Builder validRequestBuilder() {
581         return SdkHttpFullRequest.builder()
582                                  .protocol("http")
583                                  .host("localhost")
584                                  .method(SdkHttpMethod.GET);
585     }
586 
validResponseWithMaps()587     private SdkHttpResponse validResponseWithMaps() {
588         return validResponseWithMapsBuilder().build();
589     }
590 
validResponseWithMapsBuilder()591     private SdkHttpResponse.Builder validResponseWithMapsBuilder() {
592         return validResponseBuilder().putHeader("Accept", "*/*");
593     }
594 
validResponse()595     private SdkHttpFullResponse validResponse() {
596         return validResponseBuilder().build();
597     }
598 
validResponseBuilder()599     private SdkHttpFullResponse.Builder validResponseBuilder() {
600         return SdkHttpFullResponse.builder().statusCode(500);
601     }
602 }
603