5 changed files with 370 additions and 1 deletions
@ -0,0 +1,220 @@
@@ -0,0 +1,220 @@
|
||||
/* |
||||
* Copyright 2002-2020 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.time.Duration; |
||||
import java.util.function.Consumer; |
||||
|
||||
import org.hamcrest.Matcher; |
||||
import org.hamcrest.MatcherAssert; |
||||
|
||||
import org.springframework.http.ResponseCookie; |
||||
import org.springframework.test.util.AssertionErrors; |
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat; |
||||
|
||||
/** |
||||
* Assertions on cookies of the response. |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class CookieAssertions { |
||||
|
||||
private final ExchangeResult exchangeResult; |
||||
|
||||
private final WebTestClient.ResponseSpec responseSpec; |
||||
|
||||
|
||||
public CookieAssertions(ExchangeResult exchangeResult, WebTestClient.ResponseSpec responseSpec) { |
||||
this.exchangeResult = exchangeResult; |
||||
this.responseSpec = responseSpec; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Expect a header with the given name to match the specified values. |
||||
*/ |
||||
public WebTestClient.ResponseSpec valueEquals(String name, String value) { |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name); |
||||
AssertionErrors.assertEquals(message, value, getCookie(name).getValue()); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert the first value of the response cookie with a Hamcrest {@link Matcher}. |
||||
*/ |
||||
public WebTestClient.ResponseSpec value(String name, Matcher<? super String> matcher) { |
||||
String value = getCookie(name).getValue(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name); |
||||
MatcherAssert.assertThat(message, value, matcher); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Consume the value of the response cookie. |
||||
*/ |
||||
public WebTestClient.ResponseSpec value(String name, Consumer<String> consumer) { |
||||
String value = getCookie(name).getValue(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> consumer.accept(value)); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Expect that the cookie with the given name is present. |
||||
*/ |
||||
public WebTestClient.ResponseSpec exists(String name) { |
||||
getCookie(name); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Expect that the cookie with the given name is not present. |
||||
*/ |
||||
public WebTestClient.ResponseSpec doesNotExist(String name) { |
||||
ResponseCookie cookie = this.exchangeResult.getResponseCookies().getFirst(name); |
||||
if (cookie != null) { |
||||
String message = getMessage(name) + " exists with value=[" + cookie.getValue() + "]"; |
||||
this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(message)); |
||||
} |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's maxAge attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec maxAge(String name, Duration expected) { |
||||
Duration maxAge = getCookie(name).getMaxAge(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " maxAge"; |
||||
AssertionErrors.assertEquals(message, expected, maxAge); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's maxAge attribute with a Hamcrest {@link Matcher}. |
||||
*/ |
||||
public WebTestClient.ResponseSpec maxAge(String name, Matcher<? super Long> matcher) { |
||||
long maxAge = getCookie(name).getMaxAge().getSeconds(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " maxAge"; |
||||
assertThat(message, maxAge, matcher); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's path attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec path(String name, String expected) { |
||||
String path = getCookie(name).getPath(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " path"; |
||||
AssertionErrors.assertEquals(message, expected, path); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's path attribute with a Hamcrest {@link Matcher}. |
||||
*/ |
||||
public WebTestClient.ResponseSpec path(String name, Matcher<? super String> matcher) { |
||||
String path = getCookie(name).getPath(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " path"; |
||||
assertThat(message, path, matcher); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's domain attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec domain(String name, String expected) { |
||||
String path = getCookie(name).getDomain(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " domain"; |
||||
AssertionErrors.assertEquals(message, expected, path); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's domain attribute with a Hamcrest {@link Matcher}. |
||||
*/ |
||||
public WebTestClient.ResponseSpec domain(String name, Matcher<? super String> matcher) { |
||||
String domain = getCookie(name).getDomain(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " domain"; |
||||
assertThat(message, domain, matcher); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's secure attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec secure(String name, boolean expected) { |
||||
boolean isSecure = getCookie(name).isSecure(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " secure"; |
||||
AssertionErrors.assertEquals(message, expected, isSecure); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's httpOnly attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec httpOnly(String name, boolean expected) { |
||||
boolean isHttpOnly = getCookie(name).isHttpOnly(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " secure"; |
||||
AssertionErrors.assertEquals(message, expected, isHttpOnly); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
/** |
||||
* Assert a cookie's sameSite attribute. |
||||
*/ |
||||
public WebTestClient.ResponseSpec sameSite(String name, String expected) { |
||||
String sameSite = getCookie(name).getSameSite(); |
||||
this.exchangeResult.assertWithDiagnostics(() -> { |
||||
String message = getMessage(name) + " secure"; |
||||
AssertionErrors.assertEquals(message, expected, sameSite); |
||||
}); |
||||
return this.responseSpec; |
||||
} |
||||
|
||||
|
||||
private ResponseCookie getCookie(String name) { |
||||
ResponseCookie cookie = this.exchangeResult.getResponseCookies().getFirst(name); |
||||
if (cookie == null) { |
||||
String message = "No cookie with name '" + name + "'"; |
||||
this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.fail(message)); |
||||
} |
||||
return cookie; |
||||
} |
||||
|
||||
private String getMessage(String cookie) { |
||||
return "Response cookie '" + cookie + "'"; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,138 @@
@@ -0,0 +1,138 @@
|
||||
/* |
||||
* Copyright 2002-2020 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.MonoProcessor; |
||||
import reactor.core.publisher.Sinks; |
||||
|
||||
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; |
||||
|
||||
/** |
||||
* Unit tests for {@link CookieAssertions} |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class CookieAssertionTests { |
||||
|
||||
private final ResponseCookie cookie = ResponseCookie.from("foo", "bar") |
||||
.maxAge(Duration.ofMinutes(30)) |
||||
.domain("foo.com") |
||||
.path("/foo") |
||||
.secure(true) |
||||
.httpOnly(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 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); |
||||
|
||||
MonoProcessor<byte[]> emptyContent = MonoProcessor.fromSink(Sinks.one()); |
||||
emptyContent.onComplete(); |
||||
|
||||
ExchangeResult result = new ExchangeResult(request, response, emptyContent, emptyContent, Duration.ZERO, null, null); |
||||
return new CookieAssertions(result, mock(WebTestClient.ResponseSpec.class)); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue