1   /*
2    * Copyright 2004-2010 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  
17  package org.seasar.cubby.filter;
18  
19  import static org.easymock.EasyMock.anyObject;
20  import static org.easymock.EasyMock.createMock;
21  import static org.easymock.EasyMock.createNiceMock;
22  import static org.easymock.EasyMock.expect;
23  import static org.easymock.EasyMock.expectLastCall;
24  import static org.easymock.EasyMock.getCurrentArguments;
25  import static org.easymock.EasyMock.isA;
26  import static org.easymock.EasyMock.replay;
27  import static org.easymock.EasyMock.verify;
28  import static org.junit.Assert.assertArrayEquals;
29  import static org.junit.Assert.assertEquals;
30  import static org.junit.Assert.assertFalse;
31  import static org.junit.Assert.assertNotNull;
32  import static org.junit.Assert.assertNull;
33  import static org.junit.Assert.assertSame;
34  import static org.junit.Assert.assertTrue;
35  
36  import java.util.ArrayList;
37  import java.util.Collection;
38  import java.util.Enumeration;
39  import java.util.HashMap;
40  import java.util.Hashtable;
41  import java.util.List;
42  import java.util.Locale;
43  import java.util.Map;
44  import java.util.ResourceBundle;
45  
46  import javax.servlet.http.HttpServletRequest;
47  import javax.servlet.http.HttpServletResponse;
48  
49  import org.easymock.IAnswer;
50  import org.junit.After;
51  import org.junit.Before;
52  import org.junit.Test;
53  import org.seasar.cubby.CubbyConstants;
54  import org.seasar.cubby.action.Action;
55  import org.seasar.cubby.controller.MessagesBehaviour;
56  import org.seasar.cubby.controller.impl.DefaultMessagesBehaviour;
57  import org.seasar.cubby.filter.CubbyHttpServletRequestWrapper;
58  import org.seasar.cubby.internal.controller.ThreadContext;
59  import org.seasar.cubby.mock.MockContainerProvider;
60  import org.seasar.cubby.plugin.PluginRegistry;
61  import org.seasar.cubby.plugins.BinderPlugin;
62  import org.seasar.cubby.spi.BeanDescProvider;
63  import org.seasar.cubby.spi.ContainerProvider;
64  import org.seasar.cubby.spi.beans.impl.DefaultBeanDescProvider;
65  import org.seasar.cubby.spi.container.Container;
66  import org.seasar.cubby.spi.container.LookupException;
67  
68  /**
69   * 
70   * @author agata
71   */
72  public class CubbyHttpServletRequestWrapperTest {
73  
74  	private final PluginRegistry pluginRegistry = PluginRegistry.getInstance();
75  
76  	private final CubbyFilter cubbyFilter = new CubbyFilter();
77  
78  	private HttpServletRequest request;
79  
80  	private HttpServletResponse response;
81  
82  	private Hashtable<String, String[]> parameters = new Hashtable<String, String[]>();
83  
84  	@Before
85  	public void setupProvider() {
86  		final BinderPlugin binderPlugin = new BinderPlugin();
87  		binderPlugin.bind(BeanDescProvider.class).toInstance(
88  				new DefaultBeanDescProvider());
89  		final MessagesBehaviour messagesBehaviour = new DefaultMessagesBehaviour();
90  		binderPlugin.bind(ContainerProvider.class).toInstance(
91  				new MockContainerProvider(new Container() {
92  
93  					public <T> T lookup(Class<T> type) throws LookupException {
94  						if (MessagesBehaviour.class.equals(type)) {
95  							return type.cast(messagesBehaviour);
96  						}
97  						throw new LookupException(type.getName());
98  					}
99  
100 				}));
101 		pluginRegistry.register(binderPlugin);
102 	}
103 
104 	@After
105 	public void teardownProvider() {
106 		pluginRegistry.clear();
107 	}
108 
109 	@Before
110 	@SuppressWarnings("unchecked")
111 	public void setupRequest() {
112 		final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
113 		request = createMock(HttpServletRequest.class);
114 		expect(request.getContextPath()).andStubReturn("/context");
115 		expect(request.getLocale()).andStubReturn(null);
116 		expect(request.getAttribute(String.class.cast(anyObject())))
117 				.andStubAnswer(new IAnswer<Object>() {
118 
119 					public Object answer() throws Throwable {
120 						return attributes.get(getCurrentArguments()[0]);
121 					}
122 
123 				});
124 		request.setAttribute(String.class.cast(anyObject()), anyObject());
125 		expectLastCall().andStubAnswer(new IAnswer<Object>() {
126 
127 			public Object answer() throws Throwable {
128 				attributes.put(String.class.cast(getCurrentArguments()[0]),
129 						getCurrentArguments()[1]);
130 				return null;
131 			}
132 
133 		});
134 		expect(request.getAttributeNames()).andStubAnswer(
135 				new IAnswer<Enumeration>() {
136 
137 					public Enumeration answer() throws Throwable {
138 						return attributes.keys();
139 					}
140 
141 				});
142 		expect(request.getParameter(isA(String.class))).andStubAnswer(
143 				new IAnswer<String>() {
144 
145 					public String answer() throws Throwable {
146 						return parameters.get(String.class
147 								.cast(getCurrentArguments()[0]))[0];
148 					}
149 
150 				});
151 		expect(request.getParameterMap()).andStubAnswer(new IAnswer<Map>() {
152 
153 			public Map answer() throws Throwable {
154 				return parameters;
155 			}
156 
157 		});
158 		expect(request.getParameterNames()).andAnswer(
159 				new IAnswer<Enumeration>() {
160 
161 					public Enumeration answer() throws Throwable {
162 						return parameters.keys();
163 					}
164 
165 				});
166 		expect(request.getParameterValues(isA(String.class))).andAnswer(
167 				new IAnswer<String[]>() {
168 
169 					public String[] answer() throws Throwable {
170 						return parameters.get(String.class
171 								.cast(getCurrentArguments()[0]));
172 					}
173 
174 				});
175 		response = createMock(HttpServletResponse.class);
176 		replay(request, response);
177 	}
178 
179 	@Test
180 	public void getAttributeNames() throws Exception {
181 		request.setAttribute("a1", "a1");
182 		Collection<String> origNames = toCollection(request.getAttributeNames());
183 		assertTrue("追加済みの属性", origNames.contains("a1"));
184 		assertFalse("存在しない属性", origNames.contains("a2"));
185 		assertFalse("ラップ後の追加の属性", origNames
186 				.contains(CubbyConstants.ATTR_CONTEXT_PATH));
187 		assertFalse("ラップ後の追加の属性", origNames
188 				.contains(CubbyConstants.ATTR_MESSAGES));
189 		assertFalse("ラップ後の追加の属性", origNames
190 				.contains(CubbyConstants.ATTR_ACTION));
191 
192 		CubbyHttpServletRequestWrapper wrapper = new CubbyHttpServletRequestWrapper(
193 				cubbyFilter, request, new HashMap<String, String[]>());
194 		Action action = new MockAction();
195 		wrapper.setAttribute(CubbyConstants.ATTR_ACTION, action);
196 
197 		Collection<String> wrappedNames = toCollection(wrapper
198 				.getAttributeNames());
199 		assertTrue("追加済みの属性", origNames.contains("a1"));
200 		assertFalse("存在しない属性", origNames.contains("a2"));
201 		assertTrue("ラップ後の追加の属性", wrappedNames
202 				.contains(CubbyConstants.ATTR_CONTEXT_PATH));
203 		assertTrue("ラップ後の追加の属性", wrappedNames
204 				.contains(CubbyConstants.ATTR_MESSAGES));
205 		assertTrue("ラップ後の追加の属性", wrappedNames
206 				.contains(CubbyConstants.ATTR_ACTION));
207 	}
208 
209 	private Collection<String> toCollection(Enumeration<?> attributeNames) {
210 		List<String> names = new ArrayList<String>();
211 		while (attributeNames.hasMoreElements()) {
212 			names.add((String) attributeNames.nextElement());
213 		}
214 		return names;
215 	}
216 
217 	@Test
218 	public void getAttribute() throws Exception {
219 		ThreadContext.enter(request, response);
220 		try {
221 			CubbyHttpServletRequestWrapper wrapper = new CubbyHttpServletRequestWrapper(
222 					cubbyFilter, request, new HashMap<String, String[]>());
223 
224 			assertEquals("/context", wrapper
225 					.getAttribute(CubbyConstants.ATTR_CONTEXT_PATH));
226 			assertNotNull(wrapper.getAttribute(CubbyConstants.ATTR_MESSAGES));
227 
228 			assertNull(wrapper.getAttribute("name"));
229 			Action action = new MockAction();
230 			wrapper.setAttribute(CubbyConstants.ATTR_ACTION, action);
231 			assertSame(action, wrapper.getAttribute(CubbyConstants.ATTR_ACTION));
232 			assertEquals("expect name", wrapper.getAttribute("name"));
233 			assertNull(wrapper.getAttribute("value"));
234 			assertNull(wrapper.getAttribute("noprop"));
235 		} finally {
236 			ThreadContext.exit();
237 		}
238 		ThreadContext.remove();
239 	}
240 
241 	@Test
242 	public void parameter() {
243 		parameters.put("abc", new String[] { "value1" });
244 		parameters.put("def", new String[] { "value2" });
245 
246 		Map<String, String[]> uriParameterMap = new HashMap<String, String[]>();
247 		uriParameterMap.put("abc", new String[] { "value3" });
248 		uriParameterMap.put("ghi", new String[] { "value4" });
249 
250 		CubbyHttpServletRequestWrapper wrapper = new CubbyHttpServletRequestWrapper(
251 				cubbyFilter, request, uriParameterMap);
252 
253 		Hashtable<String, String[]> expects = new Hashtable<String, String[]>();
254 		expects.put("abc", new String[] { "value1", "value3" });
255 		expects.put("def", new String[] { "value2" });
256 		expects.put("ghi", new String[] { "value4" });
257 
258 		@SuppressWarnings("unchecked")
259 		Enumeration parameterNames = wrapper.getParameterNames();
260 		while (parameterNames.hasMoreElements()) {
261 			String parameterName = (String) parameterNames.nextElement();
262 			assertArrayEquals(expects.get(parameterName), wrapper
263 					.getParameterValues(parameterName));
264 			assertEquals(expects.get(parameterName)[0], wrapper
265 					.getParameter(parameterName));
266 			expects.remove(parameterName);
267 		}
268 		assertTrue(expects.isEmpty());
269 
270 		assertNull(wrapper.getParameter("jkl"));
271 
272 		@SuppressWarnings("unchecked")
273 		Map<String, String[]> parameterMap = wrapper.getParameterMap();
274 		assertEquals(3, parameterMap.size());
275 		assertArrayEquals(new String[] { "value1", "value3" }, parameterMap
276 				.get("abc"));
277 		assertArrayEquals(new String[] { "value2" }, parameterMap.get("def"));
278 		assertArrayEquals(new String[] { "value4" }, parameterMap.get("ghi"));
279 
280 	}
281 
282 	public static class MockAction extends Action {
283 		public String getName() {
284 			return "expect name";
285 		}
286 
287 		public void setValue(String value) {
288 		}
289 	}
290 
291 	@Test
292 	public void getMessagesMap_ja() throws Exception {
293 		final HttpServletRequest request = createMockRequest();
294 		expect(request.getLocale()).andStubReturn(Locale.JAPANESE);
295 		final HttpServletResponse response = createNiceMock(HttpServletResponse.class);
296 		replay(request, response);
297 
298 		final HttpServletRequest wrappedRequest = new CubbyHttpServletRequestWrapper(
299 				cubbyFilter, request, null);
300 		final Map<?, ?> result = (Map<?, ?>) wrappedRequest
301 				.getAttribute(CubbyConstants.ATTR_MESSAGES);
302 		assertEquals("result.size()", 16, result.size());
303 		assertEquals("(HashMap) result.get(\"valid.arrayMaxSize\")",
304 				"{0}は{1}以下選択してください。", result.get("valid.arrayMaxSize"));
305 
306 		verify(request, response);
307 	}
308 
309 	@Test
310 	public void getMessagesMap_en() throws Exception {
311 		final HttpServletRequest request = createMockRequest();
312 		expect(request.getLocale()).andStubReturn(Locale.ENGLISH);
313 		final HttpServletResponse response = createMock(HttpServletResponse.class);
314 		replay(request, response);
315 
316 		final HttpServletRequest wrappedRequest = new CubbyHttpServletRequestWrapper(
317 				cubbyFilter, request, null);
318 		final Map<?, ?> result = (Map<?, ?>) wrappedRequest
319 				.getAttribute(CubbyConstants.ATTR_MESSAGES);
320 		assertEquals("result.size()", 16, result.size());
321 		assertEquals("(HashMap) result.get(\"valid.arrayMaxSize\")",
322 				"{0} : selects <= {1}.", result.get("valid.arrayMaxSize"));
323 
324 		verify(request, response);
325 	}
326 
327 	@Test
328 	public void getMessagesResourceBundle_ja() throws Exception {
329 		final HttpServletRequest request = createMockRequest();
330 		expect(request.getLocale()).andStubReturn(Locale.JAPANESE);
331 		final HttpServletResponse response = createMock(HttpServletResponse.class);
332 		replay(request, response);
333 
334 		final HttpServletRequest wrappedRequest = new CubbyHttpServletRequestWrapper(
335 				cubbyFilter, request, null);
336 		final ResourceBundle result = (ResourceBundle) wrappedRequest
337 				.getAttribute(CubbyConstants.ATTR_MESSAGES_RESOURCE_BUNDLE);
338 		assertTrue("result.getKeys().hasMoreElements()", result.getKeys()
339 				.hasMoreElements());
340 
341 		verify(request, response);
342 	}
343 
344 	@Test
345 	public void getMessagesResourceBundle_en() throws Exception {
346 		final HttpServletRequest request = createMockRequest();
347 		expect(request.getLocale()).andStubReturn(Locale.ENGLISH);
348 		final HttpServletResponse response = createMock(HttpServletResponse.class);
349 		replay(request, response);
350 
351 		final HttpServletRequest wrappedRequest = new CubbyHttpServletRequestWrapper(
352 				cubbyFilter, request, null);
353 		final ResourceBundle result = (ResourceBundle) wrappedRequest
354 				.getAttribute(CubbyConstants.ATTR_MESSAGES_RESOURCE_BUNDLE);
355 		assertTrue("result.getKeys().hasMoreElements()", result.getKeys()
356 				.hasMoreElements());
357 
358 		verify(request, response);
359 	}
360 
361 	@SuppressWarnings("unchecked")
362 	private static HttpServletRequest createMockRequest() {
363 		final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
364 
365 		final HttpServletRequest request = createNiceMock(HttpServletRequest.class);
366 		expect(request.getAttribute(String.class.cast(anyObject())))
367 				.andStubAnswer(new IAnswer<Object>() {
368 
369 					public Object answer() throws Throwable {
370 						return attributes.get(getCurrentArguments()[0]);
371 					}
372 
373 				});
374 		request.setAttribute(String.class.cast(anyObject()), anyObject());
375 		expectLastCall().andStubAnswer(new IAnswer<Object>() {
376 
377 			public Object answer() throws Throwable {
378 				attributes.put(String.class.cast(getCurrentArguments()[0]),
379 						getCurrentArguments()[1]);
380 				return null;
381 			}
382 
383 		});
384 		expect(request.getAttributeNames()).andStubAnswer(
385 				new IAnswer<Enumeration>() {
386 
387 					public Enumeration answer() throws Throwable {
388 						return attributes.keys();
389 					}
390 
391 				});
392 		expect(request.getParameterMap()).andStubReturn(attributes);
393 
394 		return request;
395 	}
396 
397 }