blob: c151102a4e5b997cd9b0abb998e5f09b889f9419 [file] [log] [blame]
package com.google.inject.servlet;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.spi.BindingScopingVisitor;
import junit.framework.TestCase;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Tests the lifecycle of the encapsulated {@link FilterDefinition} class.
*
* @author Dhanji R. Prasanna (dhanji@gmail com)
*/
public class FilterDefinitionTest extends TestCase {
public final void testFilterInitAndConfig() throws ServletException {
Injector injector = createMock(Injector.class);
Binding binding = createMock(Binding.class);
final MockFilter mockFilter = new MockFilter();
expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
.andReturn(true);
expect(injector.getBinding(Key.get(Filter.class)))
.andReturn(binding);
expect(injector.getInstance(Key.get(Filter.class)))
.andReturn(mockFilter)
.anyTimes();
replay(binding, injector);
//some init params
//noinspection SSBasedInspection
final Map<String, String> initParams = new ImmutableMap.Builder<String, String>()
.put("ahsd", "asdas24dok")
.put("ahssd", "asdasd124ok").build();
ServletContext servletContext = createMock(ServletContext.class);
final String contextName = "thing__!@@44";
expect(servletContext.getServletContextName()).andReturn(contextName);
replay(servletContext);
String pattern = "/*";
final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
UriPatternType.get(UriPatternType.SERVLET, pattern), initParams, null);
filterDef.init(servletContext, injector,
Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
assertTrue(filterDef.getFilter() instanceof MockFilter);
final FilterConfig filterConfig = mockFilter.getConfig();
assertTrue(null != filterConfig);
assertTrue(contextName.equals(filterConfig.getServletContext().getServletContextName()));
assertTrue(Key.get(Filter.class).toString().equals(filterConfig.getFilterName()));
final Enumeration names = filterConfig.getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
assertTrue(initParams.containsKey(name));
assertTrue(initParams.get(name).equals(filterConfig.getInitParameter(name)));
}
verify(binding, injector, servletContext);
}
public final void testFilterCreateDispatchDestroy() throws ServletException, IOException {
Injector injector = createMock(Injector.class);
Binding binding = createMock(Binding.class);
HttpServletRequest request = createMock(HttpServletRequest.class);
final MockFilter mockFilter = new MockFilter();
expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
.andReturn(true);
expect(injector.getBinding(Key.get(Filter.class)))
.andReturn(binding);
expect(injector.getInstance(Key.get(Filter.class)))
.andReturn(mockFilter)
.anyTimes();
expect(request.getRequestURI()).andReturn("/index.html");
expect(request.getContextPath())
.andReturn("")
.anyTimes();
replay(injector, binding, request);
String pattern = "/*";
final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
UriPatternType.get(UriPatternType.SERVLET, pattern),
new HashMap<String, String>(), null);
//should fire on mockfilter now
filterDef.init(createMock(ServletContext.class), injector,
Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
assertTrue(filterDef.getFilter() instanceof MockFilter);
assertTrue("Init did not fire", mockFilter.isInit());
Filter matchingFilter = filterDef.getFilterIfMatching(request);
assertSame(mockFilter, matchingFilter);
final boolean proceed[] = new boolean[1];
matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
proceed[0] = true;
}
});
assertTrue("Filter did not proceed down chain", proceed[0]);
filterDef.destroy(Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
assertTrue("Destroy did not fire", mockFilter.isDestroy());
verify(injector, request);
}
public final void testFilterCreateDispatchDestroySupressChain()
throws ServletException, IOException {
Injector injector = createMock(Injector.class);
Binding binding = createMock(Binding.class);
HttpServletRequest request = createMock(HttpServletRequest.class);
final MockFilter mockFilter = new MockFilter() {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) {
//suppress rest of chain...
}
};
expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
.andReturn(true);
expect(injector.getBinding(Key.get(Filter.class)))
.andReturn(binding);
expect(injector.getInstance(Key.get(Filter.class)))
.andReturn(mockFilter)
.anyTimes();
expect(request.getRequestURI()).andReturn("/index.html");
expect(request.getContextPath())
.andReturn("")
.anyTimes();
replay(injector, binding, request);
String pattern = "/*";
final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
UriPatternType.get(UriPatternType.SERVLET, pattern),
new HashMap<String, String>(), null);
//should fire on mockfilter now
filterDef.init(createMock(ServletContext.class), injector,
Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
assertTrue(filterDef.getFilter() instanceof MockFilter);
assertTrue("init did not fire", mockFilter.isInit());
Filter matchingFilter = filterDef.getFilterIfMatching(request);
assertSame(mockFilter, matchingFilter);
final boolean proceed[] = new boolean[1];
matchingFilter.doFilter(request, null, new FilterChainInvocation(null, null, null) {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
proceed[0] = true;
}
});
assertTrue("filter did not suppress chain", !proceed[0]);
filterDef.destroy(Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
assertTrue("destroy did not fire", mockFilter.isDestroy());
verify(injector, request);
}
public void testGetFilterIfMatching() throws ServletException {
String pattern = "/*";
final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
UriPatternType.get(UriPatternType.SERVLET, pattern),
new HashMap<String, String>(), null);
HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
ServletContext servletContext = createMock(ServletContext.class);
Injector injector = createMock(Injector.class);
Binding binding = createMock(Binding.class);
final MockFilter mockFilter = new MockFilter() {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) {
//suppress rest of chain...
}
};
expect(injector.getBinding(Key.get(Filter.class)))
.andReturn(binding);
expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
.andReturn(true);
expect(injector.getInstance(Key.get(Filter.class)))
.andReturn(mockFilter)
.anyTimes();
expect(servletRequest.getContextPath()).andReturn("/a_context_path");
expect(servletRequest.getRequestURI()).andReturn("/a_context_path/test.html");
replay(servletRequest, binding, injector);
filterDef.init(servletContext, injector,
Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
Filter filter = filterDef.getFilterIfMatching(servletRequest);
assertSame(filter, mockFilter);
verify(servletRequest, binding, injector);
}
public void testGetFilterIfMatchingNotMatching() throws ServletException {
String pattern = "/*";
final FilterDefinition filterDef = new FilterDefinition(pattern, Key.get(Filter.class),
UriPatternType.get(UriPatternType.SERVLET, pattern),
new HashMap<String, String>(), null);
HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
ServletContext servletContext = createMock(ServletContext.class);
Injector injector = createMock(Injector.class);
Binding binding = createMock(Binding.class);
final MockFilter mockFilter = new MockFilter() {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) {
//suppress rest of chain...
}
};
expect(injector.getBinding(Key.get(Filter.class)))
.andReturn(binding);
expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject()))
.andReturn(true);
expect(injector.getInstance(Key.get(Filter.class)))
.andReturn(mockFilter)
.anyTimes();
expect(servletRequest.getContextPath()).andReturn("/a_context_path");
expect(servletRequest.getRequestURI()).andReturn("/test.html");
replay(servletRequest, binding, injector);
filterDef.init(servletContext, injector,
Sets.newSetFromMap(Maps.<Filter, Boolean>newIdentityHashMap()));
Filter filter = filterDef.getFilterIfMatching(servletRequest);
assertNull(filter);
verify(servletRequest, binding, injector);
}
private static class MockFilter implements Filter {
private boolean init;
private boolean destroy;
private FilterConfig config;
public void init(FilterConfig filterConfig) {
init = true;
this.config = filterConfig;
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//proceed
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
destroy = true;
}
public boolean isInit() {
return init;
}
public boolean isDestroy() {
return destroy;
}
public FilterConfig getConfig() {
return config;
}
}
}