/**
* Copyright (C) 2012-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 ninja.servlet;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Map;
import javax.servlet.ReadListener;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ninja.ContentTypes;
import ninja.Context;
import ninja.Cookie;
import ninja.Result;
import ninja.Results;
import ninja.Route;
import ninja.bodyparser.BodyParserEngine;
import ninja.bodyparser.BodyParserEngineManager;
import ninja.params.ParamParser;
import ninja.params.ParamParsers;
import ninja.session.FlashScope;
import ninja.session.Session;
import ninja.utils.NinjaConstant;
import ninja.utils.NinjaProperties;
import ninja.utils.ResultHandler;
import ninja.validation.Validation;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import com.google.common.collect.Maps;
import com.google.inject.Injector;
@RunWith(MockitoJUnitRunner.class)
public class NinjaServletContextTest {
@Mock
private Session sessionCookie;
@Mock
private FlashScope flashCookie;
@Mock
private BodyParserEngineManager bodyParserEngineManager;
@Mock
private ServletContext servletContext;
@Mock
private HttpServletRequest httpServletRequest;
@Mock
private HttpServletResponse httpServletResponse;
@Mock
private Route route;
@Mock
private ResultHandler resultHandler;
@Mock
private Validation validation;
@Mock
private BodyParserEngine bodyParserEngine;
@Mock
private NinjaProperties ninjaProperties;
@Mock
private Injector injector;
private NinjaServletContext context;
@Before
public void setUp() {
//default setup for httpServlet request.
//According to servlet spec the following will be returned:
when(httpServletRequest.getContextPath()).thenReturn("");
when(httpServletRequest.getRequestURI()).thenReturn("/");
context = new NinjaServletContext(
bodyParserEngineManager,
flashCookie,
ninjaProperties,
resultHandler,
sessionCookie,
validation,
injector,
new ParamParsers(new HashSet<ParamParser>()));
}
@Test
public void testGetRequestUri() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getRequestURI()).thenReturn("/index");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("/index", context.getRequestPath());
}
@Test
public void testGetHostname() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getHeader("host")).thenReturn("test.com");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("test.com", context.getHostname());
}
@Test
public void testGetRemoteAddrReturnsDefaultRemoteAddr() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getRemoteAddr()).thenReturn("mockedRemoteAddr");
when(httpServletRequest.getHeader(Context.X_FORWARD_HEADER)).thenReturn("x-forwarded-for-mockedRemoteAddr");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("mockedRemoteAddr", context.getRemoteAddr());
}
@Test
public void testGetRemoteAddrParsesXForwardedForIfSetInApplicationConf() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getRemoteAddr()).thenReturn("mockedRemoteAddr");
when(httpServletRequest.getHeader(Context.X_FORWARD_HEADER)).thenReturn("192.168.1.44");
when(ninjaProperties.getBooleanWithDefault(Context.NINJA_PROPERTIES_X_FORWARDED_FOR, false))
.thenReturn(Boolean.TRUE);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("192.168.1.44", context.getRemoteAddr());
}
@Test
public void testGetRemoteAddrParsesXForwardedForIfMoreThanOneHostPresent() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getRemoteAddr()).thenReturn("mockedRemoteAddr");
when(httpServletRequest.getHeader(Context.X_FORWARD_HEADER)).thenReturn("192.168.1.1, 192.168.1.2, 192.168.1.3");
when(ninjaProperties.getBooleanWithDefault(Context.NINJA_PROPERTIES_X_FORWARDED_FOR, false))
.thenReturn(Boolean.TRUE);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("192.168.1.1", context.getRemoteAddr());
}
@Test
public void testGetRemoteAddrUsesFallbackIfXForwardedForIsNotValidInetAddr() {
//say the httpServletRequest to return a certain value:
when(httpServletRequest.getRemoteAddr()).thenReturn("mockedRemoteAddr");
when(httpServletRequest.getHeader(Context.X_FORWARD_HEADER)).thenReturn("I_AM_NOT_A_VALID_ADDRESS");
when(ninjaProperties.getBooleanWithDefault(Context.NINJA_PROPERTIES_X_FORWARDED_FOR, false))
.thenReturn(Boolean.TRUE);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
//make sure this is correct
assertEquals("mockedRemoteAddr", context.getRemoteAddr());
}
@Test
public void testAddCookieViaResult() {
Cookie cookie = Cookie.builder("cookie", "yum").setDomain("domain").build();
context.init(servletContext, httpServletRequest, httpServletResponse);
//context.addCookie(cookie);
//generate an arbitrary result:
Result result = Results.html();
result.addCookie(cookie);
//finalize the headers => the cookies must be copied over to the servletcookies
context.finalizeHeaders(result);
//and verify the stuff:
ArgumentCaptor<javax.servlet.http.Cookie> cookieCaptor = ArgumentCaptor.forClass(javax.servlet.http.Cookie.class);
verify(httpServletResponse).addCookie(cookieCaptor.capture());
javax.servlet.http.Cookie resultCookie = cookieCaptor.getValue();
assertThat(resultCookie.getName(), equalTo("cookie"));
assertThat(resultCookie.getValue(), equalTo("yum"));
assertThat(resultCookie.getPath(), equalTo("/"));
assertThat(resultCookie.getSecure(), equalTo(false));
assertThat(resultCookie.getMaxAge(), equalTo(-1));
}
@Test
public void testAddCookieViaContext() {
Cookie cookie = Cookie.builder("cookie", "yummy").setDomain("domain").build();
context.init(servletContext, httpServletRequest, httpServletResponse);
context.addCookie(cookie);
//finalize the headers => the cookies must be copied over to the servletcookies
context.finalizeHeaders(Results.html());
//and verify the stuff:
ArgumentCaptor<javax.servlet.http.Cookie> cookieCaptor = ArgumentCaptor.forClass(javax.servlet.http.Cookie.class);
verify(httpServletResponse).addCookie(cookieCaptor.capture());
javax.servlet.http.Cookie resultCookie = cookieCaptor.getValue();
assertThat(resultCookie.getName(), equalTo("cookie"));
assertThat(resultCookie.getValue(), equalTo("yummy"));
assertThat(resultCookie.getPath(), equalTo("/"));
assertThat(resultCookie.getSecure(), equalTo(false));
assertThat(resultCookie.getMaxAge(), equalTo(-1));
}
@Test
public void testUnsetCookieViaContext() {
Cookie cookie = Cookie.builder("cookie", "yummy").setDomain("domain").build();
context.init(servletContext, httpServletRequest, httpServletResponse);
context.unsetCookie(cookie);
//finalize the headers => the cookies must be copied over to the servletcookies
context.finalizeHeaders(Results.html());
//and verify the stuff:
ArgumentCaptor<javax.servlet.http.Cookie> cookieCaptor = ArgumentCaptor.forClass(javax.servlet.http.Cookie.class);
verify(httpServletResponse).addCookie(cookieCaptor.capture());
javax.servlet.http.Cookie resultCookie = cookieCaptor.getValue();
assertThat(resultCookie.getName(), equalTo("cookie"));
assertThat(resultCookie.getValue(), equalTo("yummy"));
assertThat(resultCookie.getPath(), equalTo("/"));
assertThat(resultCookie.getSecure(), equalTo(false));
assertThat(resultCookie.getMaxAge(), equalTo(0));
}
@Test
public void getCookieTest() {
javax.servlet.http.Cookie servletCookie1 = new javax.servlet.http.Cookie("contextCookie1", "theValue1");
javax.servlet.http.Cookie servletCookie2 = new javax.servlet.http.Cookie("contextCookie2", "theValue2");
javax.servlet.http.Cookie [] servletCookies = {servletCookie1, servletCookie2};
when(httpServletRequest.getCookies()).thenReturn(servletCookies);
context.init(servletContext, httpServletRequest, httpServletResponse);
// negative test:
ninja.Cookie doesNotExist = context.getCookie("doesNotExist");
assertNull(doesNotExist);
// test against cookie that is really there
ninja.Cookie cookie1 = context.getCookie("contextCookie1");
assertEquals(cookie1.getName(), "contextCookie1");
assertEquals(cookie1.getValue(), "theValue1");
// test 2 against cookie that is really there
ninja.Cookie cookie2= context.getCookie("contextCookie2");
assertEquals(cookie2.getName(), "contextCookie2");
assertEquals(cookie2.getValue(), "theValue2");
}
@Test
public void hasCookieTest() {
javax.servlet.http.Cookie servletCookie1 = new javax.servlet.http.Cookie("contextCookie1", "theValue1");
javax.servlet.http.Cookie servletCookie2 = new javax.servlet.http.Cookie("contextCookie2", "theValue2");
javax.servlet.http.Cookie [] servletCookies = {servletCookie1, servletCookie2};
when(httpServletRequest.getCookies()).thenReturn(servletCookies);
context.init(servletContext, httpServletRequest, httpServletResponse);
// negative test:
assertFalse(context.hasCookie("doesNotExist"));
// test against cookie that is really there
assertTrue(context.hasCookie("contextCookie1"));
// test 2 against cookie that is really there
assertTrue(context.hasCookie("contextCookie2"));
}
@Test
public void getCookiesTest() {
javax.servlet.http.Cookie servletCookie1 = new javax.servlet.http.Cookie("contextCookie1", "theValue");
javax.servlet.http.Cookie servletCookie2 = new javax.servlet.http.Cookie("contextCookie2", "theValue");
javax.servlet.http.Cookie [] servletCookiesEmpty = {};
javax.servlet.http.Cookie [] servletCookies = {servletCookie1, servletCookie2};
when(httpServletRequest.getCookies()).thenReturn(servletCookiesEmpty);
context.init(servletContext, httpServletRequest, httpServletResponse);
//test when there are no cookies.
assertEquals(0, context.getCookies().size());
// now return some cookies:
when(httpServletRequest.getCookies()).thenReturn(servletCookies);
assertEquals(2, context.getCookies().size());
}
@Test
public void testGetPathParameter() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//mock a parametermap:
Map<String, String> parameterMap = Maps.newHashMap();
parameterMap.put("parameter", "parameter");
//and return the parameter map when any parameter is called...
when(route.getPathParametersEncoded(Matchers.anyString())).thenReturn(parameterMap);
context.setRoute(route);
//this parameter is not there and must return null
assertEquals(null, context.getPathParameter("parameter_not_set"));
assertEquals("parameter", context.getPathParameter("parameter"));
}
@Test
public void testGetPathParameterDecodingWorks() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//mock a parametermap:
Map<String, String> parameterMap = Maps.newHashMap();
parameterMap.put("parameter", "blue%2Fred%3Fand+green%E2%82%AC%2f");
//and return the parameter map when any parameter is called...
when(route.getPathParametersEncoded(Matchers.anyString())).thenReturn(parameterMap);
context.setRoute(route);
//that is how the above parameter looks decoded correctly:
assertEquals("blue/red?and+green€/", context.getPathParameter("parameter"));
}
@Test
public void testGetPathParameterAsInteger() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//mock a parametermap:
Map<String, String> parameterMap = Maps.newHashMap();
parameterMap.put("parameter", "parameter");
//and return the parameter map when any parameter is called...
when(route.getPathParametersEncoded(Matchers.anyString())).thenReturn(parameterMap);
context.setRoute(route);
//this will not work and return null
assertEquals(null, context.getPathParameterAsInteger("parameter"));
//now set an integer into the parametermap:
parameterMap.put("parameter", "1");
//this will work and return 1
assertEquals(new Integer(1), context.getPathParameterAsInteger("parameter"));
}
@Test
public void testGetParameter() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//and return the parameter map when any parameter is called...
when(httpServletRequest.getParameter("key")).thenReturn("value");
//this will not work and return null
assertEquals(null, context.getParameter("key_not_there"));
//this will return the default value:
assertEquals("defaultValue", context.getParameter("key_not_there", "defaultValue"));
//this will work as the value is there...
assertEquals("value", context.getParameter("key"));
}
@Test
public void testGetParameterAsInteger() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//and return the parameter map when any parameter is called...
when(httpServletRequest.getParameter("key")).thenReturn("1");
//this will not work and return null
assertEquals(null, context.getParameterAsInteger("key_not_there"));
//this will return the default value:
assertEquals(new Integer(100), context.getParameterAsInteger("key_not_there", 100));
//this will work as the value is there...
assertEquals(new Integer(1), context.getParameterAsInteger("key"));
}
@Test
public void testGetParameterAs() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//and return the parameter map when any parameter is called...
when(httpServletRequest.getParameter("key1")).thenReturn("100");
when(httpServletRequest.getParameter("key2")).thenReturn("true");
when(httpServletRequest.getParameter("key3")).thenReturn("10.1");
when(httpServletRequest.getParameter("key4")).thenReturn("x");
//this will not work and return null
assertEquals(null, context.getParameterAs("key", Long.class));
assertEquals(new Integer(100), context.getParameterAs("key1", Integer.class));
assertEquals(new Long(100), context.getParameterAs("key1", Long.class));
assertEquals(Boolean.TRUE, context.getParameterAs("key2", Boolean.class));
assertEquals(new Float(10.1), context.getParameterAs("key3", Float.class));
assertEquals(new Character('x'), context.getParameterAs("key4", Character.class));
}
@Test
public void testContentTypeGetsConvertedProperlyUponFinalize() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//this must be Content-Type: application/json; encoding=utf-8
Result result = Results.json();
context.finalizeHeaders(result);
verify(httpServletResponse).setCharacterEncoding(result.getCharset());
verify(httpServletResponse).setContentType(result.getContentType());
}
@Test
public void testContentTypeWithNullEncodingGetsConvertedProperlyUponFinalize() {
//init the context
context.init(servletContext, httpServletRequest, httpServletResponse);
//this must be Content-Type: application/json; encoding=utf-8
Result result = Results.json();
//force a characterset that is not there. Stupid but tests that its working.
result.charset(null);
context.finalizeHeaders(result);
//make sure utf-8 is used under all circumstances:
verify(httpServletResponse).setCharacterEncoding(NinjaConstant.UTF_8);
}
@Test
public void testGetRequestPathWorksAsExpectedWithContext() {
// we got a context
when(httpServletRequest.getContextPath()).thenReturn("/my/funky/prefix");
// we got a request uri
when(httpServletRequest.getRequestURI()).thenReturn("/my/funky/prefix/myapp/is/here");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals("/myapp/is/here", context.getRequestPath());
}
@Test
public void testGetRequestPathWorksAsExpectedWithOutContext() {
// we got not context.
// according to spec it will return an empty string
when(httpServletRequest.getContextPath()).thenReturn("");
when(httpServletRequest.getRequestURI()).thenReturn("/index");
// we got a request uri
when(httpServletRequest.getRequestURI()).thenReturn("/myapp/is/here");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals("/myapp/is/here", context.getRequestPath());
}
@Test
public void testGetRequestContentType() {
String contentType = "text/html";
when(httpServletRequest.getContentType()).thenReturn(contentType);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(contentType, context.getRequestContentType());
contentType = null;
when(httpServletRequest.getContentType()).thenReturn(contentType);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertNull(context.getRequestContentType());
contentType = "text/html; charset=UTF-8";
when(httpServletRequest.getContentType()).thenReturn(contentType);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(contentType, context.getRequestContentType());
}
@Test
public void testGetAcceptContentType() {
when(httpServletRequest.getHeader("accept")).thenReturn(null);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_HTML, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_HTML, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("totally_unknown");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_HTML, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("application/json");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.APPLICATION_JSON, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("text/html, application/json");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_HTML, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("application/xhtml, application/json");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_HTML, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("text/plain");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.TEXT_PLAIN, context.getAcceptContentType());
when(httpServletRequest.getHeader("accept")).thenReturn("text/plain, application/json");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(Result.APPLICATION_JSON, context.getAcceptContentType());
}
@Test
public void testGetAcceptEncoding() {
String encoding = "compress, gzip";
when(httpServletRequest.getHeader("accept-encoding")).thenReturn(encoding);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(encoding, context.getAcceptEncoding());
encoding = null;
when(httpServletRequest.getHeader("accept-encoding")).thenReturn(encoding);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertNull(context.getAcceptEncoding());
encoding = "gzip;q=1.0, identity; q=0.5, *;q=0";
when(httpServletRequest.getHeader("accept-encoding")).thenReturn(encoding);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(encoding, context.getAcceptEncoding());
}
@Test
public void testGetAcceptLanguage() {
String language = "de";
when(httpServletRequest.getHeader("accept-language")).thenReturn(language);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(language, context.getAcceptLanguage());
language = null;
when(httpServletRequest.getHeader("accept-language")).thenReturn(language);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertNull(context.getAcceptLanguage());
language = "da, en-gb;q=0.8, en;q=0.7";
when(httpServletRequest.getHeader("accept-language")).thenReturn(language);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(language, context.getAcceptLanguage());
}
@Test
public void testGetAcceptCharset() {
String charset = "UTF-8";
when(httpServletRequest.getHeader("accept-charset")).thenReturn(charset);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(charset, context.getAcceptCharset());
charset = null;
when(httpServletRequest.getHeader("accept-charset")).thenReturn(charset);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertNull(context.getAcceptCharset());
charset = "iso-8859-5, unicode-1-1;q=0.8";
when(httpServletRequest.getHeader("accept-charset")).thenReturn(charset);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(charset, context.getAcceptCharset());
}
/**
* This is the default mode.
*
* We get a Content-Type: application/json and want to parse the incoming json.
*/
@Test
public void testParseBodyJsonWorks() {
when(httpServletRequest.getContentType()).thenReturn("application/json; charset=utf-8");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
when(bodyParserEngineManager.getBodyParserEngineForContentType("application/json")).thenReturn(bodyParserEngine);
when(bodyParserEngine.invoke(context, Dummy.class)).thenReturn(new Dummy());
Object o = context.parseBody(Dummy.class);
verify(bodyParserEngineManager).getBodyParserEngineForContentType("application/json");
assertTrue(o instanceof Dummy);
}
@Test
public void testParseBodyPostWorks() {
when(httpServletRequest.getContentType()).thenReturn(ContentTypes.APPLICATION_POST_FORM);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
when(bodyParserEngineManager.getBodyParserEngineForContentType(ContentTypes.APPLICATION_POST_FORM)).thenReturn(bodyParserEngine);
Dummy dummy = new Dummy();
dummy.name = "post";
dummy.count = 245L;
when(bodyParserEngine.invoke(context, Dummy.class)).thenReturn(dummy);
Dummy o = context.parseBody(Dummy.class);
verify(bodyParserEngineManager).getBodyParserEngineForContentType(ContentTypes.APPLICATION_POST_FORM);
assertTrue(o instanceof Dummy);
assertTrue(o.name.equals(dummy.name));
assertTrue(o.count.equals(dummy.count));
}
/**
* Test for isJson
*/
@Test
public void testIsJsonWorks() {
when(httpServletRequest.getContentType()).thenReturn(ContentTypes.APPLICATION_JSON);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
assertTrue(context.isRequestJson());
}
/**
* Test is isXml
*/
@Test
public void testIsXmlWorks() {
when(httpServletRequest.getContentType()).thenReturn(ContentTypes.APPLICATION_XML);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
assertTrue(context.isRequestXml());
}
/**
* This is the default mode.
*
* We get a Content-Type: application/json and want to parse the incoming json.
*/
@Test
public void testParseBodyXmlWorks() {
when(httpServletRequest.getContentType()).thenReturn("application/xml");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
when(bodyParserEngineManager.getBodyParserEngineForContentType("application/xml")).thenReturn(bodyParserEngine);
when(bodyParserEngine.invoke(context, Dummy.class)).thenReturn(new Dummy());
Object o = context.parseBody(Dummy.class);
verify(bodyParserEngineManager).getBodyParserEngineForContentType("application/xml");
assertTrue(o instanceof Dummy);
}
/**
* The request does not have the Content-Type set => we get a null response.
*/
@Test
public void testParseBodyWithUnkownContentTypeWorks() {
when(httpServletRequest.getContentType()).thenReturn(null);
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
Object o = context.parseBody(Dummy.class);
assertNull(o);
}
/**
* We get an conetnt type that does not match any registered parsers.
* This must also return null safely.
*/
@Test
public void testParseBodyWithUnknownRequestContentTypeWorks() {
when(httpServletRequest.getContentType()).thenReturn("application/UNKNOWN");
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
Object o = context.parseBody(Dummy.class);
assertNull(o);
}
// Dummy class used for parseBody tests.
class Dummy {
public String name;
public Long count;
}
/**
* Make sure the correct character encoding is set after init.
*/
@Test
public void testInitEnforcingOfCorrectEncoding() throws Exception {
context.init(servletContext, httpServletRequest, httpServletResponse);
//this proofs that the encoding has been set:
verify(httpServletRequest).setCharacterEncoding(NinjaConstant.UTF_8);
}
/**
* Make sure the correct character encoding is set before the
* reader is returned.
*/
@Test
public void testGetReaderEnforcingOfCorrectEncoding() throws Exception {
context.init(servletContext, httpServletRequest, httpServletResponse);
context.getReader();
//this proofs that the encoding has been set:
verify(httpServletRequest).setCharacterEncoding(anyString());
}
/**
* Make sure the correct character encoding is set before the
* inputStream is returned.
*/
@Test
public void testGetInputStreamEnforcingOfCorrectEncoding() throws Exception {
context.init(servletContext, httpServletRequest, httpServletResponse);
context.getInputStream();
//this proofs that the encoding has been set:
verify(httpServletRequest).setCharacterEncoding(anyString());
}
/**
* We get an conetnt type that does not match any registered parsers.
* This must also return null safely.
*/
@Test
public void testGetServletContext() {
//init the context from a (mocked) servlet
context.init(servletContext, httpServletRequest, httpServletResponse);
Object o = context.getServletContext();
assertNotNull(o);
assertEquals(servletContext, o);
}
@Test
public void testGetScheme() {
final String scheme = "http";
when(httpServletRequest.getScheme()).thenReturn(scheme);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(scheme, httpServletRequest.getScheme());
}
@Test
public void testIsMultipart() {
when(httpServletRequest.getContentType()).thenReturn("multipart/form-data");
when(httpServletRequest.getMethod()).thenReturn("POST");
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals(true, context.isMultipart());
}
@Test
public void testGetUTF8ParameterInMultipart() throws Exception {
String body = "------Ninja\r\n"
+ "Content-Disposition: form-data; name=\"utf8\"\r\n"
+ "\r\n"
+ "✓\r\n"
+ "------Ninja--\r\n";
ServletInputStream sis = createHttpServletRequestInputStream(body.getBytes(NinjaConstant.UTF_8));
when(httpServletRequest.getContentType()).thenReturn("multipart/form-data; boundary=----Ninja");
when(httpServletRequest.getMethod()).thenReturn("POST");
when(ninjaProperties.getIntegerWithDefault(NinjaConstant.UPLOADS_MAX_FILE_SIZE, -1)).thenReturn(1024);
when(ninjaProperties.getIntegerWithDefault(NinjaConstant.UPLOADS_MAX_TOTAL_SIZE, -1)).thenReturn(1024);
when(httpServletRequest.getInputStream()).thenReturn(sis);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals("✓", context.getParameter("utf8"));
}
@Test
public void testGetWindows1250ParameterInMultipart() throws Exception {
String body = "------Ninja\r\n"
+ "content-disposition: form-data; name=\"field1\"\r\n"
+ "content-type: text/plain; charset=windows-1250\r\n"
+ "content-transfer-encoding: quoted-printable\r\n"
+ "\r\n"
+ "Joe owes €100.\r\n"
+ "------Ninja--\r\n";
ServletInputStream sis = createHttpServletRequestInputStream(body.getBytes("windows-1250"));
when(httpServletRequest.getContentType()).thenReturn("multipart/form-data; boundary=----Ninja");
when(httpServletRequest.getMethod()).thenReturn("POST");
when(ninjaProperties.getIntegerWithDefault(NinjaConstant.UPLOADS_MAX_FILE_SIZE, -1)).thenReturn(1024);
when(ninjaProperties.getIntegerWithDefault(NinjaConstant.UPLOADS_MAX_TOTAL_SIZE, -1)).thenReturn(1024);
when(httpServletRequest.getInputStream()).thenReturn(sis);
context.init(servletContext, httpServletRequest, httpServletResponse);
assertEquals("Joe owes €100.", context.getParameter("field1"));
}
private ServletInputStream createHttpServletRequestInputStream(byte[] bytes) throws UnsupportedEncodingException {
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ServletInputStream sis = new ServletInputStream(){
@Override
public boolean isFinished() { return false; }
@Override
public boolean isReady() { return false; }
@Override
public void setReadListener(ReadListener readListener) { }
@Override
public int read() throws IOException { return bais.read(); }
};
return sis;
}
}