Skip to content

Commit 9ea4569

Browse files
committed
Support cookie comments in MockHttpServletResponse and MockCookie
Prior to this commit, if a cookie was added to MockHttpServletResponse, the comment attribute was not included in the generated Set-Cookie header. In addition, MockCookie.parse(String) did not support the Comment attribute. This commit addresses both of these issues. Closes gh-28730
1 parent fe2b858 commit 9ea4569

File tree

6 files changed

+89
-16
lines changed

6 files changed

+89
-16
lines changed

spring-test/src/main/java/org/springframework/mock/web/MockCookie.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -142,6 +142,9 @@ else if (StringUtils.startsWithIgnoreCase(attribute, "HttpOnly")) {
142142
else if (StringUtils.startsWithIgnoreCase(attribute, "SameSite")) {
143143
cookie.setSameSite(extractAttributeValue(attribute, setCookieHeader));
144144
}
145+
else if (StringUtils.startsWithIgnoreCase(attribute, "Comment")) {
146+
cookie.setComment(extractAttributeValue(attribute, setCookieHeader));
147+
}
145148
}
146149
return cookie;
147150
}

spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -450,6 +450,9 @@ else if (expires != null) {
450450
buf.append("; SameSite=").append(mockCookie.getSameSite());
451451
}
452452
}
453+
if (StringUtils.hasText(cookie.getComment())) {
454+
buf.append("; Comment=").append(cookie.getComment());
455+
}
453456
return buf.toString();
454457
}
455458

spring-test/src/test/java/org/springframework/mock/web/MockCookieTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -67,7 +67,7 @@ void parseHeaderWithoutAttributes() {
6767

6868
@Test
6969
void parseHeaderWithAttributes() {
70-
MockCookie cookie = MockCookie.parse("SESSION=123; Domain=example.com; Max-Age=60; " +
70+
MockCookie cookie = MockCookie.parse("SESSION=123; Comment=Session Cookie; Domain=example.com; Max-Age=60; " +
7171
"Expires=Tue, 8 Oct 2019 19:50:00 GMT; Path=/; Secure; HttpOnly; SameSite=Lax");
7272

7373
assertCookie(cookie, "SESSION", "123");
@@ -79,6 +79,7 @@ void parseHeaderWithAttributes() {
7979
assertThat(cookie.getExpires()).isEqualTo(ZonedDateTime.parse("Tue, 8 Oct 2019 19:50:00 GMT",
8080
DateTimeFormatter.RFC_1123_DATE_TIME));
8181
assertThat(cookie.getSameSite()).isEqualTo("Lax");
82+
assertThat(cookie.getComment()).isEqualTo("Session Cookie");
8283
}
8384

8485
@ParameterizedTest

spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
3535

3636
import static org.assertj.core.api.Assertions.assertThat;
3737
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
38+
import static org.assertj.core.api.InstanceOfAssertFactories.type;
3839
import static org.assertj.core.api.SoftAssertions.assertSoftly;
3940
import static org.springframework.http.HttpHeaders.CONTENT_LANGUAGE;
4041
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
@@ -258,7 +259,7 @@ void httpHeaderNameCasingIsPreserved() throws Exception {
258259

259260
@Test
260261
void cookies() {
261-
Cookie cookie = new Cookie("foo", "bar");
262+
Cookie cookie = new MockCookie("foo", "bar");
262263
cookie.setPath("/path");
263264
cookie.setDomain("example.com");
264265
cookie.setMaxAge(0);
@@ -474,6 +475,23 @@ void setCookieHeaderWithZeroExpiresAttribute() {
474475
assertThat(header).startsWith("SESSION=123; Path=/; Max-Age=100; Expires=");
475476
}
476477

478+
/**
479+
* @since 5.3.22
480+
*/
481+
@Test
482+
void setCookieHeaderWithComment() {
483+
response.setHeader(SET_COOKIE, "SESSION=123;Comment=Test Comment;Path=/");
484+
485+
assertThat(response.getHeader(SET_COOKIE)).isEqualTo(("SESSION=123; Path=/; Comment=Test Comment"));
486+
487+
assertNumCookies(1);
488+
assertThat(response.getCookies()[0]).isInstanceOf(MockCookie.class).satisfies(mockCookie -> {
489+
assertThat(mockCookie.getName()).isEqualTo("SESSION");
490+
assertThat(mockCookie.getPath()).isEqualTo("/");
491+
assertThat(mockCookie.getComment()).isEqualTo("Test Comment");
492+
});
493+
}
494+
477495
@Test
478496
void addCookieHeader() {
479497
response.addHeader(SET_COOKIE, "SESSION=123; Path=/; Secure; HttpOnly; SameSite=Lax");
@@ -487,6 +505,26 @@ void addCookieHeader() {
487505
assertCookieValues("123", "999");
488506
}
489507

508+
@Test
509+
void addCookieHeaderWithComment() {
510+
response.addHeader(SET_COOKIE, "SESSION=123; Path=/; Secure; HttpOnly; SameSite=Lax");
511+
assertNumCookies(1);
512+
assertPrimarySessionCookie("123");
513+
514+
// Adding a 2nd cookie header should result in 2 cookies.
515+
response.addHeader(SET_COOKIE, "SESSION=999; Comment=Test Comment; Path=/; Secure; HttpOnly; SameSite=Lax");
516+
assertNumCookies(2);
517+
assertPrimarySessionCookie("123");
518+
assertThat(response.getCookies()[1]).isInstanceOf(MockCookie.class).satisfies(mockCookie -> {
519+
assertThat(mockCookie.getName()).isEqualTo("SESSION");
520+
assertThat(mockCookie.getValue()).isEqualTo("999");
521+
assertThat(mockCookie.getComment()).isEqualTo("Test Comment");
522+
assertThat(mockCookie.getPath()).isEqualTo("/");
523+
assertThat(mockCookie.getSecure()).isTrue();
524+
assertThat(mockCookie.isHttpOnly()).isTrue();
525+
});
526+
}
527+
490528
/**
491529
* @since 5.1.11
492530
*/
@@ -570,13 +608,16 @@ private void assertCookieValues(String... expected) {
570608

571609
private void assertPrimarySessionCookie(String expectedValue) {
572610
Cookie cookie = this.response.getCookie("SESSION");
573-
assertThat(cookie).isInstanceOf(MockCookie.class);
574-
assertThat(cookie.getName()).isEqualTo("SESSION");
575-
assertThat(cookie.getValue()).isEqualTo(expectedValue);
576-
assertThat(cookie.getPath()).isEqualTo("/");
577-
assertThat(cookie.getSecure()).isTrue();
578-
assertThat(cookie.isHttpOnly()).isTrue();
579-
assertThat(((MockCookie) cookie).getSameSite()).isEqualTo("Lax");
611+
assertThat(cookie).asInstanceOf(type(MockCookie.class)).satisfies(mockCookie -> {
612+
assertThat(mockCookie.getName()).isEqualTo("SESSION");
613+
assertThat(mockCookie.getValue()).isEqualTo(expectedValue);
614+
assertThat(mockCookie.getPath()).isEqualTo("/");
615+
assertThat(mockCookie.getSecure()).isTrue();
616+
assertThat(mockCookie.isHttpOnly()).isTrue();
617+
assertThat(mockCookie.getComment()).isNull();
618+
assertThat(mockCookie.getExpires()).isNull();
619+
assertThat(mockCookie.getSameSite()).isEqualTo("Lax");
620+
});
580621
}
581622

582623
@Test // gh-25501

spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockCookie.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222

2323
import javax.servlet.http.Cookie;
2424

25+
import org.springframework.core.style.ToStringCreator;
2526
import org.springframework.lang.Nullable;
2627
import org.springframework.util.Assert;
2728
import org.springframework.util.StringUtils;
@@ -67,8 +68,8 @@ public void setExpires(@Nullable ZonedDateTime expires) {
6768

6869
/**
6970
* Get the "Expires" attribute for this cookie.
70-
* @since 5.1.11
7171
* @return the "Expires" attribute for this cookie, or {@code null} if not set
72+
* @since 5.1.11
7273
*/
7374
@Nullable
7475
public ZonedDateTime getExpires() {
@@ -141,6 +142,9 @@ else if (StringUtils.startsWithIgnoreCase(attribute, "HttpOnly")) {
141142
else if (StringUtils.startsWithIgnoreCase(attribute, "SameSite")) {
142143
cookie.setSameSite(extractAttributeValue(attribute, setCookieHeader));
143144
}
145+
else if (StringUtils.startsWithIgnoreCase(attribute, "Comment")) {
146+
cookie.setComment(extractAttributeValue(attribute, setCookieHeader));
147+
}
144148
}
145149
return cookie;
146150
}
@@ -152,4 +156,22 @@ private static String extractAttributeValue(String attribute, String header) {
152156
return nameAndValue[1];
153157
}
154158

159+
@Override
160+
public String toString() {
161+
return new ToStringCreator(this)
162+
.append("name", getName())
163+
.append("value", getValue())
164+
.append("Path", getPath())
165+
.append("Domain", getDomain())
166+
.append("Version", getVersion())
167+
.append("Comment", getComment())
168+
.append("Secure", getSecure())
169+
.append("HttpOnly", isHttpOnly())
170+
.append("SameSite", this.sameSite)
171+
.append("Max-Age", getMaxAge())
172+
.append("Expires", (this.expires != null ?
173+
DateTimeFormatter.RFC_1123_DATE_TIME.format(this.expires) : null))
174+
.toString();
175+
}
176+
155177
}

spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -450,6 +450,9 @@ else if (expires != null) {
450450
buf.append("; SameSite=").append(mockCookie.getSameSite());
451451
}
452452
}
453+
if (StringUtils.hasText(cookie.getComment())) {
454+
buf.append("; Comment=").append(cookie.getComment());
455+
}
453456
return buf.toString();
454457
}
455458

0 commit comments

Comments
 (0)