Browse Source

Mock Servlet request/response support Accept-Language

Issue: SPR-15209
pull/1362/merge
Rossen Stoyanchev 8 years ago
parent
commit
5d92a85fcb
  1. 19
      spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java
  2. 10
      spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java
  3. 22
      spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java
  4. 11
      spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java
  5. 26
      spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilderTests.java
  6. 19
      spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java
  7. 10
      spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java
  8. 4
      spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java

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

@ -740,6 +740,7 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -740,6 +740,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
public void addPreferredLocale(Locale locale) {
Assert.notNull(locale, "Locale must not be null");
this.locales.add(0, locale);
updateAcceptLanguageHeader();
}
/**
@ -752,6 +753,13 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -752,6 +753,13 @@ public class MockHttpServletRequest implements HttpServletRequest {
Assert.notEmpty(locales, "Locale list must not be empty");
this.locales.clear();
this.locales.addAll(locales);
updateAcceptLanguageHeader();
}
private void updateAcceptLanguageHeader() {
HttpHeaders headers = new HttpHeaders();
headers.setAcceptLanguageAsLocales(this.locales);
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, headers.getFirst(HttpHeaders.ACCEPT_LANGUAGE), true);
}
/**
@ -951,9 +959,18 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -951,9 +959,18 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #getDateHeader
*/
public void addHeader(String name, Object value) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && !this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
setContentType(value.toString());
}
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
setPreferredLocales(headers.getAcceptLanguageAsLocales());
}
else {
this.cookieHeaderSet = HttpHeaders.COOKIE.equalsIgnoreCase(name);
doAddHeaderValue(name, value, false);

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

@ -304,6 +304,9 @@ public class MockHttpServletResponse implements HttpServletResponse { @@ -304,6 +304,9 @@ public class MockHttpServletResponse implements HttpServletResponse {
@Override
public void setLocale(Locale locale) {
this.locale = locale;
if (locale != null) {
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag(), true);
}
}
@Override
@ -577,6 +580,13 @@ public class MockHttpServletResponse implements HttpServletResponse { @@ -577,6 +580,13 @@ public class MockHttpServletResponse implements HttpServletResponse {
Integer.parseInt(value.toString()));
return true;
}
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name)) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
List<Locale> locales = headers.getAcceptLanguageAsLocales();
setLocale(locales.isEmpty() ? null : locales.get(0));
return true;
}
else {
return false;
}

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

@ -29,7 +29,6 @@ import java.util.Map; @@ -29,7 +29,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
@ -353,12 +352,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable { @@ -353,12 +352,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
if (locale == null) {
request.addPreferredLocale(Locale.getDefault());
}
else {
String[] tokens = StringUtils.tokenizeToStringArray(locale, ",");
for (int i = tokens.length - 1; i >= 0; i--) {
request.addPreferredLocale(parseLocale(tokens[i]));
}
}
}
private void params(MockHttpServletRequest request, UriComponents uriComponents) {
@ -384,21 +377,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable { @@ -384,21 +377,6 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
}
}
private Locale parseLocale(String locale) {
Matcher matcher = LOCALE_PATTERN.matcher(locale);
Assert.isTrue(matcher.matches(), () -> "Invalid locale value [" + locale + "]");
String language = matcher.group(1);
String country = matcher.group(2);
if (country == null) {
country = "";
}
String qualifier = matcher.group(3);
if (qualifier == null) {
qualifier = "";
}
return new Locale(language, country, qualifier);
}
private void servletPath(MockHttpServletRequest request, String requestPath) {
String servletPath = requestPath.substring(request.getContextPath().length());
if ("".equals(servletPath)) {

11
spring-test/src/test/java/org/springframework/mock/web/MockHttpServletRequestTests.java

@ -33,6 +33,7 @@ import org.junit.Rule; @@ -33,6 +33,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StreamUtils;
import static org.junit.Assert.*;
@ -297,6 +298,16 @@ public class MockHttpServletRequestTests { @@ -297,6 +298,16 @@ public class MockHttpServletRequestTests {
List<Locale> preferredLocales = Arrays.asList(Locale.ITALY, Locale.CHINA);
request.setPreferredLocales(preferredLocales);
assertEqualEnumerations(Collections.enumeration(preferredLocales), request.getLocales());
assertEquals("it-it, zh-cn", request.getHeader(HttpHeaders.ACCEPT_LANGUAGE));
}
@Test
public void preferredLocalesFromAcceptLanguageHeader() {
String headerValue = "fr-ch, fr;q=0.9, en-*;q=0.8, de;q=0.7, *;q=0.5";
request.addHeader("Accept-Language", headerValue);
List<Locale> actual = Collections.list(request.getLocales());
assertEquals(Arrays.asList(Locale.forLanguageTag("fr-ch"), Locale.forLanguageTag("fr"),
Locale.forLanguageTag("en"), Locale.forLanguageTag("de")), actual);
}
@Test

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

@ -45,10 +45,16 @@ import org.springframework.test.util.ReflectionTestUtils; @@ -45,10 +45,16 @@ import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static java.util.Arrays.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
* Unit tests for {@link HtmlUnitRequestBuilder}.
@ -291,16 +297,16 @@ public class HtmlUnitRequestBuilderTests { @@ -291,16 +297,16 @@ public class HtmlUnitRequestBuilderTests {
MockHttpServletRequest actualRequest = requestBuilder.buildRequest(servletContext);
assertThat(actualRequest.getLocale(), equalTo(new Locale("en", "gb", "0.8")));
assertThat(actualRequest.getLocale(), equalTo(new Locale("en", "gb")));
}
@Test
public void buildRequestLocaleEnQ07() {
webRequest.setAdditionalHeader("Accept-Language", "en;q=0.7");
webRequest.setAdditionalHeader("Accept-Language", "en");
MockHttpServletRequest actualRequest = requestBuilder.buildRequest(servletContext);
assertThat(actualRequest.getLocale(), equalTo(new Locale("en", "", "0.7")));
assertThat(actualRequest.getLocale(), equalTo(new Locale("en", "")));
}
@Test
@ -323,13 +329,11 @@ public class HtmlUnitRequestBuilderTests { @@ -323,13 +329,11 @@ public class HtmlUnitRequestBuilderTests {
@Test
public void buildRequestLocaleMulti() {
webRequest.setAdditionalHeader("Accept-Language", "da, en-gb;q=0.8, en;q=0.7");
webRequest.setAdditionalHeader("Accept-Language", "en-gb;q=0.8, da, en;q=0.7");
MockHttpServletRequest actualRequest = requestBuilder.buildRequest(servletContext);
// Append Locale.ENGLISH since MockHttpServletRequest automatically sets it as the
// preferred locale.
List<Locale> expected = asList(new Locale("da"), new Locale("en", "gb", "0.8"), new Locale("en", "", "0.7"), Locale.ENGLISH);
List<Locale> expected = asList(new Locale("da"), new Locale("en", "gb"), new Locale("en", ""));
assertThat(Collections.list(actualRequest.getLocales()), equalTo(expected));
}

19
spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java

@ -740,6 +740,7 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -740,6 +740,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
public void addPreferredLocale(Locale locale) {
Assert.notNull(locale, "Locale must not be null");
this.locales.add(0, locale);
updateAcceptLanguageHeader();
}
/**
@ -752,6 +753,13 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -752,6 +753,13 @@ public class MockHttpServletRequest implements HttpServletRequest {
Assert.notEmpty(locales, "Locale list must not be empty");
this.locales.clear();
this.locales.addAll(locales);
updateAcceptLanguageHeader();
}
private void updateAcceptLanguageHeader() {
HttpHeaders headers = new HttpHeaders();
headers.setAcceptLanguageAsLocales(this.locales);
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, headers.getFirst(HttpHeaders.ACCEPT_LANGUAGE), true);
}
/**
@ -951,9 +959,18 @@ public class MockHttpServletRequest implements HttpServletRequest { @@ -951,9 +959,18 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #getDateHeader
*/
public void addHeader(String name, Object value) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) && !this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
if (HttpHeaders.CONTENT_TYPE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.CONTENT_TYPE)) {
setContentType(value.toString());
}
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name) &&
!this.headers.containsKey(HttpHeaders.ACCEPT_LANGUAGE)) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
setPreferredLocales(headers.getAcceptLanguageAsLocales());
}
else {
this.cookieHeaderSet = HttpHeaders.COOKIE.equalsIgnoreCase(name);
doAddHeaderValue(name, value, false);

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

@ -304,6 +304,9 @@ public class MockHttpServletResponse implements HttpServletResponse { @@ -304,6 +304,9 @@ public class MockHttpServletResponse implements HttpServletResponse {
@Override
public void setLocale(Locale locale) {
this.locale = locale;
if (locale != null) {
doAddHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag(), true);
}
}
@Override
@ -577,6 +580,13 @@ public class MockHttpServletResponse implements HttpServletResponse { @@ -577,6 +580,13 @@ public class MockHttpServletResponse implements HttpServletResponse {
Integer.parseInt(value.toString()));
return true;
}
else if (HttpHeaders.ACCEPT_LANGUAGE.equalsIgnoreCase(name)) {
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_LANGUAGE, value.toString());
List<Locale> locales = headers.getAcceptLanguageAsLocales();
setLocale(locales.isEmpty() ? null : locales.get(0));
return true;
}
else {
return false;
}

4
spring-webmvc/src/test/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolverTests.java

@ -63,7 +63,7 @@ public class AcceptHeaderLocaleResolverTests { @@ -63,7 +63,7 @@ public class AcceptHeaderLocaleResolverTests {
this.resolver.setDefaultLocale(Locale.JAPAN);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Accept-Language", KOREA.toString());
request.addHeader("Accept-Language", KOREA.toLanguageTag());
request.setPreferredLocales(Collections.singletonList(KOREA));
assertEquals(Locale.JAPAN, this.resolver.resolveLocale(request));
}
@ -74,7 +74,7 @@ public class AcceptHeaderLocaleResolverTests { @@ -74,7 +74,7 @@ public class AcceptHeaderLocaleResolverTests {
MockHttpServletRequest request = new MockHttpServletRequest();
assertEquals(JAPANESE, this.resolver.resolveLocale(request));
request.addHeader("Accept-Language", US.toString());
request.addHeader("Accept-Language", US.toLanguageTag());
request.setPreferredLocales(Collections.singletonList(US));
assertEquals(US, this.resolver.resolveLocale(request));
}

Loading…
Cancel
Save