Add additional tests for redirects with different HTTP methods

Closes gh-42879
This commit is contained in:
Phillip Webb
2024-10-25 14:41:45 -07:00
parent 85b1c55bb8
commit 97b20e9a98
4 changed files with 65 additions and 17 deletions

View File

@@ -41,6 +41,10 @@ abstract class AbstractClientHttpRequestFactoryBuilder<T extends ClientHttpReque
this.customizers = (customizers != null) ? customizers : Collections.emptyList();
}
protected final List<Consumer<T>> getCustomizers() {
return this.customizers;
}
protected final List<Consumer<T>> mergedCustomizers(Consumer<T> customizer) {
Assert.notNull(this.customizers, "'customizer' must not be null");
return merge(this.customizers, List.of(customizer));

View File

@@ -21,6 +21,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.function.Function;
import javax.net.ssl.SSLHandshakeException;
@@ -62,6 +63,8 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@DirtiesUrlFactories
abstract class AbstractClientHttpRequestFactoryBuilderTests<T extends ClientHttpRequestFactory> {
private static final Function<HttpMethod, HttpStatus> ALWAYS_FOUND = (method) -> HttpStatus.FOUND;
private final Class<T> requestFactoryType;
private final ClientHttpRequestFactoryBuilder<T> builder;
@@ -120,24 +123,31 @@ abstract class AbstractClientHttpRequestFactoryBuilderTests<T extends ClientHttp
}
}
@Test
void redirectDefault() throws Exception {
testRedirect(null, HttpStatus.OK);
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "PATCH", "DELETE" })
void redirectDefault(String httpMethod) throws Exception {
testRedirect(null, HttpMethod.valueOf(httpMethod), this::getExpectedRedirect);
}
@Test
void redirectFollow() throws Exception {
testRedirect(ClientHttpRequestFactorySettings.defaults().withRedirects(Redirects.FOLLOW), HttpStatus.OK);
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "PATCH", "DELETE" })
void redirectFollow(String httpMethod) throws Exception {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.defaults()
.withRedirects(Redirects.FOLLOW);
testRedirect(settings, HttpMethod.valueOf(httpMethod), this::getExpectedRedirect);
}
@Test
void redirectDontFollow() throws Exception {
testRedirect(ClientHttpRequestFactorySettings.defaults().withRedirects(Redirects.DONT_FOLLOW),
HttpStatus.FOUND);
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "PATCH", "DELETE" })
void redirectDontFollow(String httpMethod) throws Exception {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.defaults()
.withRedirects(Redirects.DONT_FOLLOW);
testRedirect(settings, HttpMethod.valueOf(httpMethod), ALWAYS_FOUND);
}
private void testRedirect(ClientHttpRequestFactorySettings settings, HttpStatus expectedStatus)
throws URISyntaxException, IOException {
protected final void testRedirect(ClientHttpRequestFactorySettings settings, HttpMethod httpMethod,
Function<HttpMethod, HttpStatus> expectedStatusForMethod) throws URISyntaxException, IOException {
HttpStatus expectedStatus = expectedStatusForMethod.apply(httpMethod);
TomcatServletWebServerFactory webServerFactory = new TomcatServletWebServerFactory(0);
WebServer webServer = webServerFactory
.getWebServer((context) -> context.addServlet("test", TestServlet.class).addMapping("/"));
@@ -146,12 +156,11 @@ abstract class AbstractClientHttpRequestFactoryBuilderTests<T extends ClientHttp
int port = webServer.getPort();
URI uri = new URI("http://localhost:%s".formatted(port) + "/redirect");
ClientHttpRequestFactory requestFactory = this.builder.build(settings);
ClientHttpRequest request = requestFactory.createRequest(uri, HttpMethod.GET);
ClientHttpRequest request = requestFactory.createRequest(uri, httpMethod);
ClientHttpResponse response = request.execute();
assertThat(response.getStatusCode()).isEqualTo(expectedStatus);
if (expectedStatus == HttpStatus.OK) {
assertThat(response.getBody()).asString(StandardCharsets.UTF_8)
.contains("Received GET request to /redirected");
assertThat(response.getBody()).asString(StandardCharsets.UTF_8).contains("request to /redirected");
}
}
finally {
@@ -178,6 +187,10 @@ abstract class AbstractClientHttpRequestFactoryBuilderTests<T extends ClientHttp
return SslBundle.of(stores, SslBundleKey.of("password"));
}
protected HttpStatus getExpectedRedirect(HttpMethod httpMethod) {
return HttpStatus.OK;
}
protected abstract long connectTimeout(T requestFactory);
protected abstract long readTimeout(T requestFactory);

View File

@@ -54,7 +54,7 @@ class ReflectiveComponentsClientHttpRequestFactoryBuilderTests
}
@Override
void redirectFollow() throws Exception {
void redirectFollow(String httpMethod) throws Exception {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.defaults()
.withRedirects(Redirects.FOLLOW);
assertThatIllegalStateException().isThrownBy(() -> ofTestRequestFactory().build(settings))
@@ -62,7 +62,7 @@ class ReflectiveComponentsClientHttpRequestFactoryBuilderTests
}
@Override
void redirectDontFollow() throws Exception {
void redirectDontFollow(String httpMethod) throws Exception {
ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.defaults()
.withRedirects(Redirects.DONT_FOLLOW);
assertThatIllegalStateException().isThrownBy(() -> ofTestRequestFactory().build(settings))

View File

@@ -16,6 +16,11 @@
package org.springframework.boot.http.client;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.test.util.ReflectionTestUtils;
@@ -42,4 +47,30 @@ class SimpleClientHttpRequestFactoryBuilderTests
return (int) ReflectionTestUtils.getField(requestFactory, "readTimeout");
}
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "DELETE" })
@Override
void redirectDefault(String httpMethod) throws Exception {
super.redirectDefault(httpMethod);
}
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "DELETE" })
@Override
void redirectFollow(String httpMethod) throws Exception {
super.redirectFollow(httpMethod);
}
@ParameterizedTest
@ValueSource(strings = { "GET", "POST", "PUT", "DELETE" })
@Override
void redirectDontFollow(String httpMethod) throws Exception {
super.redirectDontFollow(httpMethod);
}
@Override
protected HttpStatus getExpectedRedirect(HttpMethod httpMethod) {
return (httpMethod != HttpMethod.GET) ? HttpStatus.FOUND : HttpStatus.OK;
}
}