Index: extensions/servlet/test/com/google/inject/servlet/ServletTest.java |
=================================================================== |
--- extensions/servlet/test/com/google/inject/servlet/ServletTest.java (revision 1577) |
+++ extensions/servlet/test/com/google/inject/servlet/ServletTest.java (working copy) |
@@ -22,21 +22,19 @@ |
import static java.lang.annotation.ElementType.METHOD; |
import static java.lang.annotation.ElementType.PARAMETER; |
import static java.lang.annotation.RetentionPolicy.RUNTIME; |
-import static org.easymock.EasyMock.createMock; |
-import static org.easymock.EasyMock.eq; |
-import static org.easymock.EasyMock.expect; |
-import static org.easymock.EasyMock.isA; |
-import static org.easymock.EasyMock.replay; |
-import static org.easymock.EasyMock.verify; |
+import com.google.common.collect.ImmutableMap; |
+import com.google.common.collect.Lists; |
import com.google.common.collect.Maps; |
import com.google.inject.AbstractModule; |
import com.google.inject.BindingAnnotation; |
import com.google.inject.CreationException; |
import com.google.inject.Guice; |
+import com.google.inject.Inject; |
import com.google.inject.Injector; |
import com.google.inject.Key; |
-import com.google.inject.servlet.RequestParameters; |
+import com.google.inject.Module; |
+import com.google.inject.Provider; |
import com.google.inject.util.Providers; |
import junit.framework.TestCase; |
@@ -50,12 +48,17 @@ |
import java.lang.reflect.Proxy; |
import java.util.Map; |
+import javax.servlet.Filter; |
import javax.servlet.FilterChain; |
+import javax.servlet.FilterConfig; |
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.HttpServletRequestWrapper; |
import javax.servlet.http.HttpServletResponse; |
+import javax.servlet.http.HttpServletResponseWrapper; |
import javax.servlet.http.HttpSession; |
/** |
@@ -80,26 +83,9 @@ |
public void testRequestAndResponseBindings() throws Exception { |
final Injector injector = createInjector(); |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- final HttpServletResponse response = createMock(HttpServletResponse.class); |
- final Map<String, String[]> params = Maps.newHashMap(); |
- String httpReqKey = HTTP_REQ_KEY.toString(); |
- expect(request.getAttribute(httpReqKey)).andReturn(null); |
- request.setAttribute(httpReqKey, request); |
- expect(request.getAttribute(httpReqKey)).andReturn(request).anyTimes(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
+ final HttpServletResponse response = newFakeHttpServletResponse(); |
- String httpRespKey = HTTP_RESP_KEY.toString(); |
- expect(request.getAttribute(httpRespKey)).andReturn(null); |
- request.setAttribute(httpRespKey, response); |
- expect(request.getAttribute(httpRespKey)).andReturn(response).anyTimes(); |
- |
- String reqParamsKey = REQ_PARAMS_KEY.toString(); |
- expect(request.getAttribute(reqParamsKey)).andReturn(null); |
- expect(request.getParameterMap()).andStubReturn(params); |
- request.setAttribute(reqParamsKey, params); |
- expect(request.getAttribute(reqParamsKey)).andReturn(params).anyTimes(); |
- replay(request, response); |
- |
final boolean[] invoked = new boolean[1]; |
GuiceFilter filter = new GuiceFilter(); |
FilterChain filterChain = new FilterChain() { |
@@ -114,32 +100,162 @@ |
assertSame(response, injector.getInstance(ServletResponse.class)); |
assertSame(response, injector.getInstance(HTTP_RESP_KEY)); |
- assertSame(params, servletRequest.getParameterMap()); |
- assertSame(params, injector.getInstance(REQ_PARAMS_KEY)); |
+ assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY)); |
} |
}; |
filter.doFilter(request, response, filterChain); |
assertTrue(invoked[0]); |
- verify(request, response); |
} |
+ public void testRequestAndResponseBindings_wrappingFilter() throws Exception { |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
+ final ImmutableMap<String, String[]> wrappedParamMap |
+ = ImmutableMap.of("wrap", new String[]{"a", "b"}); |
+ final HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) { |
+ @Override public Map getParameterMap() { |
+ return wrappedParamMap; |
+ } |
+ |
+ @Override public Object getAttribute(String attr) { |
+ // Ensure that attributes are stored on the original request object. |
+ throw new UnsupportedOperationException(); |
+ } |
+ }; |
+ final HttpServletResponse response = newFakeHttpServletResponse(); |
+ final HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response); |
+ |
+ final boolean[] filterInvoked = new boolean[1]; |
+ final Injector injector = createInjector(new ServletModule() { |
+ @Override protected void configureServlets() { |
+ filter("/*").through(new Filter() { |
+ @Inject Provider<ServletRequest> servletReqProvider; |
+ @Inject Provider<HttpServletRequest> reqProvider; |
+ @Inject Provider<ServletResponse> servletRespProvider; |
+ @Inject Provider<HttpServletResponse> respProvider; |
+ |
+ public void init(FilterConfig filterConfig) {} |
+ |
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) |
+ throws IOException, ServletException { |
+ filterInvoked[0] = true; |
+ assertSame(req, servletReqProvider.get()); |
+ assertSame(req, reqProvider.get()); |
+ |
+ assertSame(resp, servletRespProvider.get()); |
+ assertSame(resp, respProvider.get()); |
+ |
+ chain.doFilter(requestWrapper, responseWrapper); |
+ |
+ assertSame(req, reqProvider.get()); |
+ assertSame(resp, respProvider.get()); |
+ } |
+ |
+ public void destroy() {} |
+ }); |
+ } |
+ }); |
+ |
+ GuiceFilter filter = new GuiceFilter(); |
+ final boolean[] chainInvoked = new boolean[1]; |
+ FilterChain filterChain = new FilterChain() { |
+ public void doFilter(ServletRequest servletRequest, |
+ ServletResponse servletResponse) { |
+ chainInvoked[0] = true; |
+ assertSame(requestWrapper, servletRequest); |
+ assertSame(requestWrapper, injector.getInstance(ServletRequest.class)); |
+ assertSame(requestWrapper, injector.getInstance(HTTP_REQ_KEY)); |
+ |
+ assertSame(responseWrapper, servletResponse); |
+ assertSame(responseWrapper, injector.getInstance(ServletResponse.class)); |
+ assertSame(responseWrapper, injector.getInstance(HTTP_RESP_KEY)); |
+ |
+ assertSame(servletRequest.getParameterMap(), injector.getInstance(REQ_PARAMS_KEY)); |
+ |
+ InRequest inRequest = injector.getInstance(InRequest.class); |
+ assertSame(inRequest, injector.getInstance(InRequest.class)); |
+ } |
+ }; |
+ filter.doFilter(request, response, filterChain); |
+ |
+ assertTrue(chainInvoked[0]); |
+ assertTrue(filterInvoked[0]); |
+ } |
+ |
+ public void testRequestAndResponseBindings_matchesPassedParameters() throws Exception { |
+ final int[] filterInvoked = new int[1]; |
+ final boolean[] servletInvoked = new boolean[1]; |
+ final Injector injector = createInjector(new ServletModule() { |
+ @Override protected void configureServlets() { |
+ final HttpServletRequest[] previousReq = new HttpServletRequest[1]; |
+ final HttpServletResponse[] previousResp = new HttpServletResponse[1]; |
+ |
+ final Provider<ServletRequest> servletReqProvider = getProvider(ServletRequest.class); |
+ final Provider<HttpServletRequest> reqProvider = getProvider(HttpServletRequest.class); |
+ final Provider<ServletResponse> servletRespProvider = getProvider(ServletResponse.class); |
+ final Provider<HttpServletResponse> respProvider = getProvider(HttpServletResponse.class); |
+ |
+ Filter filter = new Filter() { |
+ public void init(FilterConfig filterConfig) {} |
+ |
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) |
+ throws IOException, ServletException { |
+ filterInvoked[0]++; |
+ assertSame(req, servletReqProvider.get()); |
+ assertSame(req, reqProvider.get()); |
+ if (previousReq[0] != null) { |
+ assertEquals(req, previousReq[0]); |
+ } |
+ |
+ assertSame(resp, servletRespProvider.get()); |
+ assertSame(resp, respProvider.get()); |
+ if (previousResp[0] != null) { |
+ assertEquals(resp, previousResp[0]); |
+ } |
+ |
+ chain.doFilter( |
+ previousReq[0] = new HttpServletRequestWrapper((HttpServletRequest) req), |
+ previousResp[0] = new HttpServletResponseWrapper((HttpServletResponse) resp)); |
+ |
+ assertSame(req, reqProvider.get()); |
+ assertSame(resp, respProvider.get()); |
+ } |
+ |
+ public void destroy() {} |
+ }; |
+ |
+ filter("/*").through(filter); |
+ filter("/*").through(filter); // filter twice to test wrapping in filters |
+ serve("/*").with(new HttpServlet() { |
+ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { |
+ servletInvoked[0] = true; |
+ assertSame(req, servletReqProvider.get()); |
+ assertSame(req, reqProvider.get()); |
+ |
+ assertSame(resp, servletRespProvider.get()); |
+ assertSame(resp, respProvider.get()); |
+ } |
+ }); |
+ } |
+ }); |
+ |
+ GuiceFilter filter = new GuiceFilter(); |
+ filter.doFilter(newFakeHttpServletRequest(), newFakeHttpServletResponse(), new FilterChain() { |
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) { |
+ throw new IllegalStateException("Shouldn't get here"); |
+ } |
+ }); |
+ |
+ assertEquals(2, filterInvoked[0]); |
+ assertTrue(servletInvoked[0]); |
+ } |
+ |
public void testNewRequestObject() |
throws CreationException, IOException, ServletException { |
final Injector injector = createInjector(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
GuiceFilter filter = new GuiceFilter(); |
- |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- |
- String inRequestKey = IN_REQUEST_KEY.toString(); |
- expect(request.getAttribute(inRequestKey)).andReturn(null); |
- request.setAttribute(eq(inRequestKey), isA(InRequest.class)); |
- |
- String inRequestNullKey = IN_REQUEST_NULL_KEY.toString(); |
- expect(request.getAttribute(inRequestNullKey)).andReturn(null); |
- request.setAttribute(eq(inRequestNullKey), eq(NullObject.INSTANCE)); |
- |
final boolean[] invoked = new boolean[1]; |
FilterChain filterChain = new FilterChain() { |
public void doFilter(ServletRequest servletRequest, |
@@ -150,70 +266,42 @@ |
} |
}; |
- replay(request); |
- |
filter.doFilter(request, null, filterChain); |
- verify(request); |
assertTrue(invoked[0]); |
} |
public void testExistingRequestObject() |
throws CreationException, IOException, ServletException { |
final Injector injector = createInjector(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
GuiceFilter filter = new GuiceFilter(); |
- |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- |
- final InRequest inRequest = new InRequest(); |
- String inRequestKey = IN_REQUEST_KEY.toString(); |
- expect(request.getAttribute(inRequestKey)).andReturn(inRequest).times(2); |
- |
- String inRequestNullKey = IN_REQUEST_NULL_KEY.toString(); |
- expect(request.getAttribute(inRequestNullKey)).andReturn(NullObject.INSTANCE).times(2); |
- |
final boolean[] invoked = new boolean[1]; |
FilterChain filterChain = new FilterChain() { |
public void doFilter(ServletRequest servletRequest, |
ServletResponse servletResponse) { |
invoked[0] = true; |
- |
+ |
+ InRequest inRequest = injector.getInstance(InRequest.class); |
assertSame(inRequest, injector.getInstance(InRequest.class)); |
- assertSame(inRequest, injector.getInstance(InRequest.class)); |
assertNull(injector.getInstance(IN_REQUEST_NULL_KEY)); |
assertNull(injector.getInstance(IN_REQUEST_NULL_KEY)); |
} |
}; |
- replay(request); |
- |
filter.doFilter(request, null, filterChain); |
- verify(request); |
assertTrue(invoked[0]); |
} |
public void testNewSessionObject() |
throws CreationException, IOException, ServletException { |
final Injector injector = createInjector(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
GuiceFilter filter = new GuiceFilter(); |
- |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- final HttpSession session = createMock(HttpSession.class); |
- |
- String inSessionKey = IN_SESSION_KEY.toString(); |
- String inSessionNullKey = IN_SESSION_NULL_KEY.toString(); |
- |
- expect(request.getSession()).andReturn(session).times(2); |
- expect(session.getAttribute(inSessionKey)).andReturn(null); |
- session.setAttribute(eq(inSessionKey), isA(InSession.class)); |
- |
- expect(session.getAttribute(inSessionNullKey)).andReturn(null); |
- session.setAttribute(eq(inSessionNullKey), eq(NullObject.INSTANCE)); |
- |
final boolean[] invoked = new boolean[1]; |
FilterChain filterChain = new FilterChain() { |
public void doFilter(ServletRequest servletRequest, |
@@ -224,68 +312,43 @@ |
} |
}; |
- replay(request, session); |
- |
filter.doFilter(request, null, filterChain); |
- verify(request, session); |
assertTrue(invoked[0]); |
} |
public void testExistingSessionObject() |
throws CreationException, IOException, ServletException { |
final Injector injector = createInjector(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
GuiceFilter filter = new GuiceFilter(); |
- |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- final HttpSession session = createMock(HttpSession.class); |
- |
- String inSessionKey = IN_SESSION_KEY.toString(); |
- String inSessionNullKey = IN_SESSION_NULL_KEY.toString(); |
- |
- final InSession inSession = new InSession(); |
- expect(request.getSession()).andReturn(session).times(4); |
- expect(session.getAttribute(inSessionKey)).andReturn(inSession).times(2); |
- |
- expect(session.getAttribute(inSessionNullKey)).andReturn(NullObject.INSTANCE).times(2); |
- |
final boolean[] invoked = new boolean[1]; |
FilterChain filterChain = new FilterChain() { |
public void doFilter(ServletRequest servletRequest, |
ServletResponse servletResponse) { |
invoked[0] = true; |
+ InSession inSession = injector.getInstance(InSession.class); |
assertSame(inSession, injector.getInstance(InSession.class)); |
- assertSame(inSession, injector.getInstance(InSession.class)); |
assertNull(injector.getInstance(IN_SESSION_NULL_KEY)); |
assertNull(injector.getInstance(IN_SESSION_NULL_KEY)); |
} |
}; |
- replay(request, session); |
- |
filter.doFilter(request, null, filterChain); |
- verify(request, session); |
assertTrue(invoked[0]); |
} |
public void testHttpSessionIsSerializable() |
throws IOException, ClassNotFoundException, ServletException { |
final Injector injector = createInjector(); |
+ final HttpServletRequest request = newFakeHttpServletRequest(); |
+ final HttpSession session = request.getSession(); |
GuiceFilter filter = new GuiceFilter(); |
- |
- final HttpServletRequest request = createMock(HttpServletRequest.class); |
- final HttpSession session = newFakeHttpSession(); |
- |
- String inSessionKey = IN_SESSION_KEY.toString(); |
- String inSessionNullKey = IN_SESSION_NULL_KEY.toString(); |
- |
- expect(request.getSession()).andReturn(session).times(2); |
- |
final boolean[] invoked = new boolean[1]; |
FilterChain filterChain = new FilterChain() { |
public void doFilter(ServletRequest servletRequest, |
@@ -296,19 +359,76 @@ |
} |
}; |
- replay(request); |
- |
filter.doFilter(request, null, filterChain); |
- verify(request); |
assertTrue(invoked[0]); |
HttpSession deserializedSession = reserialize(session); |
+ String inSessionKey = IN_SESSION_KEY.toString(); |
+ String inSessionNullKey = IN_SESSION_NULL_KEY.toString(); |
assertTrue(deserializedSession.getAttribute(inSessionKey) instanceof InSession); |
assertEquals(NullObject.INSTANCE, deserializedSession.getAttribute(inSessionNullKey)); |
} |
+ private static class ThrowingInvocationHandler implements InvocationHandler { |
+ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
+ throw new UnsupportedOperationException("No methods are supported on this object"); |
+ } |
+ } |
+ |
+ /** |
+ * Returns a fake, HttpServletRequest which stores attributes in a HashMap. |
+ */ |
+ private HttpServletRequest newFakeHttpServletRequest() { |
+ HttpServletRequest delegate = (HttpServletRequest) Proxy.newProxyInstance( |
+ HttpServletRequest.class.getClassLoader(), |
+ new Class[] { HttpServletRequest.class }, new ThrowingInvocationHandler()); |
+ |
+ return new HttpServletRequestWrapper(delegate) { |
+ final Map<String, Object> attributes = Maps.newHashMap(); |
+ final HttpSession session = newFakeHttpSession(); |
+ |
+ @Override public String getMethod() { |
+ return "GET"; |
+ } |
+ |
+ @Override public Object getAttribute(String name) { |
+ return attributes.get(name); |
+ } |
+ |
+ @Override public void setAttribute(String name, Object value) { |
+ attributes.put(name, value); |
+ } |
+ |
+ @Override public Map getParameterMap() { |
+ return ImmutableMap.of(); |
+ } |
+ |
+ @Override public String getRequestURI() { |
+ return "/"; |
+ } |
+ |
+ @Override public String getContextPath() { |
+ return ""; |
+ } |
+ |
+ @Override public HttpSession getSession() { |
+ return session; |
+ } |
+ }; |
+ } |
+ |
+ /** |
+ * Returns a fake, HttpServletResponse which throws an exception if any of its |
+ * methods are called. |
+ */ |
+ private HttpServletResponse newFakeHttpServletResponse() { |
+ return (HttpServletResponse) Proxy.newProxyInstance( |
+ HttpServletResponse.class.getClassLoader(), |
+ new Class[] { HttpServletResponse.class }, new ThrowingInvocationHandler()); |
+ } |
+ |
private static class FakeHttpSessionHandler implements InvocationHandler, Serializable { |
final Map<String, Object> attributes = Maps.newHashMap(); |
@@ -333,10 +453,8 @@ |
new Class[] { HttpSession.class }, new FakeHttpSessionHandler()); |
} |
- private Injector createInjector() throws CreationException { |
- |
- return Guice.createInjector(new AbstractModule() { |
- |
+ private Injector createInjector(Module... modules) throws CreationException { |
+ return Guice.createInjector(Lists.<Module>asList(new AbstractModule() { |
@Override |
protected void configure() { |
install(new ServletModule()); |
@@ -345,7 +463,7 @@ |
bind(InRequest.class); |
bind(IN_REQUEST_NULL_KEY).toProvider(Providers.<InRequest>of(null)).in(RequestScoped.class); |
} |
- }); |
+ }, modules)); |
} |
@SessionScoped |