Add cookie support to RestClient

See gh-33697
This commit is contained in:
Nicklas Wiegandt
2024-10-13 19:07:00 +02:00
committed by rstoyanchev
parent d8c153a9d1
commit a0af708c03
6 changed files with 339 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
@@ -42,6 +43,7 @@ import static org.assertj.core.api.Assertions.fail;
/**
* @author Arjen Poutsma
* @author Sebastien Deleuze
* @author Nicklas Wiegandt
*/
public class RestClientBuilderTests {
@@ -137,6 +139,123 @@ public class RestClientBuilderTests {
assertThatIllegalArgumentException().isThrownBy(() -> builder.messageConverters(converters));
}
@Test
void defaultCookieAddsCookieToDefaultCookiesMap() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("myCookie", "testValue");
assertThat(fieldValue("defaultCookies", (DefaultRestClientBuilder) builder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(Map.entry("myCookie", List.of("testValue")));
}
@Test
void defaultCookieWithMultipleValuesAddsCookieToDefaultCookiesMapWithAllValues() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("myCookie", "testValue1", "testValue2");
assertThat(fieldValue("defaultCookies", (DefaultRestClientBuilder) builder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(Map.entry("myCookie", List.of("testValue1", "testValue2")));
}
@Test
void defaultCookiesAllowsToAddCookie() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("firstCookie", "firstValue");
builder.defaultCookies(cookies -> cookies.add("secondCookie", "secondValue"));
assertThat(fieldValue("defaultCookies", (DefaultRestClientBuilder) builder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(
Map.entry("firstCookie", List.of("firstValue")),
Map.entry("secondCookie", List.of("secondValue"))
);
}
@Test
void defaultCookiesAllowsToRemoveCookie() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("firstCookie", "firstValue");
builder.defaultCookie("secondCookie", "secondValue");
builder.defaultCookies(cookies -> cookies.remove("firstCookie"));
assertThat(fieldValue("defaultCookies", (DefaultRestClientBuilder) builder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(Map.entry("secondCookie", List.of("secondValue")));
}
@Test
void copyConstructorCopiesDefaultCookies() {
DefaultRestClientBuilder sourceBuilder = new DefaultRestClientBuilder();
sourceBuilder.defaultCookie("firstCookie", "firstValue");
sourceBuilder.defaultCookie("secondCookie", "secondValue");
DefaultRestClientBuilder copiedBuilder = new DefaultRestClientBuilder(sourceBuilder);
assertThat(fieldValue("defaultCookies", copiedBuilder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(
Map.entry("firstCookie", List.of("firstValue")),
Map.entry("secondCookie", List.of("secondValue"))
);
}
@Test
void copyConstructorCopiesDefaultCookiesImmutable() {
DefaultRestClientBuilder sourceBuilder = new DefaultRestClientBuilder();
sourceBuilder.defaultCookie("firstCookie", "firstValue");
sourceBuilder.defaultCookie("secondCookie", "secondValue");
DefaultRestClientBuilder copiedBuilder = new DefaultRestClientBuilder(sourceBuilder);
sourceBuilder.defaultCookie("thirdCookie", "thirdValue");
assertThat(fieldValue("defaultCookies", copiedBuilder))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(
Map.entry("firstCookie", List.of("firstValue")),
Map.entry("secondCookie", List.of("secondValue"))
);
}
@Test
void buildCopiesDefaultCookies() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("firstCookie", "firstValue");
builder.defaultCookie("secondCookie", "secondValue");
RestClient restClient = builder.build();
assertThat(fieldValue("defaultCookies", restClient))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(
Map.entry("firstCookie", List.of("firstValue")),
Map.entry("secondCookie", List.of("secondValue"))
);
}
@Test
void buildCopiesDefaultCookiesImmutable() {
RestClient.Builder builder = RestClient.builder();
builder.defaultCookie("firstCookie", "firstValue");
builder.defaultCookie("secondCookie", "secondValue");
RestClient restClient = builder.build();
builder.defaultCookie("thirdCookie", "thirdValue");
builder.defaultCookie("firstCookie", "fourthValue");
assertThat(fieldValue("defaultCookies", restClient))
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsExactly(
Map.entry("firstCookie", List.of("firstValue")),
Map.entry("secondCookie", List.of("secondValue"))
);
}
@Nullable
private static Object fieldValue(String name, DefaultRestClientBuilder instance) {
try {
@@ -150,4 +269,18 @@ public class RestClientBuilderTests {
return null;
}
}
@Nullable
private static Object fieldValue(String name, RestClient instance) {
try {
Field field = DefaultRestClient.class.getDeclaredField(name);
field.setAccessible(true);
return field.get(instance);
}
catch (NoSuchFieldException | IllegalAccessException ex) {
fail(ex.getMessage(), ex);
return null;
}
}
}

View File

@@ -814,6 +814,25 @@ class RestClientIntegrationTests {
expectRequest(request -> assertThat(request.getHeader("foo")).isEqualTo("bar"));
}
@ParameterizedRestClientTest
void retrieveDefaultCookiesAsCookieHeader(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);
prepareResponse(response ->
response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!"));
RestClient restClientWithCookies = this.restClient.mutate()
.defaultCookie("testCookie", "firstValue", "secondValue")
.build();
restClientWithCookies.get()
.uri("/greeting")
.header("X-Test-Header", "testvalue")
.retrieve();
expectRequest(request ->
assertThat(request.getHeader(HttpHeaders.COOKIE))
.isEqualTo("testCookie=firstValue; testCookie=secondValue")
);
}
@ParameterizedRestClientTest
void filterForErrorHandling(ClientHttpRequestFactory requestFactory) {
@@ -947,6 +966,55 @@ class RestClientIntegrationTests {
expectRequest(request -> assertThat(request.getPath()).isEqualTo("/foo%20bar"));
}
@ParameterizedRestClientTest
void cookieAddsCookie(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
.setBody("Hello Spring!"));
this.restClient.get()
.uri("/greeting")
.cookie("foo", "bar")
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("foo=bar"));
}
@ParameterizedRestClientTest
void cookieOverridesDefaultCookie(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
.setBody("Hello Spring!"));
RestClient restClientWithCookies = this.restClient.mutate()
.defaultCookie("testCookie", "firstValue", "secondValue")
.build();
restClientWithCookies.get()
.uri("/greeting")
.cookie("testCookie", "test")
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("testCookie=test"));
}
@ParameterizedRestClientTest
void cookiesCanRemoveCookie(ClientHttpRequestFactory requestFactory) {
startServer(requestFactory);
prepareResponse(response -> response.setHeader("Content-Type", "text/plain")
.setBody("Hello Spring!"));
this.restClient.get()
.uri("/greeting")
.cookie("foo", "bar")
.cookie("test", "Hello")
.cookies(cookies -> cookies.remove("foo"))
.retrieve()
.body(String.class);
expectRequest(request -> assertThat(request.getHeader("Cookie")).isEqualTo("test=Hello"));
}
private void prepareResponse(Consumer<MockResponse> consumer) {
MockResponse response = new MockResponse();