This commit is contained in:
Shihab Uddin
2012-09-26 11:17:30 +02:00
625 changed files with 42993 additions and 14410 deletions
@@ -1,13 +1,15 @@
package com.twelvemonkeys.servlet;
import com.twelvemonkeys.lang.ObjectAbstractTestCase;
import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.*;
import org.junit.Test;
import javax.servlet.*;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import static org.junit.Assert.*;
/**
* FilterAbstractTestCase
@@ -45,6 +47,7 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
return new MockFilterChain();
}
@Test
public void testInitNull() {
Filter filter = makeFilter();
@@ -65,6 +68,7 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
}
@Test
public void testInit() {
Filter filter = makeFilter();
@@ -79,6 +83,7 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
}
@Test
public void testLifeCycle() throws ServletException {
Filter filter = makeFilter();
@@ -90,6 +95,7 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
}
@Test
public void testFilterBasic() throws ServletException, IOException {
Filter filter = makeFilter();
@@ -103,22 +109,19 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
}
@Test
public void testDestroy() {
// TODO: Implement
}
static class MockFilterConfig implements FilterConfig {
private final Map mParams;
private final Map<String, String> params;
MockFilterConfig() {
this(new HashMap());
}
MockFilterConfig(Map pParams) {
MockFilterConfig(Map<String, String> pParams) {
if (pParams == null) {
throw new IllegalArgumentException("params == null");
}
mParams = pParams;
params = pParams;
}
public String getFilterName() {
@@ -126,11 +129,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
public String getInitParameter(String pName) {
return (String) mParams.get(pName);
return params.get(pName);
}
public Enumeration getInitParameterNames() {
return Collections.enumeration(mParams.keySet());
return Collections.enumeration(params.keySet());
}
public ServletContext getServletContext() {
@@ -138,20 +141,20 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
private static class MockServletContext implements ServletContext {
private final Map mAttributes;
private final Map mParams;
private final Map<String, Object> attributes;
private final Map<String, String> params;
MockServletContext() {
mAttributes = new HashMap();
mParams = new HashMap();
attributes = new HashMap<String, Object>();
params = new HashMap<String, String>();
}
public Object getAttribute(String s) {
return mAttributes.get(s);
return attributes.get(s);
}
public Enumeration getAttributeNames() {
return Collections.enumeration(mAttributes.keySet());
return Collections.enumeration(attributes.keySet());
}
public ServletContext getContext(String s) {
@@ -159,11 +162,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
public String getInitParameter(String s) {
return (String) mParams.get(s);
return (String) params.get(s);
}
public Enumeration getInitParameterNames() {
return Collections.enumeration(mParams.keySet());
return Collections.enumeration(params.keySet());
}
public int getMajorVersion() {
@@ -223,40 +226,37 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
public void log(Exception exception, String s) {
// TODO: Implement
}
public void log(String s) {
// TODO: Implement
}
public void log(String s, Throwable throwable) {
// TODO: Implement
}
public void removeAttribute(String s) {
mAttributes.remove(s);
attributes.remove(s);
}
public void setAttribute(String s, Object obj) {
mAttributes.put(s, obj);
attributes.put(s, obj);
}
}
}
static class MockServletRequest implements ServletRequest {
final private Map mAttributes;
final private Map<String, Object> attributes;
public MockServletRequest() {
mAttributes = new HashMap();
attributes = new HashMap<String, Object>();
}
public Object getAttribute(String pKey) {
return mAttributes.get(pKey);
return attributes.get(pKey);
}
public Enumeration getAttributeNames() {
return Collections.enumeration(mAttributes.keySet());
return Collections.enumeration(attributes.keySet());
}
public String getCharacterEncoding() {
@@ -324,11 +324,11 @@ public abstract class FilterAbstractTestCase extends ObjectAbstractTestCase {
}
public void setAttribute(String pKey, Object pValue) {
mAttributes.put(pKey, pValue);
attributes.put(pKey, pValue);
}
public void removeAttribute(String pKey) {
mAttributes.remove(pKey);
attributes.remove(pKey);
}
public Locale getLocale() {
@@ -1,10 +1,13 @@
package com.twelvemonkeys.servlet;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import org.junit.Test;
import javax.servlet.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* GenericFilterTestCase
@@ -19,6 +22,7 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
return new GenericFilterImpl();
}
@Test
public void testInitOncePerRequest() {
// Default FALSE
GenericFilter filter = new GenericFilterImpl();
@@ -30,12 +34,12 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
fail(e.getMessage());
}
assertFalse("OncePerRequest should default to false", filter.mOncePerRequest);
assertFalse("OncePerRequest should default to false", filter.oncePerRequest);
filter.destroy();
// TRUE
filter = new GenericFilterImpl();
Map params = new HashMap();
Map<String, String> params = new HashMap<String, String>();
params.put("once-per-request", "true");
try {
@@ -45,12 +49,12 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
fail(e.getMessage());
}
assertTrue("oncePerRequest should be true", filter.mOncePerRequest);
assertTrue("oncePerRequest should be true", filter.oncePerRequest);
filter.destroy();
// TRUE
filter = new GenericFilterImpl();
params = new HashMap();
params = new HashMap<String, String>();
params.put("oncePerRequest", "true");
try {
@@ -60,10 +64,11 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
fail(e.getMessage());
}
assertTrue("oncePerRequest should be true", filter.mOncePerRequest);
assertTrue("oncePerRequest should be true", filter.oncePerRequest);
filter.destroy();
}
@Test
public void testFilterOnlyOnce() {
final GenericFilterImpl filter = new GenericFilterImpl();
filter.setOncePerRequest(true);
@@ -92,6 +97,7 @@ public final class GenericFilterTestCase extends FilterAbstractTestCase {
filter.destroy();
}
@Test
public void testFilterMultiple() {
final GenericFilterImpl filter = new GenericFilterImpl();
@@ -1,11 +1,12 @@
package com.twelvemonkeys.servlet;
import com.twelvemonkeys.io.NullOutputStream;
import junit.framework.TestCase;
import org.junit.Test;
import java.io.PrintWriter;
import static org.junit.Assert.*;
/**
* ServletConfigExceptionTestCase
*
@@ -13,7 +14,8 @@ import java.io.PrintWriter;
* @author last modified by $Author: haku $
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletConfigExceptionTestCase.java#2 $
*/
public class ServletConfigExceptionTestCase extends TestCase {
public class ServletConfigExceptionTestCase {
@Test
public void testThrowCatchPrintStacktrace() {
try {
throw new ServletConfigException("FooBar!");
@@ -23,6 +25,7 @@ public class ServletConfigExceptionTestCase extends TestCase {
}
}
@Test
public void testThrowCatchGetNoCause() {
try {
throw new ServletConfigException("FooBar!");
@@ -35,6 +38,7 @@ public class ServletConfigExceptionTestCase extends TestCase {
}
}
@Test
public void testThrowCatchInitCauseNull() {
try {
ServletConfigException e = new ServletConfigException("FooBar!");
@@ -49,6 +53,7 @@ public class ServletConfigExceptionTestCase extends TestCase {
}
}
@Test
public void testThrowCatchInitCause() {
//noinspection ThrowableInstanceNeverThrown
Exception cause = new Exception();
@@ -66,6 +71,7 @@ public class ServletConfigExceptionTestCase extends TestCase {
}
}
@Test
public void testThrowCatchGetNullCause() {
try {
throw new ServletConfigException("FooBar!", null);
@@ -78,6 +84,7 @@ public class ServletConfigExceptionTestCase extends TestCase {
}
}
@Test
public void testThrowCatchGetCause() {
IllegalStateException cause = new IllegalStateException();
try {
@@ -35,7 +35,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
}
private static class TestConfig implements ServletConfig, FilterConfig, ServletContext, Serializable, Cloneable {
Map mMap = new HashMap();
Map map = new HashMap();
public String getServletName() {
return "dummy"; // Not needed for this test
@@ -55,12 +55,12 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
}
public String getInitParameter(String s) {
return (String) mMap.get(s);
return (String) map.get(s);
}
public Enumeration getInitParameterNames() {
//noinspection unchecked
return Collections.enumeration(mMap.keySet());
return Collections.enumeration(map.keySet());
}
public ServletContext getContext(String uripath) {
@@ -157,7 +157,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
public Map makeFullMap() {
ServletConfig config = new TestConfig();
addSampleMappings(((TestConfig) config).mMap);
addSampleMappings(((TestConfig) config).map);
return new ServletConfigMapAdapter(config);
}
}
@@ -171,7 +171,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
public Map makeFullMap() {
FilterConfig config = new TestConfig();
addSampleMappings(((TestConfig) config).mMap);
addSampleMappings(((TestConfig) config).map);
return new ServletConfigMapAdapter(config);
}
}
@@ -185,7 +185,7 @@ public abstract class ServletConfigMapAdapterTestCase extends MapAbstractTestCas
public Map makeFullMap() {
FilterConfig config = new TestConfig();
addSampleMappings(((TestConfig) config).mMap);
addSampleMappings(((TestConfig) config).map);
return new ServletConfigMapAdapter(config);
}
}
@@ -0,0 +1,346 @@
package com.twelvemonkeys.servlet;
import org.junit.Test;
import org.mockito.Matchers;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import java.util.Arrays;
import java.util.Collections;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* ServletConfiguratorTestCase
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: ServletConfiguratorTestCase.java,v 1.0 May 2, 2010 3:08:33 PM haraldk Exp$
*/
public class ServletConfiguratorTestCase {
// TODO: Test error conditions:
// - Missing name = ... or non-bean conforming method
// - Non-accessible? How..?
// - Missing required value
// TODO: Clean up tests to test only one thing at a time
// - Public method
// - Public method with override
// - Public method overridden without annotation
// - Protected method
// - Protected method with override
// - Protected method overridden without annotation
// - Package protected method
// - Package protected method with override
// - Package protected method overridden without annotation
// - Private method
// - Multiple private methods with same signature (should invoke all, as private methods can't be overridden)
@Test
public void testConfigureAnnotatedServlet() throws ServletConfigException {
AnnotatedServlet servlet = mock(AnnotatedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar")));
when(config.getInitParameter("x")).thenReturn("99");
when(config.getInitParameter("foo")).thenReturn("Foo");
when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setX(99);
verify(servlet, times(1)).setFoo("Foo");
verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
}
@Test
public void testConfigureAnnotatedFilter() throws ServletConfigException {
AnnotatedServlet servlet = mock(AnnotatedServlet.class);
FilterConfig config = mock(FilterConfig.class);
when(config.getFilterName()).thenReturn("FooFilter");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar")));
when(config.getInitParameter("x")).thenReturn("99");
when(config.getInitParameter("foo")).thenReturn("Foo");
when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setX(99);
verify(servlet, times(1)).setFoo("Foo");
verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
}
@Test
public void testConfigurePrivateMethod() throws ServletConfigException {
AnnotatedServlet servlet = mock(AnnotatedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("private")));
when(config.getInitParameter("private")).thenReturn("99");
ServletConfigurator.configure(servlet, config);
// Verify
assertEquals(servlet.priv, "99");
}
@Test
public void testConfigurePrivateShadowedMethod() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam(name = "package-private")
abstract void setPrivate(String priv);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("private")));
when(config.getInitParameter("private")).thenReturn("private");
when(config.getInitParameter("package-private")).thenReturn("package");
ServletConfigurator.configure(servlet, config);
// Verify
assertEquals(servlet.priv, "private");
verify(servlet, times(1)).setPrivate("package");
}
@Test
public void testConfigureSubclassedServlet() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam(name = "flag")
abstract void configureMeToo(boolean flag);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo", "bar", "flag")));
when(config.getInitParameter("x")).thenReturn("99");
when(config.getInitParameter("foo")).thenReturn("Foo");
when(config.getInitParameter("bar")).thenReturn("-1, 2, 0, 42");
when(config.getInitParameter("flag")).thenReturn("true");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setX(99);
verify(servlet, times(1)).setFoo("Foo");
verify(servlet, times(1)).configTheBar(-1, 2, 0, 42);
verify(servlet, times(1)).configureMeToo(true);
}
@Test
public void testConfigureAnnotatedServletWithLispStyle() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam(name = "the-explicit-x")
abstract public void setExplicitX(int x);
@InitParam
abstract public void setTheOtherX(int x);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("the-explicit-x", "the-other-x")));
when(config.getInitParameter("the-explicit-x")).thenReturn("-1");
when(config.getInitParameter("the-other-x")).thenReturn("42");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setExplicitX(-1);
verify(servlet, times(1)).setTheOtherX(42);
}
@Test
public void testConfigureSubclassedServletWithOverride() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@Override
@InitParam(name = "y")
public void setX(int x) {
}
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "y")));
when(config.getInitParameter("x")).thenReturn("99");
when(config.getInitParameter("y")).thenReturn("-66");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setX(-66);
verify(servlet, times(1)).setX(anyInt()); // We don't want multiple invocations, only the overridden method
}
@Test
public void testConfigureSubclassedServletWithOverrideNoParam() throws ServletConfigException {
// NOTE: We must allow overriding the methods without annotation present, in order to allow CGLib/proxies of the class...
abstract class SubclassedServlet extends AnnotatedServlet {
@Override
@InitParam(name = "<THIS PARAMETER DOES NOT EXIST>")
public void setX(int x) {
}
@Override
public void setFoo(String foo) {
}
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("x", "foo")));
when(config.getInitParameter("x")).thenReturn("99");
when(config.getInitParameter("foo")).thenReturn("Foo");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, never()).setX(anyInt());
verify(servlet, times(1)).setFoo("Foo");
verify(servlet, times(1)).setFoo(Matchers.<String>any()); // We don't want multiple invocations
}
// Test interface
@Test
public void testConfigureServletWithInterface() throws ServletConfigException {
abstract class InterfacedServlet implements Servlet, Annotated {
}
InterfacedServlet servlet = mock(InterfacedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("foo")));
when(config.getInitParameter("foo")).thenReturn("Foo");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).annotated("Foo");
}
// TODO: Test override/shadow of package protected method outside package
@Test
public void testRequiredParameter() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam(required = true)
abstract void setRequired(String value);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("required")));
when(config.getInitParameter("required")).thenReturn("the required value");
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setRequired("the required value");
verify(servlet, times(1)).setRequired(Matchers.<String>any()); // We don't want multiple invocations
}
@Test
public void testMissingParameter() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam()
abstract void setNonRequired(String value);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.<Object>emptyList()));
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, never()).setNonRequired(Matchers.<String>any()); // Simply not configured
}
@Test(expected = ServletConfigException.class)
public void testMissingRequiredParameter() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@Override
@InitParam(required = true)
protected abstract void setFoo(String value);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.<Object>emptyList()));
ServletConfigurator.configure(servlet, config); // Should throw exception
}
@Test
public void testMissingParameterDefaultValue() throws ServletConfigException {
abstract class SubclassedServlet extends AnnotatedServlet {
@InitParam(defaultValue = "1, 2, 3")
abstract void setNonRequired(int[] value);
}
SubclassedServlet servlet = mock(SubclassedServlet.class);
ServletConfig config = mock(ServletConfig.class);
when(config.getServletName()).thenReturn("FooServlet");
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.<Object>emptyList()));
ServletConfigurator.configure(servlet, config);
// Verify
verify(servlet, times(1)).setNonRequired(new int[] {1, 2, 3});
verify(servlet, times(1)).setNonRequired(Matchers.<int[]>any());
}
public interface Annotated {
@InitParam(name = "foo")
public void annotated(String an);
}
public abstract class AnnotatedServlet implements Servlet, Filter {
String priv;
// Implicit name "x"
@InitParam
public abstract void setX(int x);
// Implicit name "foo"
@InitParam
protected abstract void setFoo(String foo);
@InitParam(name = "bar")
abstract void configTheBar(int... bar);
@InitParam(name = "private")
private void setPrivate(String priv) {
this.priv = priv;
}
}
}
@@ -1,20 +1,21 @@
package com.twelvemonkeys.servlet;
import com.twelvemonkeys.util.MapAbstractTestCase;
import org.jmock.Mock;
import org.jmock.core.Invocation;
import org.jmock.core.Stub;
import org.jmock.core.stub.CustomStub;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import static org.mockito.Mockito.when;
/**
* ServletConfigMapAdapterTestCase
* <p/>
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-servlet/src/test/java/com/twelvemonkeys/servlet/ServletHeadersMapAdapterTestCase.java#1 $
* @version $Id: ServletHeadersMapAdapterTestCase.java#1 $
*/
public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase {
private static final List<String> HEADER_VALUE_ETAG = Arrays.asList("\"1234567890abcdef\"");
@@ -43,24 +44,21 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase {
}
public Map makeEmptyMap() {
Mock mockRequest = mock(HttpServletRequest.class);
mockRequest.stubs().method("getHeaderNames").will(returnValue(Collections.enumeration(Collections.emptyList())));
mockRequest.stubs().method("getHeaders").will(returnValue(null));
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getHeaderNames()).thenAnswer(returnEnumeration(Collections.emptyList()));
return new SerlvetHeadersMapAdapter((HttpServletRequest) mockRequest.proxy());
return new ServletHeadersMapAdapter(request);
}
@Override
public Map makeFullMap() {
Mock mockRequest = mock(HttpServletRequest.class);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getHeaderNames()).thenAnswer(returnEnumeration(Arrays.asList(getSampleKeys())));
when(request.getHeaders("Date")).thenAnswer(returnEnumeration(HEADER_VALUE_DATE));
when(request.getHeaders("ETag")).thenAnswer(returnEnumeration(HEADER_VALUE_ETAG));
when(request.getHeaders("X-Foo")).thenAnswer(returnEnumeration(HEADER_VALUE_FOO));
mockRequest.stubs().method("getHeaderNames").will(returnEnumeration("ETag", "Date", "X-Foo"));
mockRequest.stubs().method("getHeaders").with(eq("Date")).will(returnEnumeration(HEADER_VALUE_DATE));
mockRequest.stubs().method("getHeaders").with(eq("ETag")).will(returnEnumeration(HEADER_VALUE_ETAG));
mockRequest.stubs().method("getHeaders").with(eq("X-Foo")).will(returnEnumeration(HEADER_VALUE_FOO));
mockRequest.stubs().method("getHeaders").with(not(or(eq("Date"), or(eq("ETag"), eq("X-Foo"))))).will(returnValue(null));
return new SerlvetHeadersMapAdapter((HttpServletRequest) mockRequest.proxy());
return new ServletHeadersMapAdapter(request);
}
@Override
@@ -73,31 +71,25 @@ public class ServletHeadersMapAdapterTestCase extends MapAbstractTestCase {
return new Object[] {HEADER_VALUE_DATE, HEADER_VALUE_ETAG, HEADER_VALUE_FOO};
}
@Override
public Object[] getNewSampleValues() {
// Needs to be same length but different values
return new Object[3];
}
protected Stub returnEnumeration(final Object... pValues) {
return new EnumerationStub(Arrays.asList(pValues));
protected static <T> ReturnNewEnumeration<T> returnEnumeration(final Collection<T> collection) {
return new ReturnNewEnumeration<T>(collection);
}
protected Stub returnEnumeration(final List<?> pValues) {
return new EnumerationStub(pValues);
}
private static class ReturnNewEnumeration<T> implements Answer<Enumeration<T>> {
private final Collection<T> collection;
private static class EnumerationStub extends CustomStub {
private List<?> mValues;
public EnumerationStub(final List<?> pValues) {
super("Returns a new enumeration");
mValues = pValues;
private ReturnNewEnumeration(final Collection<T> collection) {
this.collection = collection;
}
public Object invoke(Invocation invocation) throws Throwable {
return Collections.enumeration(mValues);
public Enumeration<T> answer(InvocationOnMock invocation) throws Throwable {
return Collections.enumeration(collection);
}
}
}
}
@@ -1,14 +1,15 @@
package com.twelvemonkeys.servlet;
import com.twelvemonkeys.util.MapAbstractTestCase;
import org.jmock.Mock;
import org.jmock.core.Invocation;
import org.jmock.core.Stub;
import org.jmock.core.stub.CustomStub;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import static org.mockito.Mockito.when;
/**
* ServletConfigMapAdapterTestCase
* <p/>
@@ -43,24 +44,22 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase {
}
public Map makeEmptyMap() {
Mock mockRequest = mock(HttpServletRequest.class);
mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(Collections.emptyList())));
mockRequest.stubs().method("getParameterValues").will(returnValue(null));
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
when(request.getParameterNames()).thenAnswer(returnEnumeration(Collections.emptyList()));
return new SerlvetParametersMapAdapter((HttpServletRequest) mockRequest.proxy());
return new ServletParametersMapAdapter(request);
}
@Override
public Map makeFullMap() {
Mock mockRequest = mock(HttpServletRequest.class);
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
mockRequest.stubs().method("getParameterNames").will(returnEnumeration("tag", "date", "foo"));
mockRequest.stubs().method("getParameterValues").with(eq("date")).will(returnValue(PARAM_VALUE_DATE.toArray(new String[PARAM_VALUE_DATE.size()])));
mockRequest.stubs().method("getParameterValues").with(eq("tag")).will(returnValue(PARAM_VALUE_ETAG.toArray(new String[PARAM_VALUE_ETAG.size()])));
mockRequest.stubs().method("getParameterValues").with(eq("foo")).will(returnValue(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()])));
mockRequest.stubs().method("getParameterValues").with(not(or(eq("date"), or(eq("tag"), eq("foo"))))).will(returnValue(null));
when(request.getParameterNames()).thenAnswer(returnEnumeration(Arrays.asList("tag", "date", "foo")));
when(request.getParameterValues("date")).thenReturn(PARAM_VALUE_DATE.toArray(new String[PARAM_VALUE_DATE.size()]));
when(request.getParameterValues("tag")).thenReturn(PARAM_VALUE_ETAG.toArray(new String[PARAM_VALUE_ETAG.size()]));
when(request.getParameterValues("foo")).thenReturn(PARAM_VALUE_FOO.toArray(new String[PARAM_VALUE_FOO.size()]));
return new SerlvetParametersMapAdapter((HttpServletRequest) mockRequest.proxy());
return new ServletParametersMapAdapter(request);
}
@Override
@@ -79,24 +78,19 @@ public class ServletParametersMapAdapterTestCase extends MapAbstractTestCase {
return new Object[3];
}
protected Stub returnEnumeration(final Object... pValues) {
return new EnumerationStub(Arrays.asList(pValues));
protected static <T> ReturnNewEnumeration<T> returnEnumeration(final Collection<T> collection) {
return new ReturnNewEnumeration<T>(collection);
}
protected Stub returnEnumeration(final List<?> pValues) {
return new EnumerationStub(pValues);
}
private static class ReturnNewEnumeration<T> implements Answer<Enumeration<T>> {
private final Collection<T> collection;
private static class EnumerationStub extends CustomStub {
private List<?> mValues;
public EnumerationStub(final List<?> pValues) {
super("Returns a new enumeration");
mValues = pValues;
private ReturnNewEnumeration(final Collection<T> collection) {
this.collection = collection;
}
public Object invoke(Invocation invocation) throws Throwable {
return Collections.enumeration(mValues);
public Enumeration<T> answer(InvocationOnMock invocation) throws Throwable {
return Collections.enumeration(collection);
}
}
}
@@ -0,0 +1,287 @@
/*
* Copyright (c) 2011, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.servlet;
import org.junit.Test;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
/**
* StaticContentServletTestCase
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: StaticContentServletTestCase.java,v 1.0 12.12.11 15:10 haraldk Exp$
*/
public class StaticContentServletTestCase {
private static final String IMAGE_RESOURCE = "/12monkeys-splash.png";
private static String getFileSystemRoot() {
File root = getResourceAsFile(IMAGE_RESOURCE).getParentFile();
return root.getAbsolutePath();
}
private static File getResourceAsFile(String resourceName) {
URL resource = StaticContentServletTestCase.class.getResource("/com/twelvemonkeys/servlet/image" + resourceName);
try {
return new File(resource.toURI());
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
@Test(expected = ServletException.class)
public void testBadInitNoRoot() throws ServletException {
StaticContentServlet servlet = new StaticContentServlet();
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Collections.emptyList()));
servlet.init(config);
}
@Test(expected = ServletException.class)
public void testBadInit() throws ServletException {
StaticContentServlet servlet = new StaticContentServlet();
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn("foo/bar");
servlet.init(config);
}
@Test
public void testNotFound() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("image/jpeg");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot());
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("GET");
when(request.getPathInfo()).thenReturn("/missing.jpg");
when(request.getRequestURI()).thenReturn("/foo/missing.jpg");
when(request.getContextPath()).thenReturn("/foo");
HttpServletResponse response = mock(HttpServletResponse.class);
servlet.service(request, response);
verify(response).sendError(HttpServletResponse.SC_NOT_FOUND, "/foo/missing.jpg");
}
@Test
public void testDirectoryListingForbidden() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("image/png");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot());
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("GET");
when(request.getPathInfo()).thenReturn("/"); // Attempt directory listing
when(request.getRequestURI()).thenReturn("/foo/"); // Attempt directory listing
when(request.getContextPath()).thenReturn("/foo");
ServletOutputStream stream = mock(ServletOutputStream.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(stream);
servlet.service(request, response);
verify(response).sendError(HttpServletResponse.SC_FORBIDDEN, "/foo/");
}
@Test
public void testGet() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("image/png");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot());
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("GET");
when(request.getPathInfo()).thenReturn(IMAGE_RESOURCE);
when(request.getRequestURI()).thenReturn("/foo" + IMAGE_RESOURCE);
when(request.getContextPath()).thenReturn("/foo");
ServletOutputStream stream = mock(ServletOutputStream.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(stream);
servlet.service(request, response);
verify(response).setStatus(HttpServletResponse.SC_OK);
// verify(stream, atLeastOnce()).write((byte[]) any(), anyInt(), anyInt()); // Mockito bug?
verify(stream, times(51)).write((byte[]) any(), anyInt(), anyInt()); // This test is fragile, but the above throws exception..?
verify(stream, atLeastOnce()).flush();
}
@Test
public void testGetConfiguredForSingleFile() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("text/plain");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot() + "/foo.txt");
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("GET");
when(request.getPathInfo()).thenReturn(null);
when(request.getRequestURI()).thenReturn("/foo");
when(request.getContextPath()).thenReturn("/foo");
ServletOutputStream stream = mock(ServletOutputStream.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(stream);
servlet.service(request, response);
verify(response).setStatus(HttpServletResponse.SC_OK);
// verify(stream, atLeastOnce()).write((byte[]) any(), anyInt(), anyInt()); // Mockito bug?
verify(stream, times(1)).write((byte[]) any(), anyInt(), anyInt()); // This test is fragile, but the above throws exception..?
verify(stream, atLeastOnce()).flush();
}
@Test
public void testGetNotModified() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("image/png");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot());
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("GET");
when(request.getPathInfo()).thenReturn(IMAGE_RESOURCE);
when(request.getRequestURI()).thenReturn("/foo" + IMAGE_RESOURCE);
when(request.getContextPath()).thenReturn("/foo");
when(request.getDateHeader("If-Modified-Since")).thenReturn(getResourceAsFile(IMAGE_RESOURCE).lastModified());
ServletOutputStream stream = mock(ServletOutputStream.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(stream);
servlet.service(request, response);
verify(response).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
verifyZeroInteractions(stream);
}
@Test
public void testHead() throws ServletException, IOException {
StaticContentServlet servlet = new StaticContentServlet();
ServletContext context = mock(ServletContext.class);
when(context.getServletContextName()).thenReturn("foo");
when(context.getMimeType(anyString())).thenReturn("image/png");
ServletConfig config = mock(ServletConfig.class);
when(config.getInitParameterNames()).thenReturn(Collections.enumeration(Arrays.asList("root")));
when(config.getInitParameter("root")).thenReturn(getFileSystemRoot());
when(config.getServletContext()).thenReturn(context);
servlet.init(config);
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getMethod()).thenReturn("HEAD");
when(request.getPathInfo()).thenReturn(IMAGE_RESOURCE);
when(request.getRequestURI()).thenReturn("/foo" + IMAGE_RESOURCE);
when(request.getContextPath()).thenReturn("/foo");
ServletOutputStream stream = mock(ServletOutputStream.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(stream);
servlet.service(request, response);
verify(response).setStatus(HttpServletResponse.SC_OK);
verifyZeroInteractions(stream);
}
}
@@ -1,13 +1,15 @@
package com.twelvemonkeys.servlet;
import com.twelvemonkeys.io.OutputStreamAbstractTestCase;
import org.junit.Test;
import javax.servlet.Filter;
import javax.servlet.ServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.Filter;
import javax.servlet.ServletResponse;
import static org.junit.Assert.*;
/**
* TrimWhiteSpaceFilterTestCase
@@ -23,7 +25,6 @@ public class TrimWhiteSpaceFilterTestCase extends FilterAbstractTestCase {
}
public static final class TrimWSFilterOutputStreamTestCase extends OutputStreamAbstractTestCase {
protected OutputStream makeObject() {
// NOTE: ByteArrayOutputStream does not implement flush or close...
return makeOutputStream(new ByteArrayOutputStream(16));
@@ -33,6 +34,7 @@ public class TrimWhiteSpaceFilterTestCase extends FilterAbstractTestCase {
return new TrimWhiteSpaceFilter.TrimWSFilterOutputStream(pWrapped);
}
@Test
public void testTrimWSOnlyWS() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(64);
OutputStream trim = makeOutputStream(out);
@@ -46,6 +48,7 @@ public class TrimWhiteSpaceFilterTestCase extends FilterAbstractTestCase {
assertEquals("Should be trimmed", "\"\"", '"' + new String(out.toByteArray()) + '"');
}
@Test
public void testTrimWSLeading() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(64);
OutputStream trim = makeOutputStream(out);
@@ -60,6 +63,7 @@ public class TrimWhiteSpaceFilterTestCase extends FilterAbstractTestCase {
assertEquals("Should be trimmed", '"' + trimmed + '"', '"' + new String(out.toByteArray()) + '"');
}
@Test
public void testTrimWSOffsetLength() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(64);
OutputStream trim = makeOutputStream(out);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,506 @@
/*
* Copyright (c) 2011, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name "TwelveMonkeys" nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.servlet.image;
import com.twelvemonkeys.io.FileUtil;
import com.twelvemonkeys.servlet.OutputStreamAdapter;
import com.twelvemonkeys.util.StringTokenIterator;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* ImageFilterTestCase
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: ImageFilterTestCase.java,v 1.0 07.04.11 14.14 haraldk Exp$
*/
public class ImageFilterTestCase {
@Test
public void passThroughIfNotTrigger() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter() {
@Override
protected boolean trigger(ServletRequest pRequest) {
return false;
}
};
filter.init(filterConfig);
// Request/response setup
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);
// Execute
filter.doFilter(request, response, chain);
// Verifications
verify(chain).doFilter(request, response);
verify(response, never()).getOutputStream();
verify(response, never()).getWriter();
}
@Test
public void normalFilter() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ServletOutputStream out = spy(new OutputStreamAdapter(stream));
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(out);
FilterChain chain = mock(FilterChain.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
response.setContentType("image/png");
response.setContentLength(104417);
InputStream stream = getClass().getResourceAsStream("/com/twelvemonkeys/servlet/image/12monkeys-splash.png");
assertNotNull("Missing test resource", stream);
FileUtil.copy(stream, response.getOutputStream());
return null;
}
}).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
filter.doFilter(request, response, chain);
// Verifications
int length = stream.size();
verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
verify(response).setContentType("image/png");
verify(response, atMost(1)).setContentLength(length); // setContentLength not implemented, avoid future bugs
verify(out, atLeastOnce()).flush();
// Extra verification here, until we come up with something better
assertTrue(
String.format("Unlikely length for PNG (please run manual check): %s bytes, expected about 85000 bytes", length),
length >= 60000 && length <= 120000
);
}
@Test
public void filterNoContent() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
ServletOutputStream out = mock(ServletOutputStream.class);
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(out);
FilterChain chain = mock(FilterChain.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
response.setContentType("image/x-imaginary");
return null;
}
}).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
filter.doFilter(request, response, chain);
// Verifications
verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
verify(response).setContentType("image/x-imaginary");
verify(out, atLeastOnce()).flush();
}
@Test
public void triggerWhenTriggerParamsNull() throws ServletException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Execute/Verifications
assertTrue(filter.trigger(mock(HttpServletRequest.class)));
}
@Test
public void triggerWithTriggerParams() throws ServletException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("triggerParams"));
when(filterConfig.getInitParameter("triggerParams")).thenReturn("foo");
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getParameter("foo")).thenReturn("doit");
// Execute/Verifications
assertTrue(filter.trigger(request));
}
@Test
public void dontTriggerWithoutTriggerParams() throws ServletException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("triggerParams"));
when(filterConfig.getInitParameter("triggerParams")).thenReturn("foo");
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
HttpServletRequest request = mock(HttpServletRequest.class);
// Execute/Verifications
assertFalse(filter.trigger(request));
}
@Test
public void testChaining() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig fooConfig = mock(FilterConfig.class);
when(fooConfig.getFilterName()).thenReturn("foo");
when(fooConfig.getServletContext()).thenReturn(context);
when(fooConfig.getInitParameterNames()).thenReturn(new StringTokenIterator(""));
final AtomicReference<BufferedImage> imageRef = new AtomicReference<BufferedImage>();
final AtomicReference<ImageServletResponse> responseRef = new AtomicReference<ImageServletResponse>();
DummyFilter fooFilter = new DummyFilter() {
@Override
protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
// NOTE: Post-filtering, this method is run after barFilter.doFilter
assertEquals(imageRef.get(), image);
assertEquals(responseRef.get(), response);
return image;
}
};
fooFilter.init(fooConfig);
FilterConfig barConfig = mock(FilterConfig.class);
when(barConfig.getFilterName()).thenReturn("bar");
when(barConfig.getServletContext()).thenReturn(context);
when(barConfig.getInitParameterNames()).thenReturn(new StringTokenIterator(""));
final DummyFilter barFilter = new DummyFilter() {
@Override
protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
// NOTE: Post-filtering, this method is run before fooFilter.doFilter
Graphics2D graphics = image.createGraphics();
try {
graphics.drawRect(10, 10, 100, 100);
}
finally {
graphics.dispose();
}
// Store references for later, make sure this is first and only set.
assertTrue(imageRef.compareAndSet(null, image));
assertTrue(responseRef.compareAndSet(null, response));
return image;
}
};
barFilter.init(barConfig);
// Request/response setup
ServletOutputStream out = mock(ServletOutputStream.class);
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(out);
FilterChain chain = mock(FilterChain.class);
final AtomicBoolean first = new AtomicBoolean(false);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
HttpServletRequest request = (HttpServletRequest) invocation.getArguments()[0];
HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
// Fake chaining here..
if (first.compareAndSet(false, true)) {
barFilter.doFilter(request, response, (FilterChain) invocation.getMock());
return null;
}
// Otherwise, fake servlet/file response
response.setContentType("image/gif");
InputStream stream = getClass().getResourceAsStream("/com/twelvemonkeys/servlet/image/tux.gif");
assertNotNull("Missing test resource", stream);
FileUtil.copy(stream, response.getOutputStream());
return null;
}
}).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
fooFilter.doFilter(request, response, chain);
// Verifications
verify(chain, times(2)).doFilter(any(ServletRequest.class), any(ImageServletResponse.class));
verify(response).setContentType("image/gif");
verify(out, atLeastOnce()).flush();
// NOTE:
// We verify that the image is the same in both ImageFilter implementations, to make sure the image is only
// decoded once, then encoded once.
// But this test is not necessarily 100% reliable...
}
@Test(expected = ServletException.class)
public void passThroughIfNotTriggerException() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter() {
@Override
protected boolean trigger(ServletRequest pRequest) {
return false;
}
};
filter.init(filterConfig);
// Request/response setup
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);
doThrow(new ServletException("Something went terribly wrong. Take shelter.")).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
try {
filter.doFilter(request, response, chain);
}
finally {
// Verifications
verify(chain).doFilter(request, response);
verify(response, never()).getOutputStream();
verify(response, never()).getWriter();
}
}
@Test(expected = ServletException.class)
public void normalFilterException() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ServletOutputStream out = spy(new OutputStreamAdapter(stream));
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(out);
FilterChain chain = mock(FilterChain.class);
doThrow(new ServletException("Something went terribly wrong. Take shelter.")).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
try {
filter.doFilter(request, response, chain);
}
finally {
// Verifications
verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
}
}
@Test
public void passThroughIfNotTriggerSendError() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter() {
@Override
protected boolean trigger(ServletRequest pRequest) {
return false;
}
};
filter.init(filterConfig);
// Request/response setup
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
response.sendError(HttpServletResponse.SC_FORBIDDEN, "I'm afraid I can't do that.");
return null;
}
}).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
filter.doFilter(request, response, chain);
// Verifications
verify(chain).doFilter(request, response);
verify(response, never()).getOutputStream();
verify(response, never()).getWriter();
}
@Test
public void normalFilterSendError() throws ServletException, IOException {
// Filter init & setup
ServletContext context = mock(ServletContext.class);
FilterConfig filterConfig = mock(FilterConfig.class);
when(filterConfig.getFilterName()).thenReturn("dummy");
when(filterConfig.getServletContext()).thenReturn(context);
when(filterConfig.getInitParameterNames()).thenReturn(new StringTokenIterator("foo, bar"));
DummyFilter filter = new DummyFilter();
filter.init(filterConfig);
// Request/response setup
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ServletOutputStream out = spy(new OutputStreamAdapter(stream));
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getOutputStream()).thenReturn(out);
FilterChain chain = mock(FilterChain.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
HttpServletResponse response = (HttpServletResponse) invocation.getArguments()[1];
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "I've just picked up a fault in the AE35 unit.");
return null;
}
}).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
// Execute
filter.doFilter(request, response, chain);
// Verifications
verify(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
verify(response, atMost(1)).setContentLength(stream.size()); // setContentLength not implemented, avoid future bugs
verify(out, atLeastOnce()).flush();
}
private static class DummyFilter extends ImageFilter {
@Override
protected RenderedImage doFilter(BufferedImage image, ServletRequest request, ImageServletResponse response) throws IOException {
return image;
}
}
}