/* * Copyright (C) 2014 Civilian Framework. * * Licensed under the Civilian License (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.civilian-framework.org/license.txt * * 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.civilian.context.servlet; import static org.mockito.Mockito.*; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Part; import org.civilian.CivTest; import org.civilian.Request; import org.civilian.content.ContentType; import org.civilian.content.ContentTypeList; import org.civilian.context.servlet.MpRequestAdapter; import org.civilian.context.servlet.ServletResponseAdapter; import org.civilian.context.servlet.SpRequestAdapter; import org.civilian.context.test.TestApp; import org.civilian.request.AsyncContext; import org.civilian.request.RequestHeaders; import org.civilian.request.RequestSecurity; import org.civilian.request.Upload; import org.civilian.request.RequestSecurity.SessionIdSource; import org.civilian.type.TypeLib; import org.civilian.util.Iterators; import org.civilian.util.Value; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class ServletRequestTest extends CivTest { @BeforeClass public static void beforeClass() { app = new TestApp(); app.getConfig().setSupportedLocales(Locale.ENGLISH); app.init("/app"); } @Before public void before() { servletReq = mock(HttpServletRequest.class); when(servletReq.getLocale()).thenReturn(Locale.ENGLISH); request = null; } private void init() { request = new SpRequestAdapter(app, servletReq); response = new ServletResponseAdapter(request, null); } @Test public void testAccessors() throws Exception { when(servletReq.getMethod()).thenReturn("GET"); init(); assertSame(app, request.getApplication()); assertSame(servletReq, request.getServletRequest()); assertSame(servletReq, request.unwrap(ServletRequest.class)); assertEquals("GET", request.getMethod()); assertTrue( request.hasMethod(Request.Method.GET)); assertFalse( request.hasMethod(Request.Method.POST)); request.getCookies(); verify(servletReq).getCookies(); } @Test public void testPath() throws Exception { when(servletReq.getPathInfo()).thenReturn("/alpha"); when(servletReq.getRequestURI()).thenReturn("/app/alpha"); when(servletReq.getRequestURL()).thenReturn(new StringBuffer("http:test//app/alpha")); when(servletReq.getParameterNames()).thenReturn(getEnum("a")); when(servletReq.getParameterValues("a")).thenReturn(new String[] { "1", "2" }); init(); assertEquals("/app/alpha", request.getPath().toString()); assertEquals("/app/alpha", request.getOriginalPath()); assertEquals("/alpha", request.getRelativePath().toString()); assertEquals("/app/alpha?a=1&a=2", request.getUrl(false, true).toString()); assertEquals("/app/alpha", request.getUrl(false, false).toString()); } @Test public void testAttributes() throws Exception { init(); request.setAttribute("x", "y"); verify(servletReq).setAttribute("x", "y"); when(servletReq.getAttribute("x")).thenReturn("y"); assertEquals("y", request.getAttribute("x")); request.getAttributeNames(); verify(servletReq).getAttributeNames(); } @Test public void testParameters() throws Exception { String[] aParamValues = { "1", "2"}; when(servletReq.getParameter("id")).thenReturn("15"); when(servletReq.getParameter("a")).thenReturn("1"); when(servletReq.getParameterValues("a")).thenReturn(aParamValues); init(); assertEquals("15", request.getParameter("id")); assertEquals(15, request.getParameter("id", TypeLib.INTEGER).getValue().intValue()); assertEquals("1", request.getParameter("a")); assertEquals(null, request.getParameter("b")); assertArrayEquals(aParamValues, request.getParameters("a")); assertEquals(0, request.getParameters("b").length); } @Test public void testMatrixParams() throws Exception { String[] aParamValues = { "1", "2"}; // test extension and matrix parameters when(servletReq.getPathInfo()).thenReturn("/alpha.html"); when(servletReq.getRequestURI()).thenReturn("/app;ignored=1/alpha.html;x=y;z;mp=1;mp=2"); init(); assertEquals("/app/alpha.html", request.getPath().toString()); assertEquals("y", request.getMatrixParam("x")); assertEquals("", request.getMatrixParam("z")); assertEquals("1", request.getMatrixParam("mp")); assertNull( request.getMatrixParam("p")); assertArrayEquals(aParamValues, request.getMatrixParams("mp")); assertEquals(1, request.getMatrixParam("mp", TypeLib.INTEGER).getValue().intValue()); HashSet<String> mpNames = new HashSet<>(); request.getMatrixParamNames().forEachRemaining(mpNames::add); assertTrue(mpNames.contains("mp")); assertTrue(mpNames.contains("x")); assertTrue(mpNames.contains("z")); assertEquals(3, mpNames.size()); } @SuppressWarnings("boxing") @Test public void testContent() throws Exception { init(); when(servletReq.getContentLength()).thenReturn(20); assertEquals(20L, request.getContentLength()); assertEquals(null, request.getContentEncoding()); when(servletReq.getCharacterEncoding()).thenReturn("UTF-8"); assertEquals("UTF-8", request.getContentEncoding()); request.setContentEncoding("UTF-8"); verify(servletReq).setCharacterEncoding("UTF-8"); assertNull(request.getContentType()); when(servletReq.getContentType()).thenReturn("text/html; charset=UTF-8"); assertSame(ContentType.TEXT_HTML, request.getContentType()); when(servletReq.getContentType()).thenReturn("text/css"); assertSame(ContentType.TEXT_CSS, request.getContentType()); request.getContentStream(); verify(servletReq).getInputStream(); request.getContentReader(); verify(servletReq).getReader(); } @Test public void testAsyncInfo() throws Exception { init(); request.isAsyncSupported(); verify(servletReq).isAsyncSupported(); assertFalse(request.isAsyncStarted()); AsyncContext context = request.startAsync(); verify(servletReq).startAsync(any(ServletRequest.class), any(ServletResponse.class)); assertSame(context, request.getAsyncContext()); assertTrue(request.isAsyncStarted()); } @SuppressWarnings("boxing") @Test public void testHeaders() throws Exception { String[] array = new String[] { "1", "2" }; when(servletReq.getHeader("x")).thenReturn("abc"); when(servletReq.getHeader("i")).thenReturn("123"); when(servletReq.getHeader("d")).thenReturn("123.45"); when(servletReq.getDateHeader("l")).thenReturn(3344L); when(servletReq.getHeaders("a")).thenReturn(getEnum(array)); when(servletReq.getHeaderNames()).thenReturn(getEnum("b", "c")); init(); RequestHeaders headers = request.getHeaders(); assertEquals("abc", headers.get("x")); assertTrue (headers.is("x", "abc")); assertFalse(headers.is("x", "123")); assertTrue (headers.is("y", null)); assertFalse(headers.is("y", "456")); assertEquals(123, headers.getInt("i")); Value<Double> d = headers.get("d", TypeLib.DOUBLE); assertEquals(123.45d, d.getValue().doubleValue(), 0.0); assertEquals(123, headers.getInt("i")); assertEquals(3344L, headers.getDate("l")); assertArrayEquals2(array, headers.getAll("a")); Iterator<String> names = headers.iterator(); assertEquals("b", names.next()); assertEquals("c", names.next()); assertFalse(names.hasNext()); when(servletReq.getHeaders("Accept")).thenReturn(getEnum("*/*;q=0.8,text/html,application/xml;q=0.9")); ContentTypeList types = request.getAcceptedContentTypes(); assertSame(types, request.getAcceptedContentTypes()); assertEquals(3, types.size()); assertSame(ContentType.TEXT_HTML, types.get(0)); } @Test public void testExtensionMapping() throws Exception { app.getResourceConfig().getExtensionMapping().addContentType("xyz", ContentType.APPLICATION_PDF); when(servletReq.getHeaders("Accept")).thenReturn(getEnum()); when(servletReq.getPathInfo()).thenReturn("/alpha.xyz"); init(); ContentTypeList types = request.getAcceptedContentTypes(); assertEquals(1, types.size()); assertSame(ContentType.APPLICATION_PDF, types.get(0)); } @Test public void testLocale() throws Exception { when(servletReq.getPathInfo()).thenReturn("/alpha.fr"); init(); assertSame(Locale.ENGLISH, request.getAcceptedLocale()); verify(servletReq).getHeader("Accept-Language"); app.getResourceConfig().getExtensionMapping().addLocale("fr", Locale.FRENCH); assertSame(Locale.FRENCH, request.getAcceptedLocale()); verify(servletReq, times(2)).getHeader("Accept-Language"); when(servletReq.getHeader("Accept-Language")).thenReturn("de"); when(servletReq.getLocale()).thenReturn(Locale.GERMAN); assertEquals(Locale.GERMAN, request.getAcceptedLocale()); verify(servletReq, times(3)).getHeader("Accept-Language"); verify(servletReq, times(1)).getLocale(); } @SuppressWarnings("boxing") @Test public void testSecurity() throws Exception { init(); RequestSecurity security = request.getSecurity(); security.isSecure(); verify(servletReq).isSecure(); security.authenticate(); verify(servletReq).authenticate(request.getServletResponse()); security.getAuthType(); verify(servletReq).getAuthType(); security.getUserPrincipal(); verify(servletReq).getUserPrincipal(); security.isUserInRole("x"); verify(servletReq).isUserInRole("x"); security.login("a", "b"); verify(servletReq).login("a", "b"); security.logout(); verify(servletReq).logout(); security.getRequestedSessionId(); verify(servletReq).getRequestedSessionId(); request.getSession(false); verify(servletReq).getSession(false); assertEquals(SessionIdSource.NONE, security.getRequestedSessionIdSource()); when(servletReq.isRequestedSessionIdFromURL()).thenReturn(true); assertEquals(SessionIdSource.FROM_URL, security.getRequestedSessionIdSource()); when(servletReq.isRequestedSessionIdFromCookie()).thenReturn(true); assertEquals(SessionIdSource.FROM_COOKIE, security.getRequestedSessionIdSource()); security.isRequestedSessionIdValid(); verify(servletReq).isRequestedSessionIdValid(); } @SuppressWarnings("boxing") @Test public void testMultiPart() throws Exception { when(servletReq.getPathInfo()).thenReturn("/multi"); init(); // uploads assertFalse(request.hasUploads()); assertNull (request.getUpload("file")); assertFalse(request.getUploadNames().hasNext()); assertNull (request.getUploadError()); Part part1 = mock(Part.class); Part part2 = mock(Part.class); when(part1.getHeader("Content-Disposition")).thenReturn("form-data; name=\"email\""); when(part1.getInputStream()).thenReturn(new ByteArrayInputStream("John".getBytes())); when(part1.getSize()).thenReturn(4L); when(part1.getName()).thenReturn("email"); when(part2.getHeader("Content-Disposition")).thenReturn("form-data; name=\"photo\"; filename=\"/temp/photo.jpg\""); when(part2.getInputStream()).thenReturn(new ByteArrayInputStream("jpg".getBytes())); when(part2.getSize()).thenReturn(3L); when(part2.getName()).thenReturn("photo"); ArrayList<Part> parts = new ArrayList<>(); parts.add(part1); parts.add(part2); when(servletReq.getParts()).thenReturn(parts); MpRequestAdapter request = new MpRequestAdapter(app, servletReq); assertEquals(null, request.getParameter("dummy")); assertEquals("John", request.getParameter("email")); assertEquals("photo.jpg", request.getParameter("photo")); assertTrue(request.hasUploads()); assertNull(request.getUpload("dummy")); assertNull(request.getUploadError()); Upload upload = request.getUpload("photo"); assertNotNull(upload); assertEquals(3L, upload.length()); } @SuppressWarnings("boxing") @Test public void testRequestInfos() { when(servletReq.getProtocol()).thenReturn("HTTP 1.0"); when(servletReq.getScheme()).thenReturn("http"); when(servletReq.getProtocol()).thenReturn("http"); when(servletReq.getServerName()).thenReturn("host"); when(servletReq.getServerPort()).thenReturn(8080); when(servletReq.getRemoteAddr()).thenReturn("1.2.3.4"); when(servletReq.getRemoteHost()).thenReturn("remote"); when(servletReq.getRemoteUser()).thenReturn("user"); when(servletReq.getRemotePort()).thenReturn(2345); when(servletReq.getLocalAddr()).thenReturn("5.5.5.5"); when(servletReq.getLocalName()).thenReturn("local"); when(servletReq.getLocalPort()).thenReturn(70); init(); assertEquals("http://host:8080", request.getServerInfo().toString()); assertEquals("http", request.getServerInfo().getProtocol()); assertEquals("user@remote:2345", request.getRemoteInfo().toString()); assertEquals("1.2.3.4", request.getRemoteInfo().getIp()); assertEquals("local:70", request.getLocalInfo().toString()); assertEquals("5.5.5.5", request.getLocalInfo().getIp()); } private Enumeration<String> getEnum(String... values) { Iterator<String> it = Iterators.forValues(values); // temp variable for javac return Iterators.asEnumeration(it); } private static TestApp app; private HttpServletRequest servletReq; private SpRequestAdapter request; @SuppressWarnings("unused") private ServletResponseAdapter response; }