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  
29  import java.util.Arrays;
30  import java.util.Collection;
31  import java.util.HashMap;
32  import java.util.Hashtable;
33  import java.util.Map;
34  
35  import javax.servlet.ServletContext;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  
39  import org.easymock.IAnswer;
40  import org.junit.After;
41  import org.junit.Before;
42  import org.junit.Test;
43  import org.seasar.cubby.action.ActionContext;
44  import org.seasar.cubby.action.ActionErrors;
45  import org.seasar.cubby.action.ActionResult;
46  import org.seasar.cubby.action.FlashMap;
47  import org.seasar.cubby.action.RequestParameter;
48  import org.seasar.cubby.action.impl.ActionContextImpl;
49  import org.seasar.cubby.action.impl.ActionErrorsImpl;
50  import org.seasar.cubby.controller.RequestParser;
51  import org.seasar.cubby.controller.impl.DefaultRequestParser;
52  import org.seasar.cubby.plugin.PluginRegistry;
53  import org.seasar.cubby.plugins.BinderPlugin;
54  import org.seasar.cubby.routing.PathResolver;
55  import org.seasar.cubby.routing.impl.PathResolverImpl;
56  import org.seasar.cubby.routing.impl.PathTemplateParserImpl;
57  import org.seasar.cubby.spi.BeanDescProvider;
58  import org.seasar.cubby.spi.ContainerProvider;
59  import org.seasar.cubby.spi.ConverterProvider;
60  import org.seasar.cubby.spi.PathResolverProvider;
61  import org.seasar.cubby.spi.RequestParserProvider;
62  import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
63  import org.seasar.cubby.spi.container.Container;
64  import org.seasar.cubby.spi.container.LookupException;
65  import org.seasar.cubby.spi.impl.AbstractRequestParserProvider;
66  
67  public class CubbyRunnerTest {
68  
69  	private PluginRegistry pluginRegistry = PluginRegistry.getInstance();
70  
71  	private final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
72  
73  	private final Map<String, String[]> parameterMap = new HashMap<String, String[]>();
74  
75  	private MockAction mockAction = new MockAction();
76  
77  	@Before
78  	public void before() {
79  		PathResolver pathResolver = new PathResolverImpl(
80  				new PathTemplateParserImpl());
81  		pathResolver.add(MockAction.class);
82  
83  		final ActionErrors actionErrors = new ActionErrorsImpl();
84  		final FlashMap flashMap = new MockFlashMap();
85  		final ActionContext actionContext = new ActionContextImpl();
86  
87  		BinderPlugin binderPlugin = new BinderPlugin();
88  		binderPlugin.bind(RequestParserProvider.class).toInstance(
89  				new AbstractRequestParserProvider() {
90  
91  					@Override
92  					protected Collection<RequestParser> getRequestParsers() {
93  						return Arrays
94  								.asList(new RequestParser[] { new DefaultRequestParser() });
95  					}
96  
97  				});
98  		binderPlugin.bind(ContainerProvider.class).toInstance(
99  				new MockContainerProvider(new Container() {
100 
101 					public <T> T lookup(Class<T> type) throws LookupException {
102 						if (MockAction.class.equals(type)) {
103 							return type.cast(mockAction);
104 						}
105 						if (ActionErrors.class.equals(type)) {
106 							return type.cast(actionErrors);
107 						}
108 						if (FlashMap.class.equals(type)) {
109 							return type.cast(flashMap);
110 						}
111 						if (ActionContext.class.equals(type)) {
112 							return type.cast(actionContext);
113 						}
114 						throw new LookupException("type:" + type);
115 					}
116 
117 				}));
118 		binderPlugin.bind(BeanDescProvider.class).toInstance(
119 				new DefaultBeanDescProvider());
120 		binderPlugin.bind(ConverterProvider.class).toInstance(
121 				new MockConverterProvider());
122 		binderPlugin.bind(PathResolverProvider.class).toInstance(
123 				new MockPathResolverProvider(pathResolver));
124 		pluginRegistry.register(binderPlugin);
125 	}
126 
127 	@After
128 	public void after() {
129 		pluginRegistry.clear();
130 	}
131 
132 	@Test
133 	public void processAction() throws Exception {
134 		parameterMap.put("name", new String[] { "abcdefg" });
135 
136 		HttpServletRequest request = createMock(HttpServletRequest.class);
137 		request.setAttribute(isA(String.class), anyObject());
138 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
139 
140 			public Void answer() throws Throwable {
141 				attributes.put((String) getCurrentArguments()[0],
142 						getCurrentArguments()[1]);
143 				return null;
144 			}
145 
146 		});
147 		expect(request.getAttribute(isA(String.class))).andStubAnswer(
148 				new IAnswer<Object>() {
149 
150 					public Object answer() throws Throwable {
151 						return attributes.get(getCurrentArguments()[0]);
152 					}
153 
154 				});
155 		request.removeAttribute(isA(String.class));
156 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
157 
158 			public Void answer() throws Throwable {
159 				attributes.remove(getCurrentArguments()[0]);
160 				return null;
161 			}
162 
163 		});
164 		expect(request.getServletPath()).andReturn("/mock/execute");
165 		expect(request.getPathInfo()).andReturn(null);
166 		expect(request.getParameterMap()).andReturn(parameterMap);
167 		expect(request.getRequestURI()).andReturn("/context/mock/execute");
168 		expect(request.getMethod()).andReturn("GET");
169 		expect(request.getCharacterEncoding()).andReturn("UTF-8");
170 		HttpServletResponse response = createMock(HttpServletResponse.class);
171 		ActionResult actionResult = createMock(ActionResult.class);
172 		replay(request, response, actionResult);
173 
174 		mockAction.setActionResult(actionResult);
175 		ActionResult actual = CubbyRunner.processAction(request, response);
176 		assertSame(actionResult, actual);
177 		assertEquals("abcdefg", mockAction.getName());
178 
179 		verify(request, response, actionResult);
180 	}
181 
182 	@Test
183 	public void processActionWithServletContext() throws Exception {
184 		parameterMap.put("name", new String[] { "abcdefg" });
185 
186 		HttpServletRequest request = createMock(HttpServletRequest.class);
187 		request.setAttribute(isA(String.class), anyObject());
188 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
189 
190 			public Void answer() throws Throwable {
191 				attributes.put((String) getCurrentArguments()[0],
192 						getCurrentArguments()[1]);
193 				return null;
194 			}
195 
196 		});
197 		expect(request.getAttribute(isA(String.class))).andStubAnswer(
198 				new IAnswer<Object>() {
199 
200 					public Object answer() throws Throwable {
201 						return attributes.get(getCurrentArguments()[0]);
202 					}
203 
204 				});
205 		request.removeAttribute(isA(String.class));
206 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
207 
208 			public Void answer() throws Throwable {
209 				attributes.remove(getCurrentArguments()[0]);
210 				return null;
211 			}
212 
213 		});
214 		expect(request.getServletPath()).andReturn("/mock/execute");
215 		expect(request.getPathInfo()).andReturn(null);
216 		expect(request.getParameterMap()).andReturn(parameterMap);
217 		expect(request.getRequestURI()).andReturn("/context/mock/execute");
218 		expect(request.getMethod()).andReturn("GET");
219 		expect(request.getCharacterEncoding()).andReturn("UTF-8");
220 		HttpServletResponse response = createMock(HttpServletResponse.class);
221 		ServletContext servletContext = createMock(ServletContext.class);
222 		ActionResult actionResult = createMock(ActionResult.class);
223 		replay(request, response, servletContext, actionResult);
224 
225 		mockAction.setActionResult(actionResult);
226 		ActionResult actual = CubbyRunner.processAction(servletContext,
227 				request, response);
228 		assertSame(actionResult, actual);
229 		assertEquals("abcdefg", mockAction.getName());
230 
231 		verify(request, response, servletContext, actionResult);
232 	}
233 
234 	@Test
235 	public void processActionAndExecuteActionResult() throws Exception {
236 		parameterMap.put("name", new String[] { "abcdefg" });
237 
238 		HttpServletRequest request = createMock(HttpServletRequest.class);
239 		request.setAttribute(isA(String.class), anyObject());
240 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
241 
242 			public Void answer() throws Throwable {
243 				attributes.put((String) getCurrentArguments()[0],
244 						getCurrentArguments()[1]);
245 				return null;
246 			}
247 
248 		});
249 		expect(request.getAttribute(isA(String.class))).andStubAnswer(
250 				new IAnswer<Object>() {
251 
252 					public Object answer() throws Throwable {
253 						return attributes.get(getCurrentArguments()[0]);
254 					}
255 
256 				});
257 		request.removeAttribute(isA(String.class));
258 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
259 
260 			public Void answer() throws Throwable {
261 				attributes.remove(getCurrentArguments()[0]);
262 				return null;
263 			}
264 
265 		});
266 		expect(request.getServletPath()).andReturn("/mock/execute");
267 		expect(request.getPathInfo()).andReturn(null);
268 		expect(request.getParameterMap()).andReturn(parameterMap);
269 		expect(request.getRequestURI()).andReturn("/context/mock/execute");
270 		expect(request.getMethod()).andReturn("GET");
271 		expect(request.getCharacterEncoding()).andReturn("UTF-8");
272 		HttpServletResponse response = createMock(HttpServletResponse.class);
273 		ActionResult actionResult = createMock(ActionResult.class);
274 		actionResult.execute(isA(ActionContext.class),
275 				isA(HttpServletRequest.class), isA(HttpServletResponse.class));
276 		replay(request, response, actionResult);
277 
278 		mockAction.setActionResult(actionResult);
279 		ActionResult actual = CubbyRunner.processActionAndExecuteActionResult(
280 				request, response);
281 
282 		assertSame(actionResult, actual);
283 		assertEquals("abcdefg", mockAction.getName());
284 
285 		verify(request, response, actionResult);
286 	}
287 
288 	@Test
289 	public void processActionAndExecuteActionResultWithServletContext()
290 			throws Exception {
291 		parameterMap.put("name", new String[] { "abcdefg" });
292 
293 		HttpServletRequest request = createMock(HttpServletRequest.class);
294 		request.setAttribute(isA(String.class), anyObject());
295 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
296 
297 			public Void answer() throws Throwable {
298 				attributes.put((String) getCurrentArguments()[0],
299 						getCurrentArguments()[1]);
300 				return null;
301 			}
302 
303 		});
304 		expect(request.getAttribute(isA(String.class))).andStubAnswer(
305 				new IAnswer<Object>() {
306 
307 					public Object answer() throws Throwable {
308 						return attributes.get(getCurrentArguments()[0]);
309 					}
310 
311 				});
312 		request.removeAttribute(isA(String.class));
313 		expectLastCall().andStubAnswer(new IAnswer<Void>() {
314 
315 			public Void answer() throws Throwable {
316 				attributes.remove(getCurrentArguments()[0]);
317 				return null;
318 			}
319 
320 		});
321 		expect(request.getServletPath()).andReturn("/mock/execute");
322 		expect(request.getPathInfo()).andReturn(null);
323 		expect(request.getParameterMap()).andReturn(parameterMap);
324 		expect(request.getRequestURI()).andReturn("/context/mock/execute");
325 		expect(request.getMethod()).andReturn("GET");
326 		expect(request.getCharacterEncoding()).andReturn("UTF-8");
327 		HttpServletResponse response = createMock(HttpServletResponse.class);
328 		ServletContext servletContext = createMock(ServletContext.class);
329 		ActionResult actionResult = createMock(ActionResult.class);
330 		actionResult.execute(isA(ActionContext.class),
331 				isA(HttpServletRequest.class), isA(HttpServletResponse.class));
332 		replay(request, response, servletContext, actionResult);
333 
334 		mockAction.setActionResult(actionResult);
335 		ActionResult actual = CubbyRunner.processActionAndExecuteActionResult(
336 				servletContext, request, response);
337 		assertSame(actionResult, actual);
338 		assertEquals("abcdefg", mockAction.getName());
339 
340 		verify(request, response, servletContext, actionResult);
341 	}
342 
343 	public static class MockAction {
344 		private String name;
345 
346 		private ActionResult actionResult;
347 
348 		@RequestParameter
349 		public void setName(String name) {
350 			this.name = name;
351 		}
352 
353 		public String getName() {
354 			return name;
355 		}
356 
357 		public void setActionResult(ActionResult actionResult) {
358 			this.actionResult = actionResult;
359 		}
360 
361 		public ActionResult execute() {
362 			return actionResult;
363 		}
364 	}
365 
366 }