| /* |
| * Copyright (C) 2011 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.inject.servlet; |
| |
| import static org.easymock.EasyMock.createControl; |
| import static org.easymock.EasyMock.expect; |
| |
| import com.google.inject.Guice; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.Key; |
| import com.google.inject.Scopes; |
| import com.google.inject.name.Named; |
| import com.google.inject.name.Names; |
| import java.io.IOException; |
| 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.HttpServlet; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import junit.framework.TestCase; |
| import org.easymock.IMocksControl; |
| |
| /** Tests to make sure that servlets with a context path are handled right. */ |
| public class ContextPathTest extends TestCase { |
| |
| @Inject |
| @Named("foo") |
| private TestServlet fooServlet; |
| |
| @Inject |
| @Named("bar") |
| private TestServlet barServlet; |
| |
| private IMocksControl globalControl; |
| private Injector injector; |
| private ServletContext servletContext; |
| private FilterConfig filterConfig; |
| private GuiceFilter guiceFilter; |
| |
| @Override |
| public final void setUp() throws Exception { |
| injector = |
| Guice.createInjector( |
| new ServletModule() { |
| @Override |
| protected void configureServlets() { |
| bind(TestServlet.class) |
| .annotatedWith(Names.named("foo")) |
| .to(TestServlet.class) |
| .in(Scopes.SINGLETON); |
| bind(TestServlet.class) |
| .annotatedWith(Names.named("bar")) |
| .to(TestServlet.class) |
| .in(Scopes.SINGLETON); |
| serve("/foo/*").with(Key.get(TestServlet.class, Names.named("foo"))); |
| serve("/bar/*").with(Key.get(TestServlet.class, Names.named("bar"))); |
| // TODO: add a filter(..) call and validate it is correct |
| } |
| }); |
| injector.injectMembers(this); |
| |
| assertNotNull(fooServlet); |
| assertNotNull(barServlet); |
| assertNotSame(fooServlet, barServlet); |
| |
| globalControl = createControl(); |
| servletContext = globalControl.createMock(ServletContext.class); |
| filterConfig = globalControl.createMock(FilterConfig.class); |
| |
| expect(servletContext.getAttribute(GuiceServletContextListener.INJECTOR_NAME)) |
| .andReturn(injector) |
| .anyTimes(); |
| expect(filterConfig.getServletContext()).andReturn(servletContext).anyTimes(); |
| |
| globalControl.replay(); |
| |
| guiceFilter = new GuiceFilter(); |
| guiceFilter.init(filterConfig); |
| } |
| |
| @Override |
| public final void tearDown() { |
| assertNotNull(fooServlet); |
| assertNotNull(barServlet); |
| |
| fooServlet = null; |
| barServlet = null; |
| |
| guiceFilter.destroy(); |
| guiceFilter = null; |
| |
| injector = null; |
| |
| filterConfig = null; |
| servletContext = null; |
| |
| globalControl.verify(); |
| } |
| |
| public void testSimple() throws Exception { |
| IMocksControl testControl = createControl(); |
| TestFilterChain testFilterChain = new TestFilterChain(); |
| HttpServletRequest req = testControl.createMock(HttpServletRequest.class); |
| HttpServletResponse res = testControl.createMock(HttpServletResponse.class); |
| |
| expect(req.getMethod()).andReturn("GET").anyTimes(); |
| expect(req.getRequestURI()).andReturn("/bar/foo").anyTimes(); |
| expect(req.getServletPath()).andReturn("/bar/foo").anyTimes(); |
| expect(req.getContextPath()).andReturn("").anyTimes(); |
| |
| testControl.replay(); |
| |
| guiceFilter.doFilter(req, res, testFilterChain); |
| |
| assertFalse(testFilterChain.isTriggered()); |
| assertFalse(fooServlet.isTriggered()); |
| assertTrue(barServlet.isTriggered()); |
| |
| testControl.verify(); |
| } |
| |
| // |
| // each of the following "runTest" calls takes three path parameters: |
| // |
| // The value of "getRequestURI()" |
| // The value of "getServletPath()" |
| // The value of "getContextPath()" |
| // |
| // these values have been captured using a filter in Apache Tomcat 6.0.32 |
| // and are used for real-world values that a servlet container would send into |
| // the GuiceFilter. |
| // |
| // the remaining three booleans are: |
| // |
| // True if the request gets passed down the filter chain |
| // True if the request hits the "foo" servlet |
| // True if the request hits the "bar" sevlet |
| // |
| // After adjusting the request URI for the web app deployment location, all |
| // calls |
| // should always produce the same result. |
| // |
| |
| // ROOT Web app, using Tomcat default servlet |
| public void testRootDefault() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and /bar/*). |
| runTest("/", "/", "", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/bar/", "/bar/", "", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/foo/xxx", "/foo/xxx", "", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/xxx", "/xxx", "", true, false, false); |
| } |
| |
| // ROOT Web app, using explicit backing servlet mounted at /* |
| public void testRootExplicit() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and /bar/*). |
| runTest("/", "", "", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/bar/", "", "", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/foo/xxx", "", "", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/xxx", "", "", true, false, false); |
| } |
| |
| // ROOT Web app, using two backing servlets, mounted at /bar/* and /foo/* |
| public void testRootSpecific() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and /bar/*). |
| runTest("/", "/", "", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/bar/", "/bar", "", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/foo/xxx", "/foo", "", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/xxx", "/xxx", "", true, false, false); |
| } |
| |
| // Web app located at /webtest, using Tomcat default servlet |
| public void testWebtestDefault() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and /bar/*). |
| runTest("/webtest/", "/", "/webtest", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/webtest/bar/", "/bar/", "/webtest", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/webtest/foo/xxx", "/foo/xxx", "/webtest", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/webtest/xxx", "/xxx", "/webtest", true, false, false); |
| } |
| |
| // Web app located at /webtest, using explicit backing servlet mounted at /* |
| public void testWebtestExplicit() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and /bar/*). |
| runTest("/webtest/", "", "/webtest", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/webtest/bar/", "", "/webtest", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/webtest/foo/xxx", "", "/webtest", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/webtest/xxx", "", "/webtest", true, false, false); |
| } |
| |
| // Web app located at /webtest, using two backing servlets, mounted at /bar/* |
| // and /foo/* |
| public void testWebtestSpecific() throws Exception { |
| // fetching /. Should go up the filter chain (only mappings on /foo/* and |
| // /bar/*). |
| runTest("/webtest/", "/", "/webtest", true, false, false); |
| // fetching /bar/. Should hit the bar servlet |
| runTest("/webtest/bar/", "/bar", "/webtest", false, false, true); |
| // fetching /foo/xxx. Should hit the foo servlet |
| runTest("/webtest/foo/xxx", "/foo", "/webtest", false, true, false); |
| // fetching /xxx. Should go up the chain |
| runTest("/webtest/xxx", "/xxx", "/webtest", true, false, false); |
| } |
| |
| private void runTest( |
| final String requestURI, |
| final String servletPath, |
| final String contextPath, |
| final boolean filterResult, |
| final boolean fooResult, |
| final boolean barResult) |
| throws Exception { |
| IMocksControl testControl = createControl(); |
| |
| barServlet.clear(); |
| fooServlet.clear(); |
| |
| TestFilterChain testFilterChain = new TestFilterChain(); |
| HttpServletRequest req = testControl.createMock(HttpServletRequest.class); |
| HttpServletResponse res = testControl.createMock(HttpServletResponse.class); |
| |
| expect(req.getMethod()).andReturn("GET").anyTimes(); |
| expect(req.getRequestURI()).andReturn(requestURI).anyTimes(); |
| expect(req.getServletPath()).andReturn(servletPath).anyTimes(); |
| expect(req.getContextPath()).andReturn(contextPath).anyTimes(); |
| |
| testControl.replay(); |
| |
| guiceFilter.doFilter(req, res, testFilterChain); |
| |
| assertEquals(filterResult, testFilterChain.isTriggered()); |
| assertEquals(fooResult, fooServlet.isTriggered()); |
| assertEquals(barResult, barServlet.isTriggered()); |
| |
| testControl.verify(); |
| } |
| |
| public static class TestServlet extends HttpServlet { |
| private boolean triggered = false; |
| |
| @Override |
| public void doGet(HttpServletRequest req, HttpServletResponse resp) { |
| triggered = true; |
| } |
| |
| public boolean isTriggered() { |
| return triggered; |
| } |
| |
| public void clear() { |
| triggered = false; |
| } |
| } |
| |
| public static class TestFilterChain implements FilterChain { |
| private boolean triggered = false; |
| |
| @Override |
| public void doFilter(ServletRequest request, ServletResponse response) |
| throws IOException, ServletException { |
| triggered = true; |
| } |
| |
| public boolean isTriggered() { |
| return triggered; |
| } |
| |
| public void clear() { |
| triggered = false; |
| } |
| } |
| } |