/*
* Copyright 2002-2017 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
*
* http://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.mock.web;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.Cookie;
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.*;
/**
* Unit tests for {@link MockHttpServletRequest}.
*
* @author Rick Evans
* @author Mark Fisher
* @author Rossen Stoyanchev
* @author Sam Brannen
* @author Brian Clozel
* @author Jakub Narloch
*/
public class MockHttpServletRequestTests {
private static final String HOST = "Host";
private static final String CONTENT_TYPE = "Content-Type";
private static final String IF_MODIFIED_SINCE = "If-Modified-Since";
private final MockHttpServletRequest request = new MockHttpServletRequest();
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void protocolAndScheme() {
assertEquals(MockHttpServletRequest.DEFAULT_PROTOCOL, request.getProtocol());
assertEquals(MockHttpServletRequest.DEFAULT_SCHEME, request.getScheme());
request.setProtocol("HTTP/2.0");
request.setScheme("https");
assertEquals("HTTP/2.0", request.getProtocol());
assertEquals("https", request.getScheme());
}
@Test
public void setContentAndGetInputStream() throws IOException {
byte[] bytes = "body".getBytes(Charset.defaultCharset());
request.setContent(bytes);
assertEquals(bytes.length, request.getContentLength());
assertNotNull(request.getInputStream());
assertEquals("body", StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset()));
}
@Test
public void setContentAndGetContentAsByteArray() throws IOException {
byte[] bytes = "request body".getBytes();
request.setContent(bytes);
assertEquals(bytes.length, request.getContentLength());
assertNotNull(request.getContentAsByteArray());
assertEquals(bytes, request.getContentAsByteArray());
}
@Test
public void getContentAsStringWithoutSettingCharacterEncoding() throws IOException {
exception.expect(IllegalStateException.class);
exception.expectMessage("Cannot get content as a String for a null character encoding");
request.getContentAsString();
}
@Test
public void setContentAndGetContentAsStringWithExplicitCharacterEncoding() throws IOException {
String palindrome = "ablE was I ere I saw Elba";
byte[] bytes = palindrome.getBytes("UTF-16");
request.setCharacterEncoding("UTF-16");
request.setContent(bytes);
assertEquals(bytes.length, request.getContentLength());
assertNotNull(request.getContentAsString());
assertEquals(palindrome, request.getContentAsString());
}
@Test
public void noContent() throws IOException {
assertEquals(-1, request.getContentLength());
assertNotNull(request.getInputStream());
assertEquals(-1, request.getInputStream().read());
assertNull(request.getContentAsByteArray());
}
@Test
public void setContentType() {
String contentType = "test/plain";
request.setContentType(contentType);
assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE));
assertNull(request.getCharacterEncoding());
}
@Test
public void setContentTypeUTF8() {
String contentType = "test/plain;charset=UTF-8";
request.setContentType(contentType);
assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding());
}
@Test
public void contentTypeHeader() {
String contentType = "test/plain";
request.addHeader("Content-Type", contentType);
assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE));
assertNull(request.getCharacterEncoding());
}
@Test
public void contentTypeHeaderUTF8() {
String contentType = "test/plain;charset=UTF-8";
request.addHeader("Content-Type", contentType);
assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding());
}
// SPR-12677
@Test
public void setContentTypeHeaderWithMoreComplexCharsetSyntax() {
String contentType = "test/plain;charset=\"utf-8\";foo=\"charset=bar\";foocharset=bar;foo=bar";
request.addHeader("Content-Type", contentType);
assertEquals(contentType, request.getContentType());
assertEquals(contentType, request.getHeader(CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding());
}
@Test
public void setContentTypeThenCharacterEncoding() {
request.setContentType("test/plain");
request.setCharacterEncoding("UTF-8");
assertEquals("test/plain", request.getContentType());
assertEquals("test/plain;charset=UTF-8", request.getHeader(CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding());
}
@Test
public void setCharacterEncodingThenContentType() {
request.setCharacterEncoding("UTF-8");
request.setContentType("test/plain");
assertEquals("test/plain", request.getContentType());
assertEquals("test/plain;charset=UTF-8", request.getHeader(CONTENT_TYPE));
assertEquals("UTF-8", request.getCharacterEncoding());
}
@Test
public void httpHeaderNameCasingIsPreserved() throws Exception {
String headerName = "Header1";
request.addHeader(headerName, "value1");
Enumeration<String> requestHeaders = request.getHeaderNames();
assertNotNull(requestHeaders);
assertEquals("HTTP header casing not being preserved", headerName, requestHeaders.nextElement());
}
@Test
public void nullParameterName() {
assertNull(request.getParameter(null));
assertNull(request.getParameterValues(null));
}
@Test
public void setMultipleParameters() {
request.setParameter("key1", "value1");
request.setParameter("key2", "value2");
Map<String, Object> params = new HashMap<>(2);
params.put("key1", "newValue1");
params.put("key3", new String[] { "value3A", "value3B" });
request.setParameters(params);
String[] values1 = request.getParameterValues("key1");
assertEquals(1, values1.length);
assertEquals("newValue1", request.getParameter("key1"));
assertEquals("value2", request.getParameter("key2"));
String[] values3 = request.getParameterValues("key3");
assertEquals(2, values3.length);
assertEquals("value3A", values3[0]);
assertEquals("value3B", values3[1]);
}
@Test
public void addMultipleParameters() {
request.setParameter("key1", "value1");
request.setParameter("key2", "value2");
Map<String, Object> params = new HashMap<>(2);
params.put("key1", "newValue1");
params.put("key3", new String[] { "value3A", "value3B" });
request.addParameters(params);
String[] values1 = request.getParameterValues("key1");
assertEquals(2, values1.length);
assertEquals("value1", values1[0]);
assertEquals("newValue1", values1[1]);
assertEquals("value2", request.getParameter("key2"));
String[] values3 = request.getParameterValues("key3");
assertEquals(2, values3.length);
assertEquals("value3A", values3[0]);
assertEquals("value3B", values3[1]);
}
@Test
public void removeAllParameters() {
request.setParameter("key1", "value1");
Map<String, Object> params = new HashMap<>(2);
params.put("key2", "value2");
params.put("key3", new String[] { "value3A", "value3B" });
request.addParameters(params);
assertEquals(3, request.getParameterMap().size());
request.removeAllParameters();
assertEquals(0, request.getParameterMap().size());
}
@Test
public void cookies() {
Cookie cookie1 = new Cookie("foo", "bar");
Cookie cookie2 = new Cookie("baz", "qux");
request.setCookies(cookie1, cookie2);
Cookie[] cookies = request.getCookies();
List<String> cookieHeaders = Collections.list(request.getHeaders("Cookie"));
assertEquals(2, cookies.length);
assertEquals("foo", cookies[0].getName());
assertEquals("bar", cookies[0].getValue());
assertEquals("baz", cookies[1].getName());
assertEquals("qux", cookies[1].getValue());
assertEquals(Arrays.asList("foo=bar", "baz=qux"), cookieHeaders);
}
@Test
public void noCookies() {
assertNull(request.getCookies());
}
@Test
public void defaultLocale() {
Locale originalDefaultLocale = Locale.getDefault();
try {
Locale newDefaultLocale = originalDefaultLocale.equals(Locale.GERMANY) ? Locale.FRANCE : Locale.GERMANY;
Locale.setDefault(newDefaultLocale);
// Create the request after changing the default locale.
MockHttpServletRequest request = new MockHttpServletRequest();
assertFalse(newDefaultLocale.equals(request.getLocale()));
assertEquals(Locale.ENGLISH, request.getLocale());
}
finally {
Locale.setDefault(originalDefaultLocale);
}
}
@Test(expected = IllegalArgumentException.class)
public void setPreferredLocalesWithNullList() {
request.setPreferredLocales(null);
}
@Test(expected = IllegalArgumentException.class)
public void setPreferredLocalesWithEmptyList() {
request.setPreferredLocales(new ArrayList<>());
}
@Test
public void setPreferredLocales() {
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
public void getServerNameWithDefaultName() {
assertEquals("localhost", request.getServerName());
}
@Test
public void getServerNameWithCustomName() {
request.setServerName("example.com");
assertEquals("example.com", request.getServerName());
}
@Test
public void getServerNameViaHostHeaderWithoutPort() {
String testServer = "test.server";
request.addHeader(HOST, testServer);
assertEquals(testServer, request.getServerName());
}
@Test
public void getServerNameViaHostHeaderWithPort() {
String testServer = "test.server";
request.addHeader(HOST, testServer + ":8080");
assertEquals(testServer, request.getServerName());
}
@Test
public void getServerNameViaHostHeaderAsIpv6AddressWithoutPort() {
String ipv6Address = "[2001:db8:0:1]";
request.addHeader(HOST, ipv6Address);
assertEquals("2001:db8:0:1", request.getServerName());
}
@Test
public void getServerNameViaHostHeaderAsIpv6AddressWithPort() {
String ipv6Address = "[2001:db8:0:1]:8081";
request.addHeader(HOST, ipv6Address);
assertEquals("2001:db8:0:1", request.getServerName());
}
@Test
public void getServerPortWithDefaultPort() {
assertEquals(80, request.getServerPort());
}
@Test
public void getServerPortWithCustomPort() {
request.setServerPort(8080);
assertEquals(8080, request.getServerPort());
}
@Test
public void getServerPortViaHostHeaderAsIpv6AddressWithoutPort() {
String testServer = "[2001:db8:0:1]";
request.addHeader(HOST, testServer);
assertEquals(80, request.getServerPort());
}
@Test
public void getServerPortViaHostHeaderAsIpv6AddressWithPort() {
String testServer = "[2001:db8:0:1]";
int testPort = 9999;
request.addHeader(HOST, testServer + ":" + testPort);
assertEquals(testPort, request.getServerPort());
}
@Test
public void getServerPortViaHostHeaderWithoutPort() {
String testServer = "test.server";
request.addHeader(HOST, testServer);
assertEquals(80, request.getServerPort());
}
@Test
public void getServerPortViaHostHeaderWithPort() {
String testServer = "test.server";
int testPort = 9999;
request.addHeader(HOST, testServer + ":" + testPort);
assertEquals(testPort, request.getServerPort());
}
@Test
public void getRequestURL() {
request.setServerPort(8080);
request.setRequestURI("/path");
assertEquals("http://localhost:8080/path", request.getRequestURL().toString());
request.setScheme("https");
request.setServerName("example.com");
request.setServerPort(8443);
assertEquals("https://example.com:8443/path", request.getRequestURL().toString());
}
@Test
public void getRequestURLWithDefaults() {
StringBuffer requestURL = request.getRequestURL();
assertEquals("http://localhost", requestURL.toString());
}
@Test
public void getRequestURLWithNullRequestUri() {
request.setRequestURI(null);
StringBuffer requestURL = request.getRequestURL();
assertEquals("http://localhost", requestURL.toString());
}
@Test
public void getRequestURLWithDefaultsAndHttps() {
request.setScheme("https");
request.setServerPort(443);
StringBuffer requestURL = request.getRequestURL();
assertEquals("https://localhost", requestURL.toString());
}
@Test
public void getRequestURLWithNegativePort() {
request.setServerPort(-99);
StringBuffer requestURL = request.getRequestURL();
assertEquals("http://localhost", requestURL.toString());
}
@Test
public void isSecureWithHttpSchemeAndSecureFlagIsFalse() {
assertFalse(request.isSecure());
request.setScheme("http");
request.setSecure(false);
assertFalse(request.isSecure());
}
@Test
public void isSecureWithHttpSchemeAndSecureFlagIsTrue() {
assertFalse(request.isSecure());
request.setScheme("http");
request.setSecure(true);
assertTrue(request.isSecure());
}
@Test
public void isSecureWithHttpsSchemeAndSecureFlagIsFalse() {
assertFalse(request.isSecure());
request.setScheme("https");
request.setSecure(false);
assertTrue(request.isSecure());
}
@Test
public void isSecureWithHttpsSchemeAndSecureFlagIsTrue() {
assertFalse(request.isSecure());
request.setScheme("https");
request.setSecure(true);
assertTrue(request.isSecure());
}
@Test
public void httpHeaderDate() throws Exception {
Date date = new Date();
request.addHeader(IF_MODIFIED_SINCE, date);
assertEquals(date.getTime(), request.getDateHeader(IF_MODIFIED_SINCE));
}
@Test
public void httpHeaderTimestamp() throws Exception {
long timestamp = new Date().getTime();
request.addHeader(IF_MODIFIED_SINCE, timestamp);
assertEquals(timestamp, request.getDateHeader(IF_MODIFIED_SINCE));
}
@Test
public void httpHeaderRfcFormatedDate() throws Exception {
request.addHeader(IF_MODIFIED_SINCE, "Tue, 21 Jul 2015 10:00:00 GMT");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE));
}
@Test
public void httpHeaderFirstVariantFormatedDate() throws Exception {
request.addHeader(IF_MODIFIED_SINCE, "Tue, 21-Jul-15 10:00:00 GMT");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE));
}
@Test
public void httpHeaderSecondVariantFormatedDate() throws Exception {
request.addHeader(IF_MODIFIED_SINCE, "Tue Jul 21 10:00:00 2015");
assertEquals(1437472800000L, request.getDateHeader(IF_MODIFIED_SINCE));
}
@Test(expected = IllegalArgumentException.class)
public void httpHeaderFormatedDateError() throws Exception {
request.addHeader(IF_MODIFIED_SINCE, "This is not a date");
request.getDateHeader(IF_MODIFIED_SINCE);
}
private void assertEqualEnumerations(Enumeration<?> enum1, Enumeration<?> enum2) {
assertNotNull(enum1);
assertNotNull(enum2);
int count = 0;
while (enum1.hasMoreElements()) {
assertTrue("enumerations must be equal in length", enum2.hasMoreElements());
assertEquals("enumeration element #" + ++count, enum1.nextElement(), enum2.nextElement());
}
}
}