1 /*
2  * Copyright (C) 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.inject.servlet;
18 
19 import static org.easymock.EasyMock.createMock;
20 import static org.easymock.EasyMock.expect;
21 import static org.easymock.EasyMock.replay;
22 import static org.easymock.EasyMock.verify;
23 
24 import com.google.inject.Guice;
25 import com.google.inject.Injector;
26 import com.google.inject.Key;
27 import com.google.inject.Singleton;
28 import java.io.IOException;
29 import javax.servlet.Filter;
30 import javax.servlet.FilterChain;
31 import javax.servlet.FilterConfig;
32 import javax.servlet.ServletConfig;
33 import javax.servlet.ServletException;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.ServletResponse;
36 import javax.servlet.http.HttpServlet;
37 import javax.servlet.http.HttpServletRequest;
38 import junit.framework.TestCase;
39 
40 /**
41  * Tests the FilterPipeline that dispatches to guice-managed servlets, is a full integration test,
42  * with a real injector.
43  *
44  * @author Dhanji R. Prasanna (dhanji gmail com)
45  */
46 public class VarargsServletDispatchIntegrationTest extends TestCase {
47   private static int inits, services, destroys, doFilters;
48 
49   @Override
setUp()50   public void setUp() {
51     inits = 0;
52     services = 0;
53     destroys = 0;
54     doFilters = 0;
55 
56     GuiceFilter.reset();
57   }
58 
testDispatchRequestToManagedPipelineServlets()59   public final void testDispatchRequestToManagedPipelineServlets()
60       throws ServletException, IOException {
61     final Injector injector =
62         Guice.createInjector(
63             new ServletModule() {
64 
65               @Override
66               protected void configureServlets() {
67                 serve("/*", "/index.html").with(TestServlet.class);
68 
69                 // These servets should never fire... (ordering test)
70                 serve("*.html", "/o/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
71               }
72             });
73 
74     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
75 
76     pipeline.initPipeline(null);
77 
78     //create ourselves a mock request with test URI
79     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
80 
81     expect(requestMock.getRequestURI()).andReturn("/index.html").times(1);
82     expect(requestMock.getContextPath()).andReturn("").anyTimes();
83 
84     //dispatch request
85     replay(requestMock);
86 
87     pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
88     pipeline.destroyPipeline();
89 
90     verify(requestMock);
91 
92     assertTrue(
93         "lifecycle states did not fire correct number of times-- inits: "
94             + inits
95             + "; dos: "
96             + services
97             + "; destroys: "
98             + destroys,
99         inits == 2 && services == 1 && destroys == 2);
100   }
101 
testVarargsSkipDispatchRequestToManagedPipelineServlets()102   public final void testVarargsSkipDispatchRequestToManagedPipelineServlets()
103       throws ServletException, IOException {
104     final Injector injector =
105         Guice.createInjector(
106             new ServletModule() {
107 
108               @Override
109               protected void configureServlets() {
110                 serve("/notindex", "/&*", "/index.html").with(TestServlet.class);
111 
112                 // These servets should never fire... (ordering test)
113                 serve("*.html", "/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
114               }
115             });
116 
117     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
118 
119     pipeline.initPipeline(null);
120 
121     //create ourselves a mock request with test URI
122     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
123 
124     expect(requestMock.getRequestURI()).andReturn("/index.html").times(3);
125     expect(requestMock.getContextPath()).andReturn("").anyTimes();
126 
127     //dispatch request
128     replay(requestMock);
129 
130     pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
131     pipeline.destroyPipeline();
132 
133     verify(requestMock);
134 
135     assertTrue(
136         "lifecycle states did not fire correct number of times-- inits: "
137             + inits
138             + "; dos: "
139             + services
140             + "; destroys: "
141             + destroys,
142         inits == 2 && services == 1 && destroys == 2);
143   }
144 
testDispatchRequestToManagedPipelineWithFilter()145   public final void testDispatchRequestToManagedPipelineWithFilter()
146       throws ServletException, IOException {
147     final Injector injector =
148         Guice.createInjector(
149             new ServletModule() {
150 
151               @Override
152               protected void configureServlets() {
153                 filter("/*").through(TestFilter.class);
154 
155                 serve("/*").with(TestServlet.class);
156 
157                 // These servets should never fire...
158                 serve("*.html", "/y/*", "/index/*", "*.jsp").with(Key.get(NeverServlet.class));
159               }
160             });
161 
162     final FilterPipeline pipeline = injector.getInstance(FilterPipeline.class);
163 
164     pipeline.initPipeline(null);
165 
166     //create ourselves a mock request with test URI
167     HttpServletRequest requestMock = createMock(HttpServletRequest.class);
168 
169     expect(requestMock.getRequestURI()).andReturn("/index.html").times(2);
170     expect(requestMock.getContextPath()).andReturn("").anyTimes();
171 
172     //dispatch request
173     replay(requestMock);
174 
175     pipeline.dispatch(requestMock, null, createMock(FilterChain.class));
176 
177     pipeline.destroyPipeline();
178 
179     verify(requestMock);
180 
181     assertTrue(
182         "lifecycle states did not fire correct number of times-- inits: "
183             + inits
184             + "; dos: "
185             + services
186             + "; destroys: "
187             + destroys,
188         inits == 3 && services == 1 && destroys == 3 && doFilters == 1);
189   }
190 
191   @Singleton
192   public static class TestServlet extends HttpServlet {
193     @Override
init(ServletConfig filterConfig)194     public void init(ServletConfig filterConfig) throws ServletException {
195       inits++;
196     }
197 
198     @Override
service(ServletRequest servletRequest, ServletResponse servletResponse)199     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
200         throws IOException, ServletException {
201       services++;
202     }
203 
204     @Override
destroy()205     public void destroy() {
206       destroys++;
207     }
208   }
209 
210   @Singleton
211   public static class NeverServlet extends HttpServlet {
212     @Override
init(ServletConfig filterConfig)213     public void init(ServletConfig filterConfig) throws ServletException {
214       inits++;
215     }
216 
217     @Override
service(ServletRequest servletRequest, ServletResponse servletResponse)218     public void service(ServletRequest servletRequest, ServletResponse servletResponse)
219         throws IOException, ServletException {
220       fail("NeverServlet was fired, when it should not have been.");
221     }
222 
223     @Override
destroy()224     public void destroy() {
225       destroys++;
226     }
227   }
228 
229   @Singleton
230   public static class TestFilter implements Filter {
231     @Override
init(FilterConfig filterConfig)232     public void init(FilterConfig filterConfig) throws ServletException {
233       inits++;
234     }
235 
236     @Override
doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)237     public void doFilter(
238         ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
239         throws IOException, ServletException {
240       doFilters++;
241       filterChain.doFilter(servletRequest, servletResponse);
242     }
243 
244     @Override
destroy()245     public void destroy() {
246       destroys++;
247     }
248   }
249 }
250