1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
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,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.unit;
17  
18  import static org.easymock.EasyMock.anyObject;
19  import static org.easymock.EasyMock.createMock;
20  import static org.easymock.EasyMock.expect;
21  import static org.easymock.EasyMock.expectLastCall;
22  import static org.easymock.EasyMock.getCurrentArguments;
23  import static org.easymock.EasyMock.isA;
24  import static org.easymock.EasyMock.replay;
25  import static org.easymock.EasyMock.verify;
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertSame;
28  import static org.junit.Assert.assertTrue;
29  
30  import java.io.IOException;
31  import java.util.Arrays;
32  import java.util.Collection;
33  import java.util.HashMap;
34  import java.util.Hashtable;
35  import java.util.Map;
36  
37  import javax.servlet.Filter;
38  import javax.servlet.FilterChain;
39  import javax.servlet.FilterConfig;
40  import javax.servlet.ServletException;
41  import javax.servlet.ServletRequest;
42  import javax.servlet.ServletResponse;
43  import javax.servlet.http.HttpServletRequest;
44  import javax.servlet.http.HttpServletResponse;
45  
46  import org.easymock.IAnswer;
47  import org.junit.After;
48  import org.junit.Before;
49  import org.junit.Test;
50  import org.seasar.cubby.action.ActionContext;
51  import org.seasar.cubby.action.ActionErrors;
52  import org.seasar.cubby.action.ActionResult;
53  import org.seasar.cubby.action.FlashMap;
54  import org.seasar.cubby.action.RequestParameter;
55  import org.seasar.cubby.action.impl.ActionContextImpl;
56  import org.seasar.cubby.action.impl.ActionErrorsImpl;
57  import org.seasar.cubby.controller.RequestParser;
58  import org.seasar.cubby.controller.impl.DefaultRequestParser;
59  import org.seasar.cubby.internal.controller.ThreadContext;
60  import org.seasar.cubby.plugin.PluginRegistry;
61  import org.seasar.cubby.plugins.BinderPlugin;
62  import org.seasar.cubby.routing.PathResolver;
63  import org.seasar.cubby.routing.impl.PathResolverImpl;
64  import org.seasar.cubby.routing.impl.PathTemplateParserImpl;
65  import org.seasar.cubby.spi.BeanDescProvider;
66  import org.seasar.cubby.spi.ContainerProvider;
67  import org.seasar.cubby.spi.ConverterProvider;
68  import org.seasar.cubby.spi.PathResolverProvider;
69  import org.seasar.cubby.spi.RequestParserProvider;
70  import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
71  import org.seasar.cubby.spi.container.Container;
72  import org.seasar.cubby.spi.container.LookupException;
73  import org.seasar.cubby.spi.impl.AbstractRequestParserProvider;
74  
75  public class CubbyRunnerFilterTest {
76  
77  	private PluginRegistry pluginRegistry = PluginRegistry.getInstance();
78  
79  	private final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
80  
81  	private final Map<String, String[]> parameterMap = new HashMap<String, String[]>();
82  
83  	private MockAction mockAction = new MockAction();
84  
85  	private static ActionResult expectActionResult = new ActionResult() {
86  
87  		public void execute(ActionContext actionContext,
88  				HttpServletRequest request, HttpServletResponse response)
89  				throws Exception {
90  		}
91  
92  	};
93  
94  	@Before
95  	public void before() {
96  		PathResolver pathResolver = new PathResolverImpl(
97  				new PathTemplateParserImpl());
98  		pathResolver.add(MockAction.class);
99  
100 		final ActionErrors actionErrors = new ActionErrorsImpl();
101 		final FlashMap flashMap = new MockFlashMap();
102 		final ActionContext actionContext = new ActionContextImpl();
103 
104 		BinderPlugin binderPlugin = new BinderPlugin();
105 		binderPlugin.bind(RequestParserProvider.class).toInstance(
106 				new AbstractRequestParserProvider() {
107 
108 					@Override
109 					protected Collection<RequestParser> getRequestParsers() {
110 						return Arrays
111 								.asList(new RequestParser[] { new DefaultRequestParser() });
112 					}
113 
114 				});
115 		binderPlugin.bind(ContainerProvider.class).toInstance(
116 				new MockContainerProvider(new Container() {
117 
118 					public <T> T lookup(Class<T> type) throws LookupException {
119 						if (MockAction.class.equals(type)) {
120 							return type.cast(mockAction);
121 						}
122 						if (ActionErrors.class.equals(type)) {
123 							return type.cast(actionErrors);
124 						}
125 						if (FlashMap.class.equals(type)) {
126 							return type.cast(flashMap);
127 						}
128 						if (ActionContext.class.equals(type)) {
129 							return type.cast(actionContext);
130 						}
131 						throw new LookupException("type:" + type);
132 					}
133 
134 				}));
135 		binderPlugin.bind(BeanDescProvider.class).toInstance(
136 				new DefaultBeanDescProvider());
137 		binderPlugin.bind(ConverterProvider.class).toInstance(
138 				new MockConverterProvider());
139 		binderPlugin.bind(PathResolverProvider.class).toInstance(
140 				new MockPathResolverProvider(pathResolver));
141 		pluginRegistry.register(binderPlugin);
142 	}
143 
144 	@After
145 	public void after() {
146 		pluginRegistry.clear();
147 	}
148 
149 	@Test
150 	public void processActionWithFilter() throws Exception {
151 		parameterMap.put("name", new String[] { "abcdefg" });
152 
153 		HttpServletRequest request = createMock(HttpServletRequest.class);
154 		request.setAttribute(isA(String.class), anyObject());
155 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
156 
157 			public Void answer() throws Throwable {
158 				attributes.put((String) getCurrentArguments()[0],
159 						getCurrentArguments()[1]);
160 				return null;
161 			}
162 
163 		});
164 		expect(request.getAttribute(isA(String.class))).andStubAnswer(
165 				new IAnswer<Object>() {
166 
167 					public Object answer() throws Throwable {
168 						return attributes.get(getCurrentArguments()[0]);
169 					}
170 
171 				});
172 		request.removeAttribute(isA(String.class));
173 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
174 
175 			public Void answer() throws Throwable {
176 				attributes.remove(getCurrentArguments()[0]);
177 				return null;
178 			}
179 
180 		});
181 		expect(request.getServletPath()).andReturn("/mock/execute");
182 		expect(request.getPathInfo()).andReturn(null);
183 		expect(request.getParameterMap()).andReturn(parameterMap);
184 		expect(request.getRequestURI()).andReturn("/context/mock/execute");
185 		expect(request.getMethod()).andReturn("GET");
186 		expect(request.getCharacterEncoding()).andReturn("UTF-8");
187 		HttpServletResponse response = createMock(HttpServletResponse.class);
188 		replay(request, response);
189 
190 		MockFilter filter = new MockFilter();
191 		ActionResult result = CubbyRunner.processAction(request, response,
192 				filter);
193 		assertSame(expectActionResult, result);
194 		assertEquals("abcdefg", mockAction.getName());
195 
196 		verify(request, response);
197 	}
198 
199 	public static class MockAction {
200 		private String name;
201 
202 		@RequestParameter
203 		public void setName(String name) {
204 			this.name = name;
205 		}
206 
207 		public String getName() {
208 			return name;
209 		}
210 
211 		public ActionResult execute() {
212 			HttpServletRequest request = ThreadContext.getRequest();
213 			assertTrue((Boolean) request.getAttribute("filtered"));
214 			return expectActionResult;
215 		}
216 	}
217 
218 	public static class MockFilter implements Filter {
219 
220 		public void init(FilterConfig filterConfig) throws ServletException {
221 		}
222 
223 		public void destroy() {
224 		}
225 
226 		public void doFilter(ServletRequest request, ServletResponse response,
227 				FilterChain chain) throws IOException, ServletException {
228 			request.setAttribute("filtered", true);
229 			chain.doFilter(request, response);
230 		}
231 
232 	}
233 
234 }