Skip to content

Commit 54f84cb

Browse files
Rob Winchrstoyanchev
authored andcommitted
MockMvcWebConnection stores cookies from response
Previously MockMvcWebConnection did not update the cookie manager with the cookies from MockHttpServletResponse. This meant that newly added cookies are not saved to the cookie manager and thus are not presented in the next request. This commit ensures that MockMvcWebConnection stores the response cookies in the cookie manager. Issue: SPR-14265
1 parent 92f1b69 commit 54f84cb

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package org.springframework.test.web.servlet.htmlunit;
1818

1919
import java.io.IOException;
20+
import java.util.Date;
2021
import java.util.HashMap;
2122
import java.util.Map;
2223

24+
import com.gargoylesoftware.htmlunit.CookieManager;
2325
import com.gargoylesoftware.htmlunit.WebClient;
2426
import com.gargoylesoftware.htmlunit.WebConnection;
2527
import com.gargoylesoftware.htmlunit.WebRequest;
2628
import com.gargoylesoftware.htmlunit.WebResponse;
29+
import com.gargoylesoftware.htmlunit.util.Cookie;
2730

2831
import org.springframework.mock.web.MockHttpServletResponse;
2932
import org.springframework.mock.web.MockHttpSession;
@@ -142,10 +145,32 @@ public WebResponse getResponse(WebRequest webRequest) throws IOException {
142145
httpServletResponse = getResponse(requestBuilder);
143146
forwardedUrl = httpServletResponse.getForwardedUrl();
144147
}
148+
storeCookies(webRequest, httpServletResponse.getCookies());
145149

146150
return new MockWebResponseBuilder(startTime, webRequest, httpServletResponse).build();
147151
}
148152

153+
private void storeCookies(WebRequest webRequest, javax.servlet.http.Cookie[] cookies) {
154+
if (cookies == null) {
155+
return;
156+
}
157+
Date now = new Date();
158+
CookieManager cookieManager = webClient.getCookieManager();
159+
for (javax.servlet.http.Cookie cookie : cookies) {
160+
if (cookie.getDomain() == null) {
161+
cookie.setDomain(webRequest.getUrl().getHost());
162+
}
163+
Cookie toManage = MockWebResponseBuilder.createCookie(cookie);
164+
Date expires = toManage.getExpires();
165+
if (expires == null || expires.after(now)) {
166+
cookieManager.addCookie(toManage);
167+
}
168+
else {
169+
cookieManager.removeCookie(toManage);
170+
}
171+
}
172+
}
173+
149174
private MockHttpServletResponse getResponse(RequestBuilder requestBuilder) throws IOException {
150175
ResultActions resultActions;
151176
try {
@@ -182,5 +207,4 @@ static void validateContextPath(String contextPath) {
182207
throw new IllegalArgumentException("contextPath '" + contextPath + "' must not end with '/'.");
183208
}
184209
}
185-
186210
}

spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockWebResponseBuilder.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ private List<NameValuePair> responseHeaders() {
112112
}
113113

114114
private String valueOfCookie(Cookie cookie) {
115+
return createCookie(cookie).toString();
116+
}
117+
118+
static com.gargoylesoftware.htmlunit.util.Cookie createCookie(Cookie cookie) {
115119
Date expires = null;
116120
if (cookie.getMaxAge() > -1) {
117121
expires = new Date(System.currentTimeMillis() + cookie.getMaxAge() * 1000);
@@ -125,7 +129,6 @@ private String valueOfCookie(Cookie cookie) {
125129
if(cookie.isHttpOnly()) {
126130
result.setAttribute("httponly", "true");
127131
}
128-
return new com.gargoylesoftware.htmlunit.util.Cookie(result).toString();
132+
return new com.gargoylesoftware.htmlunit.util.Cookie(result);
129133
}
130-
131134
}

spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilderTests.java

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import java.io.IOException;
2020
import java.net.URL;
2121
import javax.servlet.http.HttpServletRequest;
22+
import javax.servlet.http.HttpServletResponse;
2223

24+
import com.gargoylesoftware.htmlunit.HttpMethod;
2325
import com.gargoylesoftware.htmlunit.WebClient;
2426
import com.gargoylesoftware.htmlunit.WebRequest;
2527
import com.gargoylesoftware.htmlunit.WebResponse;
@@ -38,7 +40,10 @@
3840
import org.springframework.tests.Assume;
3941
import org.springframework.tests.TestGroup;
4042
import org.springframework.web.bind.annotation.CookieValue;
43+
import org.springframework.web.bind.annotation.DeleteMapping;
44+
import org.springframework.web.bind.annotation.PostMapping;
4145
import org.springframework.web.bind.annotation.RequestMapping;
46+
import org.springframework.web.bind.annotation.RequestParam;
4247
import org.springframework.web.bind.annotation.RestController;
4348
import org.springframework.web.context.WebApplicationContext;
4449
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@@ -103,11 +108,22 @@ public void cookieManagerShared() throws Exception {
103108
this.mockMvc = MockMvcBuilders.standaloneSetup(new CookieController()).build();
104109
WebClient client = MockMvcWebClientBuilder.mockMvcSetup(this.mockMvc).build();
105110

106-
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo(""));
111+
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo("NA"));
107112
client.getCookieManager().addCookie(new Cookie("localhost", "cookie", "cookieManagerShared"));
108113
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo("cookieManagerShared"));
109114
}
110115

116+
@Test // SPR-14265
117+
public void cookiesAreManaged() throws Exception {
118+
this.mockMvc = MockMvcBuilders.standaloneSetup(new CookieController()).build();
119+
WebClient client = MockMvcWebClientBuilder.mockMvcSetup(this.mockMvc).build();
120+
121+
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo("NA"));
122+
assertThat(postResponse(client, "http://localhost/?cookie=foo").getContentAsString(), equalTo("Set"));
123+
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo("foo"));
124+
assertThat(deleteResponse(client, "http://localhost/").getContentAsString(), equalTo("Delete"));
125+
assertThat(getResponse(client, "http://localhost/").getContentAsString(), equalTo("NA"));
126+
}
111127

112128
private void assertMockMvcUsed(WebClient client, String url) throws Exception {
113129
assertThat(getResponse(client, url).getContentAsString(), equalTo("mvc"));
@@ -118,7 +134,19 @@ private void assertMockMvcNotUsed(WebClient client, String url) throws Exception
118134
}
119135

120136
private WebResponse getResponse(WebClient client, String url) throws IOException {
121-
return client.getWebConnection().getResponse(new WebRequest(new URL(url)));
137+
return createResponse(client, new WebRequest(new URL(url)));
138+
}
139+
140+
private WebResponse postResponse(WebClient client, String url) throws IOException {
141+
return createResponse(client, new WebRequest(new URL(url), HttpMethod.POST));
142+
}
143+
144+
private WebResponse deleteResponse(WebClient client, String url) throws IOException {
145+
return createResponse(client, new WebRequest(new URL(url), HttpMethod.DELETE));
146+
}
147+
148+
private WebResponse createResponse(WebClient client, WebRequest request) throws IOException {
149+
return client.getWebConnection().getResponse(request);
122150
}
123151

124152

@@ -139,10 +167,26 @@ public String contextPath(HttpServletRequest request) {
139167
@RestController
140168
static class CookieController {
141169

170+
static final String COOKIE_NAME = "cookie";
171+
142172
@RequestMapping(path = "/", produces = "text/plain")
143-
String cookie(@CookieValue("cookie") String cookie) {
173+
String cookie(@CookieValue(name = COOKIE_NAME, defaultValue = "NA") String cookie) {
144174
return cookie;
145175
}
176+
177+
@PostMapping(path = "/", produces = "text/plain")
178+
String setCookie(@RequestParam String cookie, HttpServletResponse response) {
179+
response.addCookie(new javax.servlet.http.Cookie(COOKIE_NAME, cookie));
180+
return "Set";
181+
}
182+
183+
@DeleteMapping(path = "/", produces = "text/plain")
184+
String deleteCookie(HttpServletResponse response) {
185+
javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie(COOKIE_NAME, "");
186+
cookie.setMaxAge(0);
187+
response.addCookie(cookie);
188+
return "Delete";
189+
}
146190
}
147191

148192
}

0 commit comments

Comments
 (0)