1 package com.google.inject.servlet; 2 3 import static org.easymock.EasyMock.anyObject; 4 import static org.easymock.EasyMock.createMock; 5 import static org.easymock.EasyMock.expect; 6 import static org.easymock.EasyMock.replay; 7 import static org.easymock.EasyMock.verify; 8 9 import com.google.common.collect.ImmutableMap; 10 import com.google.common.collect.Sets; 11 import com.google.inject.Binding; 12 import com.google.inject.Injector; 13 import com.google.inject.Key; 14 import com.google.inject.spi.BindingScopingVisitor; 15 import java.io.IOException; 16 import java.util.Enumeration; 17 import java.util.HashMap; 18 import java.util.Map; 19 import javax.servlet.Filter; 20 import javax.servlet.FilterChain; 21 import javax.servlet.FilterConfig; 22 import javax.servlet.ServletContext; 23 import javax.servlet.ServletException; 24 import javax.servlet.ServletRequest; 25 import javax.servlet.ServletResponse; 26 import javax.servlet.http.HttpServletRequest; 27 import junit.framework.TestCase; 28 29 /** 30 * Tests the lifecycle of the encapsulated {@link FilterDefinition} class. 31 * 32 * @author Dhanji R. Prasanna (dhanji@gmail com) 33 */ 34 public class FilterDefinitionTest extends TestCase { 35 testFilterInitAndConfig()36 public final void testFilterInitAndConfig() throws ServletException { 37 38 Injector injector = createMock(Injector.class); 39 Binding binding = createMock(Binding.class); 40 41 final MockFilter mockFilter = new MockFilter(); 42 43 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true); 44 expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding); 45 46 expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes(); 47 48 replay(binding, injector); 49 50 //some init params 51 //noinspection SSBasedInspection 52 final Map<String, String> initParams = 53 new ImmutableMap.Builder<String, String>() 54 .put("ahsd", "asdas24dok") 55 .put("ahssd", "asdasd124ok") 56 .build(); 57 58 ServletContext servletContext = createMock(ServletContext.class); 59 final String contextName = "thing__!@@44"; 60 expect(servletContext.getServletContextName()).andReturn(contextName); 61 62 replay(servletContext); 63 64 String pattern = "/*"; 65 final FilterDefinition filterDef = 66 new FilterDefinition( 67 Key.get(Filter.class), 68 UriPatternType.get(UriPatternType.SERVLET, pattern), 69 initParams, 70 null); 71 filterDef.init(servletContext, injector, Sets.<Filter>newIdentityHashSet()); 72 73 assertTrue(filterDef.getFilter() instanceof MockFilter); 74 final FilterConfig filterConfig = mockFilter.getConfig(); 75 assertTrue(null != filterConfig); 76 assertEquals(contextName, filterConfig.getServletContext().getServletContextName()); 77 assertEquals(filterConfig.getFilterName(), Key.get(Filter.class).toString()); 78 79 final Enumeration names = filterConfig.getInitParameterNames(); 80 while (names.hasMoreElements()) { 81 String name = (String) names.nextElement(); 82 83 assertTrue(initParams.containsKey(name)); 84 assertEquals(filterConfig.getInitParameter(name), initParams.get(name)); 85 } 86 87 verify(binding, injector, servletContext); 88 } 89 testFilterCreateDispatchDestroy()90 public final void testFilterCreateDispatchDestroy() throws ServletException, IOException { 91 Injector injector = createMock(Injector.class); 92 Binding binding = createMock(Binding.class); 93 HttpServletRequest request = createMock(HttpServletRequest.class); 94 95 final MockFilter mockFilter = new MockFilter(); 96 97 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true); 98 expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding); 99 100 expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes(); 101 102 expect(request.getRequestURI()).andReturn("/index.html"); 103 expect(request.getContextPath()).andReturn("").anyTimes(); 104 105 replay(injector, binding, request); 106 107 String pattern = "/*"; 108 final FilterDefinition filterDef = 109 new FilterDefinition( 110 Key.get(Filter.class), 111 UriPatternType.get(UriPatternType.SERVLET, pattern), 112 new HashMap<String, String>(), 113 null); 114 //should fire on mockfilter now 115 filterDef.init(createMock(ServletContext.class), injector, Sets.<Filter>newIdentityHashSet()); 116 assertTrue(filterDef.getFilter() instanceof MockFilter); 117 118 assertTrue("Init did not fire", mockFilter.isInit()); 119 120 Filter matchingFilter = filterDef.getFilterIfMatching(request); 121 assertSame(mockFilter, matchingFilter); 122 123 final boolean proceed[] = new boolean[1]; 124 matchingFilter.doFilter( 125 request, 126 null, 127 new FilterChainInvocation(null, null, null) { 128 @Override 129 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { 130 proceed[0] = true; 131 } 132 }); 133 134 assertTrue("Filter did not proceed down chain", proceed[0]); 135 136 filterDef.destroy(Sets.<Filter>newIdentityHashSet()); 137 assertTrue("Destroy did not fire", mockFilter.isDestroy()); 138 139 verify(injector, request); 140 } 141 testFilterCreateDispatchDestroySupressChain()142 public final void testFilterCreateDispatchDestroySupressChain() 143 throws ServletException, IOException { 144 145 Injector injector = createMock(Injector.class); 146 Binding binding = createMock(Binding.class); 147 HttpServletRequest request = createMock(HttpServletRequest.class); 148 149 final MockFilter mockFilter = 150 new MockFilter() { 151 @Override 152 public void doFilter( 153 ServletRequest servletRequest, 154 ServletResponse servletResponse, 155 FilterChain filterChain) { 156 //suppress rest of chain... 157 } 158 }; 159 160 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true); 161 expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding); 162 163 expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes(); 164 165 expect(request.getRequestURI()).andReturn("/index.html"); 166 expect(request.getContextPath()).andReturn("").anyTimes(); 167 168 replay(injector, binding, request); 169 170 String pattern = "/*"; 171 final FilterDefinition filterDef = 172 new FilterDefinition( 173 Key.get(Filter.class), 174 UriPatternType.get(UriPatternType.SERVLET, pattern), 175 new HashMap<String, String>(), 176 null); 177 //should fire on mockfilter now 178 filterDef.init(createMock(ServletContext.class), injector, Sets.<Filter>newIdentityHashSet()); 179 assertTrue(filterDef.getFilter() instanceof MockFilter); 180 181 assertTrue("init did not fire", mockFilter.isInit()); 182 183 Filter matchingFilter = filterDef.getFilterIfMatching(request); 184 assertSame(mockFilter, matchingFilter); 185 186 final boolean proceed[] = new boolean[1]; 187 matchingFilter.doFilter( 188 request, 189 null, 190 new FilterChainInvocation(null, null, null) { 191 @Override 192 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { 193 proceed[0] = true; 194 } 195 }); 196 197 assertFalse("filter did not suppress chain", proceed[0]); 198 199 filterDef.destroy(Sets.<Filter>newIdentityHashSet()); 200 assertTrue("destroy did not fire", mockFilter.isDestroy()); 201 202 verify(injector, request); 203 } 204 testGetFilterIfMatching()205 public void testGetFilterIfMatching() throws ServletException { 206 String pattern = "/*"; 207 final FilterDefinition filterDef = 208 new FilterDefinition( 209 Key.get(Filter.class), 210 UriPatternType.get(UriPatternType.SERVLET, pattern), 211 new HashMap<String, String>(), 212 null); 213 HttpServletRequest servletRequest = createMock(HttpServletRequest.class); 214 ServletContext servletContext = createMock(ServletContext.class); 215 Injector injector = createMock(Injector.class); 216 Binding binding = createMock(Binding.class); 217 218 final MockFilter mockFilter = 219 new MockFilter() { 220 @Override 221 public void doFilter( 222 ServletRequest servletRequest, 223 ServletResponse servletResponse, 224 FilterChain filterChain) { 225 //suppress rest of chain... 226 } 227 }; 228 expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding); 229 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true); 230 expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes(); 231 232 expect(servletRequest.getContextPath()).andReturn("/a_context_path"); 233 expect(servletRequest.getRequestURI()).andReturn("/a_context_path/test.html"); 234 235 replay(servletRequest, binding, injector); 236 filterDef.init(servletContext, injector, Sets.<Filter>newIdentityHashSet()); 237 Filter filter = filterDef.getFilterIfMatching(servletRequest); 238 assertSame(filter, mockFilter); 239 verify(servletRequest, binding, injector); 240 } 241 testGetFilterIfMatchingNotMatching()242 public void testGetFilterIfMatchingNotMatching() throws ServletException { 243 String pattern = "/*"; 244 final FilterDefinition filterDef = 245 new FilterDefinition( 246 Key.get(Filter.class), 247 UriPatternType.get(UriPatternType.SERVLET, pattern), 248 new HashMap<String, String>(), 249 null); 250 HttpServletRequest servletRequest = createMock(HttpServletRequest.class); 251 ServletContext servletContext = createMock(ServletContext.class); 252 Injector injector = createMock(Injector.class); 253 Binding binding = createMock(Binding.class); 254 255 final MockFilter mockFilter = 256 new MockFilter() { 257 @Override 258 public void doFilter( 259 ServletRequest servletRequest, 260 ServletResponse servletResponse, 261 FilterChain filterChain) { 262 //suppress rest of chain... 263 } 264 }; 265 expect(injector.getBinding(Key.get(Filter.class))).andReturn(binding); 266 expect(binding.acceptScopingVisitor((BindingScopingVisitor) anyObject())).andReturn(true); 267 expect(injector.getInstance(Key.get(Filter.class))).andReturn(mockFilter).anyTimes(); 268 269 expect(servletRequest.getContextPath()).andReturn("/a_context_path"); 270 expect(servletRequest.getRequestURI()).andReturn("/test.html"); 271 272 replay(servletRequest, binding, injector); 273 filterDef.init(servletContext, injector, Sets.<Filter>newIdentityHashSet()); 274 Filter filter = filterDef.getFilterIfMatching(servletRequest); 275 assertNull(filter); 276 verify(servletRequest, binding, injector); 277 } 278 279 private static class MockFilter implements Filter { 280 private boolean init; 281 private boolean destroy; 282 private FilterConfig config; 283 284 @Override init(FilterConfig filterConfig)285 public void init(FilterConfig filterConfig) { 286 init = true; 287 288 this.config = filterConfig; 289 } 290 291 @Override doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)292 public void doFilter( 293 ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 294 throws IOException, ServletException { 295 //proceed 296 filterChain.doFilter(servletRequest, servletResponse); 297 } 298 299 @Override destroy()300 public void destroy() { 301 destroy = true; 302 } 303 isInit()304 public boolean isInit() { 305 return init; 306 } 307 isDestroy()308 public boolean isDestroy() { 309 return destroy; 310 } 311 getConfig()312 public FilterConfig getConfig() { 313 return config; 314 } 315 } 316 } 317