/** * XWeb project * Created by Hamed Abdollahpour * https://github.com/abdollahpour/xweb */ package ir.xweb.test.module; import ir.xweb.module.GzipModule; import ir.xweb.module.Manager; import ir.xweb.module.ModuleParam; import ir.xweb.module.ResourceModule; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import javax.servlet.FilterChain; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import static org.mockito.Mockito.*; import static org.testng.Assert.*; public class TestGzipModule { private final TestModules modules; public TestGzipModule(final TestModules modules) { this.modules = modules; } public void test(final boolean zip) throws IOException, ServletException { final HashMap<String, Object> params = new HashMap<String, Object>(); params.put("api", "empty2"); params.put("key1", "value1"); final String data = "this is test"; final byte[] bytes = data.getBytes(); final byte[] zipped = zip(bytes); final HttpServletRequest request = mock(HttpServletRequest.class); when(request.getContextPath()).thenReturn(""); when(request.getRequestURI()).thenReturn("/api"); when(request.getParameter(anyString())).thenAnswer(new Answer<String>() { @Override public String answer(InvocationOnMock invocation) throws Throwable { final Object[] args = invocation.getArguments(); final String arg = (String) args[0]; return (String) params.get(arg); } }); when(request.getParameterNames()).thenReturn( new IteratorEnumeration(params.keySet().iterator())); if(zip) { when(request.getInputStream()).thenReturn(new RequestInput(zipped)); when(request.getHeader("Content-Encoding")).thenReturn("gzip"); when(request.getHeader("Accept-Encoding")).thenReturn("gzip"); } else { when(request.getInputStream()).thenReturn(new RequestInput(bytes)); } final ResponseOut out = new ResponseOut(); final HttpServletResponse response = mock(HttpServletResponse.class); when(response.getOutputStream()).thenReturn(out); when(response.getCharacterEncoding()).thenReturn("UTF-8"); when(modules.getServletContext().getRealPath(anyString())).thenReturn(""); final EmptyModule2 module = modules.getManager().getModuleOrThrow(EmptyModule2.class); final GzipModule gzip = modules.getManager().getModuleOrThrow(GzipModule.class); final TestChain chain = new TestChain(); gzip.doFilter(modules.getServletContext(), request, response, chain); module.process( modules.getServletContext(), (HttpServletRequest) chain.request, (HttpServletResponse) chain.response, new ModuleParam(params), null); chain.response.flushBuffer(); final byte[] outData = out.baos.toByteArray(); if(zip) { verify(response, times(1)).addHeader(eq("Content-Encoding"), eq("gzip")); assertEquals(data, new String(unzip(outData))); } else { verify(response, times(0)).addHeader(eq("Content-Encoding"), eq("gzip")); assertEquals(data, new String(outData)); } } private class TestChain implements FilterChain { ServletRequest request; ServletResponse response; @Override public void doFilter( final ServletRequest servletRequest, final ServletResponse servletResponse) throws IOException, ServletException { this.request = servletRequest; this.response = servletResponse; } boolean done() { return this.request != null || this.response != null; } } private class IteratorEnumeration<E> implements Enumeration<E> { private final Iterator<E> iterator; public IteratorEnumeration(Iterator<E> iterator) { this.iterator = iterator; } public E nextElement() { return iterator.next(); } public boolean hasMoreElements() { return iterator.hasNext(); } } private byte[] zip(final byte[] data) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final GZIPOutputStream gos = new GZIPOutputStream(baos); gos.write(data); gos.finish(); gos.flush(); gos.close(); return baos.toByteArray(); } private byte[] unzip(final byte[] data) throws IOException { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ByteArrayInputStream bais = new ByteArrayInputStream(data); final GZIPInputStream gis = new GZIPInputStream(bais); byte[] buffer = new byte[1024]; int size; while((size = gis.read(buffer)) > 0) { baos.write(buffer, 0, size); } gis.close(); return baos.toByteArray(); } private class RequestInput extends ServletInputStream { ByteArrayInputStream bais; RequestInput(final byte[] data) { bais = new ByteArrayInputStream(data); } @Override public int read() throws IOException { return bais.read(); } } private class ResponseOut extends ServletOutputStream { ByteArrayOutputStream baos = new ByteArrayOutputStream(); @Override public void write(int b) throws IOException { baos.write(b); } } }