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