Java tutorial
/* * Copyright (c) 2012, Inversoft Inc., All Rights Reserved * * 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.primeframework.mvc.parameter; import org.apache.commons.io.FileUtils; import org.easymock.Capture; import org.easymock.EasyMock; import org.primeframework.mock.servlet.MockServletInputStream; import org.primeframework.mvc.parameter.fileupload.FileInfo; import org.primeframework.mvc.servlet.MockWorkflowChain; import org.primeframework.mvc.util.MapBuilder; import org.primeframework.mvc.util.RequestKeys; import org.primeframework.mvc.workflow.WorkflowChain; import org.testng.annotations.Test; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import static java.util.Arrays.asList; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; /** * This class tests the request body workflow. * * @author Brian Pontarelli */ public class RequestBodyWorkflowTest { @Test public void containerDrainedBody() throws IOException, ServletException { HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(new HashMap<>()); expect(request.getContentType()).andReturn("application/x-www-form-urlencoded"); expect(request.getInputStream()).andReturn(new MockServletInputStream(new byte[0])); expect(request.getContentLength()).andReturn(0); expect(request.getCharacterEncoding()).andReturn("UTF-8"); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); // This is the assert since the request would be unwrapped if the body contained parameters RequestBodyWorkflow workflow = new RequestBodyWorkflow(request); workflow.perform(chain); verify(request, chain); } @Test public void multipleFiles() throws IOException, ServletException { String body = FileUtils.readFileToString( new File("src/test/java/org/primeframework/mvc/servlet/http-test-body-multiple-files.txt")); HttpServletRequest request = EasyMock.createStrictMock(HttpServletRequest.class); EasyMock.expect(request.getParameterMap()).andReturn(new HashMap<>()); EasyMock.expect(request.getContentType()).andReturn("multipart/form-data, boundary=AaB03x").times(2); EasyMock.expect(request.getInputStream()).andReturn(new MockServletInputStream(body.getBytes())); EasyMock.expect(request.getCharacterEncoding()).andReturn("UTF-8"); EasyMock.expect(request.getContentLength()).andReturn(body.length()); final Capture<Map<String, List<FileInfo>>> capture = new Capture<>(); request.setAttribute(eq(RequestKeys.FILE_ATTRIBUTE), capture(capture)); EasyMock.replay(request); final AtomicBoolean run = new AtomicBoolean(false); MockWorkflowChain chain = new MockWorkflowChain(() -> { Map<String, List<FileInfo>> files = capture.getValue(); assertEquals(files.size(), 1); try { assertEquals(FileUtils.readFileToString(files.get("userfiles").get(0).file), "test"); assertEquals(FileUtils.readFileToString(files.get("userfiles").get(1).file), "test2"); } catch (IOException e) { throw new RuntimeException(e); } run.set(true); }); HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); RequestBodyWorkflow workflow = new RequestBodyWorkflow(wrapper); workflow.perform(chain); assertTrue(run.get()); assertEquals(wrapper.getParameter("field1"), "value1"); assertEquals(wrapper.getParameter("field2"), "value2"); EasyMock.verify(request); } @Test public void noContentType() throws IOException, ServletException { HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(null); expect(request.getContentType()).andReturn(null); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); RequestBodyWorkflow workflow = new RequestBodyWorkflow(request); workflow.perform(chain); verify(request, chain); } @Test public void parse() throws IOException, ServletException { HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(new HashMap<>()); expect(request.getContentType()).andReturn("application/x-www-form-urlencoded"); String body = "param1=value1¶m2=value2¶m+space+key=param+space+value¶m%2Bencoded%2Bkey=param%2Bencoded%2Bvalue"; expect(request.getInputStream()).andReturn(new MockServletInputStream(body.getBytes())); expect(request.getContentLength()).andReturn(body.getBytes().length); expect(request.getCharacterEncoding()).andReturn("UTF-8"); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); RequestBodyWorkflow workflow = new RequestBodyWorkflow(wrapper); workflow.perform(chain); @SuppressWarnings("unchecked") Map<String, String[]> actual = wrapper.getParameterMap(); Map<String, String[]> expected = MapBuilder.<String, String[]>map().put("param1", new String[] { "value1" }) .put("param2", new String[] { "value2" }) .put("param space key", new String[] { "param space value" }) .put("param+encoded+key", new String[] { "param+encoded+value" }).done(); assertParameterMapsEquals(actual, expected); verify(request, chain); } @Test public void parseCombine() throws IOException, ServletException { Map<String, String[]> oldParams = new HashMap<>(); oldParams.put("param1", new String[] { "oldvalue1", "oldvalue2" }); oldParams.put("param2", new String[] { "oldvalue3" }); String body = "param1=value1¶m1=value2¶m2=value3"; HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(oldParams); expect(request.getContentType()).andReturn("application/x-www-form-urlencoded"); expect(request.getInputStream()).andReturn(new MockServletInputStream(body.getBytes())); expect(request.getContentLength()).andReturn(body.getBytes().length); expect(request.getCharacterEncoding()).andReturn("UTF-8"); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); RequestBodyWorkflow workflow = new RequestBodyWorkflow(wrapper); workflow.perform(chain); @SuppressWarnings("unchecked") Map<String, String[]> actual = wrapper.getParameterMap(); Map<String, String[]> expected = MapBuilder.<String, String[]>map() .put("param1", new String[] { "oldvalue1", "oldvalue2", "value1", "value2" }) .put("param2", new String[] { "oldvalue3", "value3" }).done(); assertParameterMapsEquals(actual, expected); verify(request, chain); } @Test public void parseMultiple() throws IOException, ServletException { String body = "param1=value1¶m1=value2¶m2=value3"; HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(new HashMap<>()); expect(request.getContentType()).andReturn("application/x-www-form-urlencoded"); expect(request.getInputStream()).andReturn(new MockServletInputStream(body.getBytes())); expect(request.getContentLength()).andReturn(body.getBytes().length); expect(request.getCharacterEncoding()).andReturn("UTF-8"); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); RequestBodyWorkflow workflow = new RequestBodyWorkflow(wrapper); workflow.perform(chain); @SuppressWarnings("unchecked") Map<String, String[]> actual = wrapper.getParameterMap(); Map<String, String[]> expected = MapBuilder.<String, String[]>map() .put("param1", new String[] { "value1", "value2" }).put("param2", new String[] { "value3" }).done(); assertParameterMapsEquals(actual, expected); verify(request, chain); } @Test public void singleFiles() throws IOException, ServletException { String body = FileUtils.readFileToString( new File("src/test/java/org/primeframework/mvc/servlet/http-test-body-single-file.txt")); HttpServletRequest request = EasyMock.createStrictMock(HttpServletRequest.class); EasyMock.expect(request.getParameterMap()).andReturn(new HashMap<>()); EasyMock.expect(request.getContentType()).andReturn("multipart/form-data, boundary=AaB03x").times(2); EasyMock.expect(request.getInputStream()).andReturn(new MockServletInputStream(body.getBytes())); EasyMock.expect(request.getCharacterEncoding()).andReturn("UTF-8"); EasyMock.expect(request.getContentLength()).andReturn(body.length()); final Capture<Map<String, List<FileInfo>>> capture = new Capture<>(); request.setAttribute(eq(RequestKeys.FILE_ATTRIBUTE), capture(capture)); EasyMock.replay(request); final AtomicBoolean run = new AtomicBoolean(false); MockWorkflowChain chain = new MockWorkflowChain(() -> { Map<String, List<FileInfo>> files = capture.getValue(); assertEquals(files.size(), 1); try { assertEquals(FileUtils.readFileToString(files.get("userfile").get(0).file), "test"); } catch (IOException e) { throw new RuntimeException(e); } run.set(true); }); HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request); RequestBodyWorkflow workflow = new RequestBodyWorkflow(wrapper); workflow.perform(chain); assertTrue(run.get()); assertEquals(wrapper.getParameter("field1"), "value1"); assertEquals(wrapper.getParameter("field2"), "value2"); EasyMock.verify(request); } @Test public void wrongContentType() throws IOException, ServletException { HttpServletRequest request = createStrictMock(HttpServletRequest.class); expect(request.getParameterMap()).andReturn(null); expect(request.getContentType()).andReturn("text/xml"); replay(request); WorkflowChain chain = createStrictMock(WorkflowChain.class); chain.continueWorkflow(); replay(chain); RequestBodyWorkflow workflow = new RequestBodyWorkflow(request); workflow.perform(chain); verify(request, chain); } private void assertParameterMapsEquals(Map<String, String[]> actual, Map<String, String[]> expected) { assertEquals(actual.size(), expected.size(), "Maps have different sizes. Key difference is: " + keyDiff(actual, expected) + "\nActual: " + actual + "\nExpected: " + expected); assertEquals(actual.keySet(), expected.keySet(), "Maps have different keys"); for (String key : actual.keySet()) { assertEquals(actual.get(key), expected.get(key), "Maps have different arrays for key [" + key + "]\nActual: " + asList(actual.get(key)) + "\nExpected: " + asList(expected.get(key))); } } private String keyDiff(Map<String, String[]> actual, Map<String, String[]> expected) { Set<String> finalSet = new HashSet<>(); finalSet.addAll(actual.keySet()); finalSet.removeAll(expected.keySet()); finalSet.addAll(expected.keySet()); finalSet.removeAll(actual.keySet()); return finalSet.toString(); } }