Skip to content

Commit

Permalink
Add AssertJ support for cookies
Browse files Browse the repository at this point in the history
This commit adds AssertJ compatible assertions for cookies

See gh-21178

Co-authored-by: Brian Clozel <[email protected]>
  • Loading branch information
snicoll and bclozel committed Mar 15, 2024
1 parent 1cdbcc5 commit 555d4a6
Show file tree
Hide file tree
Showing 2 changed files with 355 additions and 0 deletions.
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));
}

}
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);
}

}

0 comments on commit 555d4a6

Please sign in to comment.