-
Notifications
You must be signed in to change notification settings - Fork 38.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds AssertJ compatible assertions for cookies See gh-21178 Co-authored-by: Brian Clozel <[email protected]>
- Loading branch information
Showing
2 changed files
with
355 additions
and
0 deletions.
There are no files selected for viewing
173 changes: 173 additions & 0 deletions
173
spring-test/src/main/java/org/springframework/test/web/servlet/assertj/CookieMapAssert.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright 2002-2024 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.assertj; | ||
|
||
import java.time.Duration; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
import java.util.function.Consumer; | ||
|
||
import jakarta.servlet.http.Cookie; | ||
import org.assertj.core.api.AbstractMapAssert; | ||
import org.assertj.core.api.Assertions; | ||
|
||
/** | ||
* AssertJ {@link org.assertj.core.api.Assert assertions} that can be applied to | ||
* {@link Cookie cookies}. | ||
* | ||
* @author Brian Clozel | ||
* @author Stephane Nicoll | ||
* @since 6.2 | ||
*/ | ||
public class CookieMapAssert extends AbstractMapAssert<CookieMapAssert, Map<String, Cookie>, String, Cookie> { | ||
|
||
public CookieMapAssert(Cookie[] actual) { | ||
super(mapCookies(actual), CookieMapAssert.class); | ||
as("Cookies"); | ||
} | ||
|
||
private static Map<String, Cookie> mapCookies(Cookie[] cookies) { | ||
Map<String, Cookie> map = new LinkedHashMap<>(); | ||
for (Cookie cookie : cookies) { | ||
map.putIfAbsent(cookie.getName(), cookie); | ||
} | ||
return map; | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given {@code name}. | ||
* @param name the name of an expected cookie | ||
* @see #containsKey | ||
*/ | ||
public CookieMapAssert containsCookie(String name) { | ||
return containsKey(name); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain the cookies with the given | ||
* {@code names}. | ||
* @param names the names of expected cookies | ||
* @see #containsKeys | ||
*/ | ||
public CookieMapAssert containsCookies(String... names) { | ||
return containsKeys(names); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies do not contain a cookie with the | ||
* given {@code name}. | ||
* @param name the name of a cookie that should not be present | ||
* @see #doesNotContainKey | ||
*/ | ||
public CookieMapAssert doesNotContainCookie(String name) { | ||
return doesNotContainKey(name); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies do not contain any of the cookies with | ||
* the given {@code names}. | ||
* @param names the names of cookies that should not be present | ||
* @see #doesNotContainKeys | ||
*/ | ||
public CookieMapAssert doesNotContainCookies(String... names) { | ||
return doesNotContainKeys(names); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} that satisfy given {@code cookieRequirements}. | ||
* the specified names. | ||
* @param name the name of an expected cookie | ||
* @param cookieRequirements the requirements for the cookie | ||
*/ | ||
public CookieMapAssert hasCookieSatisfying(String name, Consumer<Cookie> cookieRequirements) { | ||
return hasEntrySatisfying(name, cookieRequirements); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#getValue() value} is equal to the | ||
* given one. | ||
* @param name the name of the cookie | ||
* @param expected the expected value of the cookie | ||
*/ | ||
public CookieMapAssert hasValue(String name, String expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(cookie.getValue()).isEqualTo(expected)); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#getMaxAge() max age} is equal to | ||
* the given one. | ||
* @param name the name of the cookie | ||
* @param expected the expected max age of the cookie | ||
*/ | ||
public CookieMapAssert hasMaxAge(String name, Duration expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(Duration.ofSeconds(cookie.getMaxAge())).isEqualTo(expected)); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#getPath() path} is equal to | ||
* the given one. | ||
* @param name the name of the cookie | ||
* @param expected the expected path of the cookie | ||
*/ | ||
public CookieMapAssert hasPath(String name, String expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(cookie.getPath()).isEqualTo(expected)); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#getDomain() domain} is equal to | ||
* the given one. | ||
* @param name the name of the cookie | ||
* @param expected the expected path of the cookie | ||
*/ | ||
public CookieMapAssert hasDomain(String name, String expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(cookie.getDomain()).isEqualTo(expected)); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#getSecure() secure flag} is equal | ||
* to the given one. | ||
* @param name the name of the cookie | ||
* @param expected whether the cookie is secure | ||
*/ | ||
public CookieMapAssert isSecure(String name, boolean expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(cookie.getSecure()).isEqualTo(expected)); | ||
} | ||
|
||
/** | ||
* Verify that the actual cookies contain a cookie with the given | ||
* {@code name} whose {@linkplain Cookie#isHttpOnly() http only flag} is | ||
* equal to the given one. | ||
* @param name the name of the cookie | ||
* @param expected whether the cookie is http only | ||
*/ | ||
public CookieMapAssert isHttpOnly(String name, boolean expected) { | ||
return hasCookieSatisfying(name, cookie -> | ||
Assertions.assertThat(cookie.isHttpOnly()).isEqualTo(expected)); | ||
} | ||
|
||
} |
182 changes: 182 additions & 0 deletions
182
...test/src/test/java/org/springframework/test/web/servlet/assertj/CookieMapAssertTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* | ||
* Copyright 2002-2024 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.assertj; | ||
|
||
|
||
import java.time.Duration; | ||
import java.util.List; | ||
|
||
import jakarta.servlet.http.Cookie; | ||
import org.assertj.core.api.AssertProvider; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||
|
||
/** | ||
* Tests for {@link CookieMapAssert}. | ||
* | ||
* @author Brian Clozel | ||
*/ | ||
class CookieMapAssertTests { | ||
|
||
static Cookie[] cookies; | ||
|
||
@BeforeAll | ||
static void setup() { | ||
Cookie framework = new Cookie("framework", "spring"); | ||
framework.setSecure(true); | ||
framework.setHttpOnly(true); | ||
Cookie age = new Cookie("age", "value"); | ||
age.setMaxAge(1200); | ||
Cookie domain = new Cookie("domain", "value"); | ||
domain.setDomain("spring.io"); | ||
Cookie path = new Cookie("path", "value"); | ||
path.setPath("/spring"); | ||
cookies = List.of(framework, age, domain, path).toArray(new Cookie[0]); | ||
} | ||
|
||
@Test | ||
void containsCookieWhenCookieExistsShouldPass() { | ||
assertThat(forCookies()).containsCookie("framework"); | ||
} | ||
|
||
@Test | ||
void containsCookieWhenCookieMissingShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).containsCookie("missing")); | ||
} | ||
|
||
@Test | ||
void containsCookiesWhenCookiesExistShouldPass() { | ||
assertThat(forCookies()).containsCookies("framework", "age"); | ||
} | ||
|
||
@Test | ||
void containsCookiesWhenCookieMissingShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).containsCookies("framework", "missing")); | ||
} | ||
|
||
@Test | ||
void doesNotContainCookieWhenCookieMissingShouldPass() { | ||
assertThat(forCookies()).doesNotContainCookie("missing"); | ||
} | ||
|
||
@Test | ||
void doesNotContainCookieWhenCookieExistsShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).doesNotContainCookie("framework")); | ||
} | ||
|
||
@Test | ||
void doesNotContainCookiesWhenCookiesMissingShouldPass() { | ||
assertThat(forCookies()).doesNotContainCookies("missing", "missing2"); | ||
} | ||
|
||
@Test | ||
void doesNotContainCookiesWhenAtLeastOneCookieExistShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).doesNotContainCookies("missing", "framework")); | ||
} | ||
|
||
@Test | ||
void hasValueEqualsWhenCookieValueMatchesShouldPass() { | ||
assertThat(forCookies()).hasValue("framework", "spring"); | ||
} | ||
|
||
@Test | ||
void hasValueEqualsWhenCookieValueDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).hasValue("framework", "other")); | ||
} | ||
|
||
@Test | ||
void hasCookieSatisfyingWhenCookieValueMatchesShouldPass() { | ||
assertThat(forCookies()).hasCookieSatisfying("framework", cookie -> | ||
assertThat(cookie.getValue()).startsWith("spr")); | ||
} | ||
|
||
@Test | ||
void hasCookieSatisfyingWhenCookieValueDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).hasCookieSatisfying("framework", cookie -> | ||
assertThat(cookie.getValue()).startsWith("not"))); | ||
} | ||
|
||
@Test | ||
void hasMaxAgeWhenCookieAgeMatchesShouldPass() { | ||
assertThat(forCookies()).hasMaxAge("age", Duration.ofMinutes(20)); | ||
} | ||
|
||
@Test | ||
void hasMaxAgeWhenCookieAgeDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).hasMaxAge("age", Duration.ofMinutes(30))); | ||
} | ||
|
||
@Test | ||
void pathWhenCookiePathMatchesShouldPass() { | ||
assertThat(forCookies()).hasPath("path", "/spring"); | ||
} | ||
|
||
@Test | ||
void pathWhenCookiePathDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).hasPath("path", "/other")); | ||
} | ||
|
||
@Test | ||
void hasDomainWhenCookieDomainMatchesShouldPass() { | ||
assertThat(forCookies()).hasDomain("domain", "spring.io"); | ||
} | ||
|
||
@Test | ||
void hasDomainWhenCookieDomainDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).hasDomain("domain", "example.org")); | ||
} | ||
|
||
@Test | ||
void isSecureWhenCookieSecureMatchesShouldPass() { | ||
assertThat(forCookies()).isSecure("framework", true); | ||
} | ||
|
||
@Test | ||
void isSecureWhenCookieSecureDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).isSecure("domain", true)); | ||
} | ||
|
||
@Test | ||
void isHttpOnlyWhenCookieHttpOnlyMatchesShouldPass() { | ||
assertThat(forCookies()).isHttpOnly("framework", true); | ||
} | ||
|
||
@Test | ||
void isHttpOnlyWhenCookieHttpOnlyDiffersShouldFail() { | ||
assertThatExceptionOfType(AssertionError.class).isThrownBy(() -> | ||
assertThat(forCookies()).isHttpOnly("domain", true)); | ||
} | ||
|
||
|
||
private AssertProvider<CookieMapAssert> forCookies() { | ||
return () -> new CookieMapAssert(cookies); | ||
} | ||
|
||
} |