1 package com.google.inject.servlet; 2 3 import static org.easymock.EasyMock.createMock; 4 import static org.easymock.EasyMock.expect; 5 import static org.easymock.EasyMock.replay; 6 import static org.easymock.EasyMock.verify; 7 8 import com.google.inject.Guice; 9 import com.google.inject.Injector; 10 import com.google.inject.Key; 11 import com.google.inject.Singleton; 12 import java.io.IOException; 13 import javax.servlet.Filter; 14 import javax.servlet.FilterChain; 15 import javax.servlet.FilterConfig; 16 import javax.servlet.ServletException; 17 import javax.servlet.ServletRequest; 18 import javax.servlet.ServletResponse; 19 import javax.servlet.http.HttpServletRequest; 20 import junit.framework.TestCase; 21 22 /** 23 * This tests that filter stage of the pipeline dispatches correctly to guice-managed filters. 24 * 25 * <p>WARNING(dhanji): Non-parallelizable test =( 26 * 27 * @author dhanji@gmail.com (Dhanji R. Prasanna) 28 */ 29 public class VarargsFilterDispatchIntegrationTest extends TestCase { 30 private static int inits, doFilters, destroys; 31 32 @Override setUp()33 public final void setUp() { 34 inits = 0; 35 doFilters = 0; 36 destroys = 0; 37 38 GuiceFilter.reset(); 39 } 40 testDispatchRequestToManagedPipeline()41 public final void testDispatchRequestToManagedPipeline() throws ServletException, IOException { 42 final Injector injector = 43 Guice.createInjector( 44 new ServletModule() { 45 46 @Override 47 protected void configureServlets() { 48 // This is actually a double match for "/*" 49 filter("/*", "*.html", "/*").through(Key.get(TestFilter.class)); 50 51 // These filters should never fire 52 filter("/index/*").through(Key.get(TestFilter.class)); 53 filter("*.jsp").through(Key.get(TestFilter.class)); 54 } 55 }); 56 57 final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class); 58 pipeline.initPipeline(null); 59 60 //create ourselves a mock request with test URI 61 HttpServletRequest requestMock = createMock(HttpServletRequest.class); 62 63 expect(requestMock.getRequestURI()).andReturn("/index.html").anyTimes(); 64 expect(requestMock.getContextPath()).andReturn("").anyTimes(); 65 66 //dispatch request 67 replay(requestMock); 68 pipeline.dispatch(requestMock, null, createMock(FilterChain.class)); 69 pipeline.destroyPipeline(); 70 71 verify(requestMock); 72 73 assertTrue( 74 "lifecycle states did not" 75 + " fire correct number of times-- inits: " 76 + inits 77 + "; dos: " 78 + doFilters 79 + "; destroys: " 80 + destroys, 81 inits == 1 && doFilters == 3 && destroys == 1); 82 } 83 testDispatchThatNoFiltersFire()84 public final void testDispatchThatNoFiltersFire() throws ServletException, IOException { 85 final Injector injector = 86 Guice.createInjector( 87 new ServletModule() { 88 89 @Override 90 protected void configureServlets() { 91 filter("/public/*", "*.html", "*.xml").through(Key.get(TestFilter.class)); 92 93 // These filters should never fire 94 filter("/index/*").through(Key.get(TestFilter.class)); 95 filter("*.jsp").through(Key.get(TestFilter.class)); 96 } 97 }); 98 99 final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class); 100 pipeline.initPipeline(null); 101 102 //create ourselves a mock request with test URI 103 HttpServletRequest requestMock = createMock(HttpServletRequest.class); 104 105 expect(requestMock.getRequestURI()).andReturn("/index.xhtml").anyTimes(); 106 expect(requestMock.getContextPath()).andReturn("").anyTimes(); 107 108 //dispatch request 109 replay(requestMock); 110 pipeline.dispatch(requestMock, null, createMock(FilterChain.class)); 111 pipeline.destroyPipeline(); 112 113 verify(requestMock); 114 115 assertTrue( 116 "lifecycle states did not " 117 + "fire correct number of times-- inits: " 118 + inits 119 + "; dos: " 120 + doFilters 121 + "; destroys: " 122 + destroys, 123 inits == 1 && doFilters == 0 && destroys == 1); 124 } 125 testDispatchFilterPipelineWithRegexMatching()126 public final void testDispatchFilterPipelineWithRegexMatching() 127 throws ServletException, IOException { 128 129 final Injector injector = 130 Guice.createInjector( 131 new ServletModule() { 132 133 @Override 134 protected void configureServlets() { 135 filterRegex("/[A-Za-z]*", "/index").through(TestFilter.class); 136 137 //these filters should never fire 138 filterRegex("\\w").through(Key.get(TestFilter.class)); 139 } 140 }); 141 142 final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class); 143 pipeline.initPipeline(null); 144 145 //create ourselves a mock request with test URI 146 HttpServletRequest requestMock = createMock(HttpServletRequest.class); 147 148 expect(requestMock.getRequestURI()).andReturn("/index").anyTimes(); 149 expect(requestMock.getContextPath()).andReturn("").anyTimes(); 150 151 //dispatch request 152 replay(requestMock); 153 pipeline.dispatch(requestMock, null, createMock(FilterChain.class)); 154 pipeline.destroyPipeline(); 155 156 verify(requestMock); 157 158 assertTrue( 159 "lifecycle states did not fire " 160 + "correct number of times-- inits: " 161 + inits 162 + "; dos: " 163 + doFilters 164 + "; destroys: " 165 + destroys, 166 inits == 1 && doFilters == 2 && destroys == 1); 167 } 168 169 @Singleton 170 public static class TestFilter implements Filter { 171 @Override init(FilterConfig filterConfig)172 public void init(FilterConfig filterConfig) throws ServletException { 173 inits++; 174 } 175 176 @Override doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)177 public void doFilter( 178 ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 179 throws IOException, ServletException { 180 doFilters++; 181 filterChain.doFilter(servletRequest, servletResponse); 182 } 183 184 @Override destroy()185 public void destroy() { 186 destroys++; 187 } 188 } 189 } 190