Polishing in [Rest|Web]TestClient Assertions
See gh-34428
This commit is contained in:
parent
6cc1310274
commit
88ddc9d45d
|
@ -36,12 +36,13 @@ public class CookieAssertions extends AbstractCookieAssertions<ExchangeResult, W
|
|||
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
protected MultiValueMap<String, ResponseCookie> getResponseCookies() {
|
||||
return getExchangeResult().getResponseCookies();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValueMap<String, ResponseCookie> getResponseCookies() {
|
||||
return exchangeResult.getResponseCookies();
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,12 +38,13 @@ public class HeaderAssertions extends AbstractHeaderAssertions<ExchangeResult, W
|
|||
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
protected HttpHeaders getResponseHeaders() {
|
||||
return getExchangeResult().getResponseHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHeaders getResponseHeaders() {
|
||||
return exchangeResult.getResponseHeaders();
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@ public class StatusAssertions extends AbstractStatusAssertions<ExchangeResult, W
|
|||
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
protected HttpStatusCode getStatus() {
|
||||
return getExchangeResult().getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpStatusCode getStatus() {
|
||||
return exchangeResult.getStatus();
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,20 +35,23 @@ import org.springframework.util.Assert;
|
|||
*/
|
||||
public class XpathAssertions extends AbstractXpathAssertions<WebTestClient.BodyContentSpec> {
|
||||
|
||||
XpathAssertions(WebTestClient.BodyContentSpec spec,
|
||||
|
||||
XpathAssertions(
|
||||
WebTestClient.BodyContentSpec spec,
|
||||
String expression, @Nullable Map<String, String> namespaces, Object... args) {
|
||||
|
||||
super(spec, expression, namespaces, args);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Optional<HttpHeaders> getResponseHeaders() {
|
||||
return Optional.of(bodySpec.returnResult())
|
||||
.map(ExchangeResult::getResponseHeaders);
|
||||
return Optional.of(getBodySpec().returnResult()).map(ExchangeResult::getResponseHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] getContent() {
|
||||
byte[] body = this.bodySpec.returnResult().getResponseBody();
|
||||
byte[] body = getBodySpec().returnResult().getResponseBody();
|
||||
Assert.notNull(body, "Expected body content");
|
||||
return body;
|
||||
}
|
||||
|
|
|
@ -35,12 +35,13 @@ public class CookieAssertions extends AbstractCookieAssertions<ExchangeResult, R
|
|||
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
protected MultiValueMap<String, ResponseCookie> getResponseCookies() {
|
||||
return getExchangeResult().getResponseCookies();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValueMap<String, ResponseCookie> getResponseCookies() {
|
||||
return exchangeResult.getResponseCookies();
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable;
|
|||
* extracted to a representation of type {@code <T>}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @since 7.0
|
||||
* @param <T> the response body type
|
||||
*/
|
||||
public class EntityExchangeResult<T> extends ExchangeResult {
|
||||
|
|
|
@ -33,13 +33,15 @@ public class HeaderAssertions extends AbstractHeaderAssertions<ExchangeResult, R
|
|||
super(exchangeResult, responseSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpHeaders getResponseHeaders() {
|
||||
return exchangeResult.getResponseHeaders();
|
||||
return getExchangeResult().getResponseHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@ public class StatusAssertions extends AbstractStatusAssertions<ExchangeResult, R
|
|||
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
exchangeResult.assertWithDiagnostics(assertion);
|
||||
protected HttpStatusCode getStatus() {
|
||||
return getExchangeResult().getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpStatusCode getStatus() {
|
||||
return exchangeResult.getStatus();
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
getExchangeResult().assertWithDiagnostics(assertion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,13 +44,12 @@ public class XpathAssertions extends AbstractXpathAssertions<RestTestClient.Body
|
|||
|
||||
@Override
|
||||
protected Optional<HttpHeaders> getResponseHeaders() {
|
||||
return Optional.of(bodySpec.returnResult())
|
||||
.map(ExchangeResult::getResponseHeaders);
|
||||
return Optional.of(getBodySpec().returnResult()).map(ExchangeResult::getResponseHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] getContent() {
|
||||
byte[] body = this.bodySpec.returnResult().getResponseBody();
|
||||
byte[] body = getBodySpec().returnResult().getResponseBody();
|
||||
Assert.notNull(body, "Expected body content");
|
||||
return body;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/**
|
||||
* Support for testing Spring MVC applications via
|
||||
* {@link org.springframework.test.web.reactive.server.WebTestClient}
|
||||
* with {@link org.springframework.test.web.servlet.MockMvc} for server request
|
||||
* handling.
|
||||
* {@link org.springframework.test.web.servlet.client.RestTestClient} with
|
||||
* {@link org.springframework.test.web.servlet.MockMvc} for server request handling.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
|
|
|
@ -34,19 +34,42 @@ import static org.springframework.test.util.AssertionErrors.fail;
|
|||
* Assertions on cookies of the response.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
* @param <E> the type of the exchange result
|
||||
* @param <R> the type of the response spec
|
||||
*/
|
||||
public abstract class AbstractCookieAssertions<E, R> {
|
||||
protected final E exchangeResult;
|
||||
|
||||
private final E exchangeResult;
|
||||
|
||||
private final R responseSpec;
|
||||
|
||||
|
||||
protected AbstractCookieAssertions(E exchangeResult, R responseSpec) {
|
||||
this.exchangeResult = exchangeResult;
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the exchange result.
|
||||
*/
|
||||
protected E getExchangeResult() {
|
||||
return this.exchangeResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to provide access to response cookies.
|
||||
*/
|
||||
protected abstract MultiValueMap<String, ResponseCookie> getResponseCookies();
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to assert with diagnostics.
|
||||
*/
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
|
||||
/**
|
||||
* Expect a response cookie with the given name to match the specified value.
|
||||
*/
|
||||
|
@ -224,10 +247,6 @@ public abstract class AbstractCookieAssertions<E, R> {
|
|||
return this.responseSpec;
|
||||
}
|
||||
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
protected abstract MultiValueMap<String, ResponseCookie> getResponseCookies();
|
||||
|
||||
private ResponseCookie getCookie(String name) {
|
||||
ResponseCookie cookie = getResponseCookies().getFirst(name);
|
||||
if (cookie != null) {
|
||||
|
|
|
@ -40,19 +40,42 @@ import static org.springframework.test.util.AssertionErrors.fail;
|
|||
* Assertions on headers of the response.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
* @param <E> the type of the exchange result
|
||||
* @param <R> the type of the response spec
|
||||
*/
|
||||
public abstract class AbstractHeaderAssertions <E, R> {
|
||||
protected final E exchangeResult;
|
||||
|
||||
private final E exchangeResult;
|
||||
|
||||
private final R responseSpec;
|
||||
|
||||
|
||||
protected AbstractHeaderAssertions(E exchangeResult, R responseSpec) {
|
||||
this.exchangeResult = exchangeResult;
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the exchange result.
|
||||
*/
|
||||
protected E getExchangeResult() {
|
||||
return this.exchangeResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to provide access to response headers.
|
||||
*/
|
||||
protected abstract HttpHeaders getResponseHeaders();
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to assert with diagnostics.
|
||||
*/
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
|
||||
/**
|
||||
* Expect a header with the given name to match the specified values.
|
||||
*/
|
||||
|
@ -277,10 +300,6 @@ public abstract class AbstractHeaderAssertions <E, R> {
|
|||
return assertHeader("Location", URI.create(location), getResponseHeaders().getLocation());
|
||||
}
|
||||
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
protected abstract HttpHeaders getResponseHeaders();
|
||||
|
||||
private R assertHeader(String name, @Nullable Object expected, @Nullable Object actual) {
|
||||
assertWithDiagnostics(() -> {
|
||||
String message = getMessage(name);
|
||||
|
|
|
@ -26,6 +26,18 @@ import org.springframework.core.ParameterizedTypeReference;
|
|||
import org.springframework.test.util.JsonPathExpectationsHelper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for applying
|
||||
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> assertions
|
||||
* in RestTestClient and WebTestClient.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
* @param <B> the type of body spec (RestTestClient vs WebTestClient specific)
|
||||
* @see <a href="https://github.com/jayway/JsonPath">https://github.com/jayway/JsonPath</a>
|
||||
* @see JsonPathExpectationsHelper
|
||||
*/
|
||||
public abstract class AbstractJsonPathAssertions<B> {
|
||||
|
||||
private final B bodySpec;
|
||||
|
@ -34,6 +46,7 @@ public abstract class AbstractJsonPathAssertions<B> {
|
|||
|
||||
private final JsonPathExpectationsHelper pathHelper;
|
||||
|
||||
|
||||
protected AbstractJsonPathAssertions(B spec, String content, String expression, @Nullable Configuration configuration) {
|
||||
Assert.hasText(expression, "expression must not be null or empty");
|
||||
this.bodySpec = spec;
|
||||
|
@ -41,6 +54,7 @@ public abstract class AbstractJsonPathAssertions<B> {
|
|||
this.pathHelper = new JsonPathExpectationsHelper(expression, configuration);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies {@link JsonPathExpectationsHelper#assertValue(String, Object)}.
|
||||
*/
|
||||
|
|
|
@ -31,18 +31,42 @@ import static org.springframework.test.util.AssertionErrors.assertNotNull;
|
|||
* Assertions on the response status.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
* @param <E> the type of the exchange result
|
||||
* @param <R> the type of the response spec
|
||||
*/
|
||||
public abstract class AbstractStatusAssertions<E, R> {
|
||||
protected final E exchangeResult;
|
||||
|
||||
private final E exchangeResult;
|
||||
|
||||
private final R responseSpec;
|
||||
|
||||
|
||||
protected AbstractStatusAssertions(E exchangeResult, R responseSpec) {
|
||||
this.exchangeResult = exchangeResult;
|
||||
this.responseSpec = responseSpec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the exchange result.
|
||||
*/
|
||||
protected E getExchangeResult() {
|
||||
return this.exchangeResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to provide access to the response status.
|
||||
*/
|
||||
protected abstract HttpStatusCode getStatus();
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to assert with diagnostics.
|
||||
*/
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
|
||||
/**
|
||||
* Assert the response status as an {@link HttpStatusCode}.
|
||||
*/
|
||||
|
@ -226,10 +250,6 @@ public abstract class AbstractStatusAssertions<E, R> {
|
|||
return this.responseSpec;
|
||||
}
|
||||
|
||||
protected abstract void assertWithDiagnostics(Runnable assertion);
|
||||
|
||||
protected abstract HttpStatusCode getStatus();
|
||||
|
||||
private R assertStatusAndReturn(HttpStatus expected) {
|
||||
assertNotNull("exchangeResult unexpectedly null", this.exchangeResult);
|
||||
HttpStatusCode actual = getStatus();
|
||||
|
|
|
@ -30,12 +30,24 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.test.util.XpathExpectationsHelper;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
/**
|
||||
* Base class for applying XPath assertions in RestTestClient and WebTestClient.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 7.0
|
||||
* @param <B> the type of body spec (RestTestClient vs WebTestClient specific)
|
||||
*/
|
||||
public abstract class AbstractXpathAssertions<B> {
|
||||
protected final B bodySpec;
|
||||
|
||||
private final B bodySpec;
|
||||
|
||||
private final XpathExpectationsHelper xpathHelper;
|
||||
|
||||
public AbstractXpathAssertions(B spec, String expression, @Nullable Map<String, String> namespaces, Object... args) {
|
||||
|
||||
public AbstractXpathAssertions(
|
||||
B spec, String expression, @Nullable Map<String, String> namespaces, Object... args) {
|
||||
|
||||
this.bodySpec = spec;
|
||||
this.xpathHelper = initXpathHelper(expression, namespaces, args);
|
||||
}
|
||||
|
@ -52,6 +64,24 @@ public abstract class AbstractXpathAssertions<B> {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the body spec.
|
||||
*/
|
||||
protected B getBodySpec() {
|
||||
return this.bodySpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to provide access to response headers.
|
||||
*/
|
||||
protected abstract Optional<HttpHeaders> getResponseHeaders();
|
||||
|
||||
/**
|
||||
* Subclasses must implement this to provide access to the response content.
|
||||
*/
|
||||
protected abstract byte[] getContent();
|
||||
|
||||
|
||||
/**
|
||||
* Delegates to {@link XpathExpectationsHelper#assertString(byte[], String, String)}.
|
||||
*/
|
||||
|
@ -175,9 +205,6 @@ public abstract class AbstractXpathAssertions<B> {
|
|||
return super.hashCode();
|
||||
}
|
||||
|
||||
protected abstract Optional<HttpHeaders> getResponseHeaders();
|
||||
|
||||
protected abstract byte[] getContent();
|
||||
|
||||
/**
|
||||
* Lets us be able to use lambda expressions that could throw checked exceptions, since
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpRequest;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CookieAssertions}
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class CookieAssertionsTests {
|
||||
|
||||
private final ResponseCookie cookie = ResponseCookie.from("foo", "bar")
|
||||
.maxAge(Duration.ofMinutes(30))
|
||||
.domain("foo.com")
|
||||
.path("/foo")
|
||||
.secure(true)
|
||||
.httpOnly(true)
|
||||
.partitioned(true)
|
||||
.sameSite("Lax")
|
||||
.build();
|
||||
|
||||
private final CookieAssertions assertions = cookieAssertions(cookie);
|
||||
|
||||
|
||||
@Test
|
||||
void valueEquals() {
|
||||
assertions.valueEquals("foo", "bar");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.valueEquals("what?!", "bar"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.valueEquals("foo", "what?!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void value() {
|
||||
assertions.value("foo", equalTo("bar"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.value("foo", equalTo("what?!")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void exists() {
|
||||
assertions.exists("foo");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.exists("what?!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotExist() {
|
||||
assertions.doesNotExist("what?!");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.doesNotExist("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void maxAge() {
|
||||
assertions.maxAge("foo", Duration.ofMinutes(30));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.maxAge("foo", Duration.ofMinutes(29)));
|
||||
|
||||
assertions.maxAge("foo", equalTo(Duration.ofMinutes(30).getSeconds()));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.maxAge("foo", equalTo(Duration.ofMinutes(29).getSeconds())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void domain() {
|
||||
assertions.domain("foo", "foo.com");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.domain("foo", "what.com"));
|
||||
|
||||
assertions.domain("foo", equalTo("foo.com"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.domain("foo", equalTo("what.com")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void path() {
|
||||
assertions.path("foo", "/foo");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.path("foo", "/what"));
|
||||
|
||||
assertions.path("foo", equalTo("/foo"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.path("foo", equalTo("/what")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void secure() {
|
||||
assertions.secure("foo", true);
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.secure("foo", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpOnly() {
|
||||
assertions.httpOnly("foo", true);
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.httpOnly("foo", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void partitioned() {
|
||||
assertions.partitioned("foo", true);
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.partitioned("foo", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void sameSite() {
|
||||
assertions.sameSite("foo", "Lax");
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.sameSite("foo", "Strict"));
|
||||
}
|
||||
|
||||
|
||||
private CookieAssertions cookieAssertions(ResponseCookie cookie) {
|
||||
MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("/"));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
|
||||
response.getCookies().add(cookie.getName(), cookie);
|
||||
|
||||
ExchangeResult result = new ExchangeResult(
|
||||
request, response, Mono.empty(), Mono.empty(), Duration.ZERO, null, null);
|
||||
|
||||
return new CookieAssertions(result, mock());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpRequest;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link HeaderAssertions}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class HeaderAssertionTests {
|
||||
|
||||
@Test
|
||||
void valueEquals() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueEquals("foo", "bar");
|
||||
|
||||
// Missing header
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("what?!", "bar"));
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "what?!"));
|
||||
|
||||
// Wrong # of values
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar", "what?!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueEqualsWithMultipleValues() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
headers.add("foo", "baz");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueEquals("foo", "bar", "baz");
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar", "what?!"));
|
||||
|
||||
// Too few values
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueMatches() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueMatches("Content-Type", ".*UTF-8.*");
|
||||
|
||||
// Wrong pattern
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueMatches("Content-Type", ".*ISO-8859-1.*"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage("Response header " +
|
||||
"'Content-Type'=[application/json;charset=UTF-8] does not match " +
|
||||
"[.*ISO-8859-1.*]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueMatchesWithNonexistentHeader() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueMatches("Content-XYZ", ".*ISO-8859-1.*"))
|
||||
.withMessage("Response header 'Content-XYZ' not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valuesMatch() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "value1");
|
||||
headers.add("foo", "value2");
|
||||
headers.add("foo", "value3");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
assertions.valuesMatch("foo", "val.*1", "val.*2", "val.*3");
|
||||
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valuesMatch("foo", ".*", "val.*5"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage(
|
||||
"Response header 'foo' has fewer or more values [value1, value2, value3] " +
|
||||
"than number of patterns to match with [.*, val.*5]"));
|
||||
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valuesMatch("foo", ".*", "val.*5", ".*"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage(
|
||||
"Response header 'foo'[1]='value2' does not match 'val.*5'"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueMatcher() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
assertions.value("foo", containsString("a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valuesMatcher() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
headers.add("foo", "baz");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
assertions.values("foo", hasItems("bar", "baz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void exists() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.exists("Content-Type");
|
||||
|
||||
// Header should not exist
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.exists("Framework"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage("Response header 'Framework' does not exist"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotExist() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.doesNotExist("Framework");
|
||||
|
||||
// Existing header
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.doesNotExist("Content-Type"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage("Response header " +
|
||||
"'Content-Type' exists with value=[application/json;charset=UTF-8]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contentTypeCompatibleWith() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_XML);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.contentTypeCompatibleWith(MediaType.parseMediaType("application/*"));
|
||||
|
||||
// MediaTypes not compatible
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.contentTypeCompatibleWith(MediaType.TEXT_XML))
|
||||
.withMessage("Response header 'Content-Type'=[application/xml] is not compatible with [text/xml]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void cacheControl() {
|
||||
CacheControl control = CacheControl.maxAge(1, TimeUnit.HOURS).noTransform();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setCacheControl(control.getHeaderValue());
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.cacheControl(control);
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.cacheControl(CacheControl.noStore()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void expires() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
ZonedDateTime expires = ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
|
||||
headers.setExpires(expires);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
assertions.expires(expires.toInstant().toEpochMilli());
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.expires(expires.toInstant().toEpochMilli() + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void lastModified() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
ZonedDateTime lastModified = ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
|
||||
headers.setLastModified(lastModified.toInstant().toEpochMilli());
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
assertions.lastModified(lastModified.toInstant().toEpochMilli());
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.lastModified(lastModified.toInstant().toEpochMilli() + 1));
|
||||
}
|
||||
|
||||
private HeaderAssertions headerAssertions(HttpHeaders responseHeaders) {
|
||||
MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("/"));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK);
|
||||
response.getHeaders().putAll(responseHeaders);
|
||||
|
||||
ExchangeResult result = new ExchangeResult(
|
||||
request, response, Mono.empty(), Mono.empty(), Duration.ZERO, null, null);
|
||||
|
||||
return new HeaderAssertions(result, mock());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.reactive.server;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpRequest;
|
||||
import org.springframework.mock.http.client.reactive.MockClientHttpResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link StatusAssertions}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class StatusAssertionTests {
|
||||
|
||||
@Test
|
||||
void isEqualTo() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.isEqualTo(HttpStatus.CONFLICT);
|
||||
assertions.isEqualTo(409);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(HttpStatus.REQUEST_TIMEOUT));
|
||||
|
||||
// Wrong status value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(408));
|
||||
}
|
||||
|
||||
@Test // gh-23630, gh-29283
|
||||
void isEqualToWithCustomStatus() {
|
||||
StatusAssertions assertions = statusAssertions(600);
|
||||
|
||||
// Success
|
||||
// assertions.isEqualTo(600);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(HttpStatus.REQUEST_TIMEOUT));
|
||||
|
||||
// Wrong status value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(408));
|
||||
}
|
||||
|
||||
@Test
|
||||
void reasonEquals() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.reasonEquals("Conflict");
|
||||
|
||||
// Wrong reason
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.reasonEquals("Request Timeout"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries1xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONTINUE);
|
||||
|
||||
// Success
|
||||
assertions.is1xxInformational();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(assertions::is2xxSuccessful);
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries2xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.OK);
|
||||
|
||||
// Success
|
||||
assertions.is2xxSuccessful();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(assertions::is5xxServerError);
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries3xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.PERMANENT_REDIRECT);
|
||||
|
||||
// Success
|
||||
assertions.is3xxRedirection();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(assertions::is2xxSuccessful);
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries4xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.BAD_REQUEST);
|
||||
|
||||
// Success
|
||||
assertions.is4xxClientError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(assertions::is2xxSuccessful);
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries5xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
// Success
|
||||
assertions.is5xxServerError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(assertions::is2xxSuccessful);
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesStatusValue() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.value(equalTo(409));
|
||||
assertions.value(greaterThan(400));
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.value(equalTo(200)));
|
||||
}
|
||||
|
||||
@Test // gh-26658
|
||||
void matchesCustomStatusValue() {
|
||||
statusAssertions(600).value(equalTo(600));
|
||||
}
|
||||
|
||||
|
||||
private StatusAssertions statusAssertions(HttpStatus status) {
|
||||
return statusAssertions(status.value());
|
||||
}
|
||||
|
||||
private StatusAssertions statusAssertions(int status) {
|
||||
MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, URI.create("/"));
|
||||
MockClientHttpResponse response = new MockClientHttpResponse(status);
|
||||
|
||||
ExchangeResult result = new ExchangeResult(
|
||||
request, response, Mono.empty(), Mono.empty(), Duration.ZERO, null, null);
|
||||
|
||||
return new StatusAssertions(result, mock());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.servlet.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link StatusAssertions}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
*/
|
||||
class StatusAssertionTests {
|
||||
|
||||
@Test
|
||||
void isEqualTo() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.isEqualTo(HttpStatus.CONFLICT);
|
||||
assertions.isEqualTo(409);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(HttpStatus.REQUEST_TIMEOUT));
|
||||
|
||||
// Wrong status value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.isEqualTo(408));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWithCustomStatus() {
|
||||
StatusAssertions assertions = statusAssertions(600);
|
||||
|
||||
// Success
|
||||
assertions.isEqualTo(600);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(601).isEqualTo(600));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void reasonEquals() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.reasonEquals("Conflict");
|
||||
|
||||
// Wrong reason
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).reasonEquals("Conflict"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries1xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONTINUE);
|
||||
|
||||
// Success
|
||||
assertions.is1xxInformational();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.OK).is1xxInformational());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries2xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.OK);
|
||||
|
||||
// Success
|
||||
assertions.is2xxSuccessful();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is2xxSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries3xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.PERMANENT_REDIRECT);
|
||||
|
||||
// Success
|
||||
assertions.is3xxRedirection();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is3xxRedirection());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries4xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.BAD_REQUEST);
|
||||
|
||||
// Success
|
||||
assertions.is4xxClientError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is4xxClientError());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries5xx() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
// Success
|
||||
assertions.is5xxServerError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
statusAssertions(HttpStatus.OK).is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesStatusValue() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.value(equalTo(409));
|
||||
assertions.value(greaterThan(400));
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.value(equalTo(200)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesCustomStatusValue() {
|
||||
statusAssertions(600).value(equalTo(600));
|
||||
}
|
||||
|
||||
@Test
|
||||
void consumesStatusValue() {
|
||||
StatusAssertions assertions = statusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.value((Integer value) -> assertThat(value).isEqualTo(409));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsAccepted() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.ACCEPTED).isAccepted();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isAccepted());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsNoContent() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.NO_CONTENT).isNoContent();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isNoContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsFound() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.FOUND).isFound();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsSeeOther() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.SEE_OTHER).isSeeOther();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isSeeOther());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsNotModified() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.NOT_MODIFIED).isNotModified();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isNotModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsTemporaryRedirect() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.TEMPORARY_REDIRECT).isTemporaryRedirect();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isTemporaryRedirect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsPermanentRedirect() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.PERMANENT_REDIRECT).isPermanentRedirect();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isPermanentRedirect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsUnauthorized() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.UNAUTHORIZED).isUnauthorized();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsForbidden() {
|
||||
// Success
|
||||
statusAssertions(HttpStatus.FORBIDDEN).isForbidden();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> statusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isForbidden());
|
||||
}
|
||||
|
||||
private StatusAssertions statusAssertions(HttpStatus status) {
|
||||
return statusAssertions(status.value());
|
||||
}
|
||||
|
||||
private StatusAssertions statusAssertions(int status) {
|
||||
try {
|
||||
RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse response = mock();
|
||||
when(response.getStatusCode()).thenReturn(HttpStatusCode.valueOf(status));
|
||||
when(response.getHeaders()).thenReturn(new HttpHeaders());
|
||||
ExchangeResult result = new ExchangeResult(new MockClientHttpRequest(), response, null);
|
||||
return new StatusAssertions(result, mock());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new AssertionError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,34 +14,37 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.servlet.client;
|
||||
package org.springframework.test.web.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link CookieAssertions}
|
||||
* Tests for {@link AbstractCookieAssertions}.
|
||||
*
|
||||
* @author Rob Worsnop
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class CookieAssertionsTests {
|
||||
|
||||
private final ResponseCookie cookie = ResponseCookie.from("foo", "bar")
|
||||
private TestCookieAssertions assertions;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws IOException {
|
||||
|
||||
ResponseCookie cookie = ResponseCookie.from("foo", "bar")
|
||||
.maxAge(Duration.ofMinutes(30))
|
||||
.domain("foo.com")
|
||||
.path("/foo")
|
||||
|
@ -51,14 +54,10 @@ public class CookieAssertionsTests {
|
|||
.sameSite("Lax")
|
||||
.build();
|
||||
|
||||
private CookieAssertions assertions;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws IOException {
|
||||
this.assertions = cookieAssertions(cookie);
|
||||
this.assertions = initCookieAssertions(cookie);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void valueEquals() {
|
||||
assertions.valueEquals("foo", "bar");
|
||||
|
@ -75,7 +74,8 @@ public class CookieAssertionsTests {
|
|||
@Test
|
||||
void valueConsumer() {
|
||||
assertions.value("foo", input -> assertThat(input).isEqualTo("bar"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.value("foo", input -> assertThat(input).isEqualTo("what?!")));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.value("foo", input -> assertThat(input).isEqualTo("what?!")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -143,15 +143,31 @@ public class CookieAssertionsTests {
|
|||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.sameSite("foo", "Strict"));
|
||||
}
|
||||
|
||||
private TestCookieAssertions initCookieAssertions(ResponseCookie cookie) throws IOException {
|
||||
return new TestCookieAssertions(cookie);
|
||||
}
|
||||
|
||||
private CookieAssertions cookieAssertions(ResponseCookie cookie) throws IOException {
|
||||
RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse response = mock();
|
||||
var headers = new HttpHeaders();
|
||||
headers.set(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||
when(response.getHeaders()).thenReturn(headers);
|
||||
when(response.getStatusCode()).thenReturn(HttpStatusCode.valueOf(200));
|
||||
ExchangeResult result = new ExchangeResult(new MockClientHttpRequest(), response, null);
|
||||
return new CookieAssertions(result, mock());
|
||||
|
||||
private static class TestCookieAssertions extends AbstractCookieAssertions<TestExchangeResult, Object> {
|
||||
|
||||
TestCookieAssertions(ResponseCookie cookie) {
|
||||
super(new TestExchangeResult(cookie), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValueMap<String, ResponseCookie> getResponseCookies() {
|
||||
ResponseCookie cookie = getExchangeResult().cookie();
|
||||
return MultiValueMap.fromSingleValue(Map.of(cookie.getName(), cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
assertion.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private record TestExchangeResult(ResponseCookie cookie) {
|
||||
}
|
||||
|
||||
}
|
|
@ -14,9 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.servlet.client;
|
||||
package org.springframework.test.web.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
@ -27,21 +26,17 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.mockito.BDDMockito.mock;
|
||||
import static org.mockito.BDDMockito.when;
|
||||
|
||||
/**
|
||||
* Tests for {@link HeaderAssertions}.
|
||||
* Tests for {@link AbstractHeaderAssertions}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Rob Worsnop
|
||||
*/
|
||||
class HeaderAssertionTests {
|
||||
|
@ -51,7 +46,7 @@ class HeaderAssertionTests {
|
|||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
headers.add("age", "22");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueEquals("foo", "bar");
|
||||
|
@ -60,16 +55,16 @@ class HeaderAssertionTests {
|
|||
assertions.valueEquals("age", 22);
|
||||
|
||||
// Missing header
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("what?!", "bar"));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEquals("what?!", "bar"));
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "what?!"));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEquals("foo", "what?!"));
|
||||
|
||||
// Wrong # of values
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar", "what?!"));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEquals("foo", "bar", "what?!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -77,25 +72,25 @@ class HeaderAssertionTests {
|
|||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
headers.add("foo", "baz");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueEquals("foo", "bar", "baz");
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar", "what?!"));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEquals("foo", "bar", "what?!"));
|
||||
|
||||
// Too few values
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEquals("foo", "bar"));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEquals("foo", "bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueMatches() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.valueMatches("Content-Type", ".*UTF-8.*");
|
||||
|
@ -112,7 +107,7 @@ class HeaderAssertionTests {
|
|||
void valueMatchesWithNonexistentHeader() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueMatches("Content-XYZ", ".*ISO-8859-1.*"))
|
||||
|
@ -125,7 +120,7 @@ class HeaderAssertionTests {
|
|||
headers.add("foo", "value1");
|
||||
headers.add("foo", "value2");
|
||||
headers.add("foo", "value3");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
assertions.valuesMatch("foo", "val.*1", "val.*2", "val.*3");
|
||||
|
||||
|
@ -145,7 +140,7 @@ class HeaderAssertionTests {
|
|||
void valueMatcher() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
assertions.value("foo", containsString("a"));
|
||||
}
|
||||
|
@ -155,7 +150,7 @@ class HeaderAssertionTests {
|
|||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("foo", "bar");
|
||||
headers.add("foo", "baz");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
assertions.values("foo", hasItems("bar", "baz"));
|
||||
}
|
||||
|
@ -164,14 +159,14 @@ class HeaderAssertionTests {
|
|||
void exists() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.exists("Content-Type");
|
||||
|
||||
// Header should not exist
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.exists("Framework"))
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.exists("Framework"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage("Response header 'Framework' does not exist"));
|
||||
}
|
||||
|
||||
|
@ -179,14 +174,14 @@ class HeaderAssertionTests {
|
|||
void doesNotExist() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.doesNotExist("Framework");
|
||||
|
||||
// Existing header
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.doesNotExist("Content-Type"))
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.doesNotExist("Content-Type"))
|
||||
.satisfies(ex -> assertThat(ex).hasMessage("Response header " +
|
||||
"'Content-Type' exists with value=[application/json;charset=UTF-8]"));
|
||||
}
|
||||
|
@ -195,7 +190,7 @@ class HeaderAssertionTests {
|
|||
void contentTypeCompatibleWith() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_XML);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.contentTypeCompatibleWith(MediaType.parseMediaType("application/*"));
|
||||
|
@ -211,14 +206,13 @@ class HeaderAssertionTests {
|
|||
void location() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setLocation(URI.create("http://localhost:8080/"));
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.location("http://localhost:8080/");
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.location("http://localhost:8081/"));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.location("http://localhost:8081/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -227,51 +221,50 @@ class HeaderAssertionTests {
|
|||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setCacheControl(control.getHeaderValue());
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
|
||||
// Success
|
||||
assertions.cacheControl(control);
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.cacheControl(CacheControl.noStore()));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.cacheControl(CacheControl.noStore()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contentDisposition() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentDispositionFormData("foo", "bar");
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.contentDisposition(ContentDisposition.formData().name("foo").filename("bar").build());
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.contentDisposition(ContentDisposition.attachment().build()));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.contentDisposition(ContentDisposition.attachment().build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contentLength() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentLength(100);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.contentLength(100);
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.contentLength(200));
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.contentLength(200));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contentType() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.contentType(MediaType.APPLICATION_JSON);
|
||||
assertions.contentType("application/json");
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.contentType(MediaType.APPLICATION_XML));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.contentType(MediaType.APPLICATION_XML));
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,12 +273,12 @@ class HeaderAssertionTests {
|
|||
HttpHeaders headers = new HttpHeaders();
|
||||
ZonedDateTime expires = ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
|
||||
headers.setExpires(expires);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.expires(expires.toInstant().toEpochMilli());
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.expires(expires.toInstant().toEpochMilli() + 1));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.expires(expires.toInstant().toEpochMilli() + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -293,37 +286,45 @@ class HeaderAssertionTests {
|
|||
HttpHeaders headers = new HttpHeaders();
|
||||
ZonedDateTime lastModified = ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"));
|
||||
headers.setLastModified(lastModified.toInstant().toEpochMilli());
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.lastModified(lastModified.toInstant().toEpochMilli());
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.lastModified(lastModified.toInstant().toEpochMilli() + 1));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.lastModified(lastModified.toInstant().toEpochMilli() + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsDate() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setDate("foo", 1000);
|
||||
HeaderAssertions assertions = headerAssertions(headers);
|
||||
TestHeaderAssertions assertions = new TestHeaderAssertions(headers);
|
||||
assertions.valueEqualsDate("foo", 1000);
|
||||
|
||||
// Wrong value
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() ->
|
||||
assertions.valueEqualsDate("foo", 2000));
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.valueEqualsDate("foo", 2000));
|
||||
}
|
||||
|
||||
private HeaderAssertions headerAssertions(HttpHeaders responseHeaders) {
|
||||
try {
|
||||
RestClient.RequestHeadersSpec.ConvertibleClientHttpResponse response = mock();
|
||||
when(response.getStatusCode()).thenReturn(HttpStatusCode.valueOf(200));
|
||||
when(response.getHeaders()).thenReturn(responseHeaders);
|
||||
ExchangeResult result = new ExchangeResult(new MockClientHttpRequest(), response, null);
|
||||
return new HeaderAssertions(result, mock());
|
||||
|
||||
private static class TestHeaderAssertions extends AbstractHeaderAssertions<TestExchangeResult, Object> {
|
||||
|
||||
TestHeaderAssertions(HttpHeaders headers) {
|
||||
super(new TestExchangeResult(headers), "");
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
|
||||
@Override
|
||||
protected HttpHeaders getResponseHeaders() {
|
||||
return getExchangeResult().headers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
assertion.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private record TestExchangeResult(HttpHeaders headers) {}
|
||||
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* Copyright 2002-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.web.support;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
/**
|
||||
* Tests for {@link AbstractStatusAssertions}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Rob Worsnop
|
||||
*/
|
||||
class StatusAssertionTests {
|
||||
|
||||
@Test
|
||||
void isEqualTo() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.isEqualTo(HttpStatus.CONFLICT);
|
||||
assertions.isEqualTo(409);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.isEqualTo(HttpStatus.REQUEST_TIMEOUT));
|
||||
|
||||
// Wrong status value
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> assertions.isEqualTo(408));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWithCustomStatus() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(600);
|
||||
|
||||
// Success
|
||||
assertions.isEqualTo(600);
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(601).isEqualTo(600));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void reasonEquals() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.reasonEquals("Conflict");
|
||||
|
||||
// Wrong reason
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).reasonEquals("Conflict"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries1xx() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.CONTINUE);
|
||||
|
||||
// Success
|
||||
assertions.is1xxInformational();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.OK).is1xxInformational());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries2xx() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.OK);
|
||||
|
||||
// Success
|
||||
assertions.is2xxSuccessful();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is2xxSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries3xx() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.PERMANENT_REDIRECT);
|
||||
|
||||
// Success
|
||||
assertions.is3xxRedirection();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is3xxRedirection());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries4xx() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.BAD_REQUEST);
|
||||
|
||||
// Success
|
||||
assertions.is4xxClientError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).is4xxClientError());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusSeries5xx() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
|
||||
// Success
|
||||
assertions.is5xxServerError();
|
||||
|
||||
// Wrong series
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.OK).is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesStatusValue() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.value(equalTo(409));
|
||||
assertions.value(greaterThan(400));
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> assertions.value(equalTo(200)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesCustomStatusValue() {
|
||||
new TestStatusAssertions(600).value(equalTo(600));
|
||||
}
|
||||
|
||||
@Test
|
||||
void consumesStatusValue() {
|
||||
TestStatusAssertions assertions = new TestStatusAssertions(HttpStatus.CONFLICT);
|
||||
|
||||
// Success
|
||||
assertions.value((Integer value) -> assertThat(value).isEqualTo(409));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsAccepted() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.ACCEPTED).isAccepted();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isAccepted());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsNoContent() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.NO_CONTENT).isNoContent();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isNoContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsFound() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.FOUND).isFound();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsSeeOther() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.SEE_OTHER).isSeeOther();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isSeeOther());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsNotModified() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.NOT_MODIFIED).isNotModified();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isNotModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsTemporaryRedirect() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.TEMPORARY_REDIRECT).isTemporaryRedirect();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isTemporaryRedirect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsPermanentRedirect() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.PERMANENT_REDIRECT).isPermanentRedirect();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isPermanentRedirect());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsUnauthorized() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.UNAUTHORIZED).isUnauthorized();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusIsForbidden() {
|
||||
// Success
|
||||
new TestStatusAssertions(HttpStatus.FORBIDDEN).isForbidden();
|
||||
|
||||
// Wrong status
|
||||
assertThatExceptionOfType(AssertionError.class)
|
||||
.isThrownBy(() -> new TestStatusAssertions(HttpStatus.INTERNAL_SERVER_ERROR).isForbidden());
|
||||
}
|
||||
|
||||
|
||||
private static class TestStatusAssertions extends AbstractStatusAssertions<TestExchangeResult, Object> {
|
||||
|
||||
TestStatusAssertions(HttpStatus status) {
|
||||
this(status.value());
|
||||
}
|
||||
|
||||
TestStatusAssertions(int status) {
|
||||
super(new TestExchangeResult(HttpStatusCode.valueOf(status)), "");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpStatusCode getStatus() {
|
||||
return getExchangeResult().status();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertWithDiagnostics(Runnable assertion) {
|
||||
assertion.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private record TestExchangeResult(HttpStatusCode status) {
|
||||
}
|
||||
|
||||
}
|
|
@ -98,7 +98,7 @@
|
|||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]aot[\\/]samples[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/]junit[\\/]jupiter[\\/]web[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]util[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/](client|reactive|servlet)[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]web[\\/](client|reactive|servlet|support)[\\/].+Tests" checks="IllegalImport" id="bannedHamcrestImports"/>
|
||||
<suppress files="src[\\/]test[\\/]java[\\/]org[\\/]springframework[\\/]test[\\/]context[\\/](aot|junit4)" checks="SpringJUnit5"/>
|
||||
<suppress files="org[\\/]springframework[\\/]test[\\/]context[\\/].+[\\/](ExpectedExceptionSpringRunnerTests|StandardJUnit4FeaturesTests|ProgrammaticTxMgmtTestNGTests)" checks="RegexpSinglelineJava" id="expectedExceptionAnnotation"/>
|
||||
|
||||
|
|
Loading…
Reference in New Issue