1   /*
2    * Copyright 2004-2008 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.action;
17  
18  import java.io.IOException;
19  import java.lang.reflect.Method;
20  import java.util.HashMap;
21  import java.util.LinkedHashMap;
22  import java.util.Map;
23  
24  import javax.servlet.http.HttpServletResponse;
25  import javax.servlet.http.HttpServletResponseWrapper;
26  
27  import org.seasar.cubby.exception.ActionRuntimeException;
28  import org.seasar.extension.unit.S2TestCase;
29  import org.seasar.framework.mock.servlet.MockHttpServletRequest;
30  import org.seasar.framework.mock.servlet.MockHttpServletResponse;
31  import org.seasar.framework.mock.servlet.MockServletContext;
32  import org.seasar.framework.util.ClassUtil;
33  
34  public class RedirectTest extends S2TestCase {
35  
36  	public MockAction action;
37  
38  	@Override
39  	protected void setUp() throws Exception {
40  		include(this.getClass().getName().replaceAll("\\.", "/") + ".dicon");
41  	}
42  
43  	public void testBasicSequence() throws Exception {
44  		final MockServletContext servletContext = this.getServletContext();
45  		servletContext.setServletContextName("/cubby");
46  		final MockHttpServletRequest request = this.getRequest();
47  		final MockHttpServletResponse response = this.getResponse();
48  		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
49  				null);
50  
51  		final Redirect redirect = new Redirect("path.jsp");
52  		assertFalse(action.isPrerendered());
53  		redirect.execute(action, MockAction.class, method, request,
54  				new RequestDispatcherAssertionWrapper(response, new Asserter() {
55  					public void assertDispatchPath(final String path) {
56  						assertEquals("/cubby/mock/path.jsp", path);
57  					}
58  				}));
59  		assertFalse(action.isPrerendered());
60  		assertFalse(action.isPostrendered());
61  	}
62  
63  	public void testBasicSequenceWithProtocol() throws Exception {
64  		final MockServletContext servletContext = this.getServletContext();
65  		servletContext.setServletContextName("/cubby");
66  		final MockHttpServletRequest request = this.getRequest();
67  		final MockHttpServletResponse response = this.getResponse();
68  		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
69  				null);
70  
71  		final Redirect redirect = new Redirect("path.jsp", "https");
72  		assertFalse(action.isPrerendered());
73  		redirect.execute(action, MockAction.class, method, request,
74  				new RequestDispatcherAssertionWrapper(response, new Asserter() {
75  					public void assertDispatchPath(final String path) {
76  						assertEquals("https://localhost/cubby/mock/path.jsp",
77  								path);
78  					}
79  				}));
80  		assertFalse(action.isPrerendered());
81  		assertFalse(action.isPostrendered());
82  	}
83  
84  	public void testBasicSequenceWithProtocolAndPort() throws Exception {
85  		final MockServletContext servletContext = this.getServletContext();
86  		servletContext.setServletContextName("/cubby");
87  		final MockHttpServletRequest request = this.getRequest();
88  		final MockHttpServletResponse response = this.getResponse();
89  		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
90  				null);
91  
92  		final Redirect redirect = new Redirect("path.jsp", "http", 8080);
93  		assertFalse(action.isPrerendered());
94  		redirect.execute(action, MockAction.class, method, request,
95  				new RequestDispatcherAssertionWrapper(response, new Asserter() {
96  					public void assertDispatchPath(final String path) {
97  						assertEquals(
98  								"http://localhost:8080/cubby/mock/path.jsp",
99  								path);
100 					}
101 				}));
102 		assertFalse(action.isPrerendered());
103 		assertFalse(action.isPostrendered());
104 	}
105 
106 	public void testRelativePath() throws Exception {
107 		final MockServletContext servletContext = this.getServletContext();
108 		servletContext.setServletContextName("/cubby");
109 		final MockHttpServletRequest request = this.getRequest();
110 		final MockHttpServletResponse response = this.getResponse();
111 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
112 				null);
113 
114 		final Redirect redirect = new Redirect("page.jsp");
115 		redirect.execute(action, MockAction.class, method, request,
116 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
117 					public void assertDispatchPath(final String path) {
118 						assertEquals("/cubby/mock/page.jsp", path);
119 					}
120 				}));
121 	}
122 
123 	public void testRelativePathWithProtocol() throws Exception {
124 		final MockServletContext servletContext = this.getServletContext();
125 		servletContext.setServletContextName("/cubby");
126 		final MockHttpServletRequest request = this.getRequest();
127 		final MockHttpServletResponse response = this.getResponse();
128 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
129 				null);
130 
131 		final Redirect redirect = new Redirect("page.jsp", "https");
132 		redirect.execute(action, MockAction.class, method, request,
133 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
134 					public void assertDispatchPath(final String path) {
135 						assertEquals("https://localhost/cubby/mock/page.jsp",
136 								path);
137 					}
138 				}));
139 	}
140 
141 	public void testAbsolutePath() throws Exception {
142 		final MockServletContext servletContext = this.getServletContext();
143 		servletContext.setServletContextName("/cubby");
144 		final MockHttpServletRequest request = this.getRequest();
145 		final MockHttpServletResponse response = this.getResponse();
146 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
147 				null);
148 
149 		final Redirect redirect = new Redirect("/absolute/path.jsp");
150 		redirect.execute(action, MockAction.class, method, request,
151 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
152 					public void assertDispatchPath(final String path) {
153 						assertEquals("/cubby/absolute/path.jsp", path);
154 					}
155 				}));
156 	}
157 
158 	public void testAbsolutePathWithProtocol() throws Exception {
159 		final MockServletContext servletContext = this.getServletContext();
160 		servletContext.setServletContextName("/cubby");
161 		final MockHttpServletRequest request = this.getRequest();
162 		final MockHttpServletResponse response = this.getResponse();
163 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
164 				null);
165 
166 		final Redirect redirect = new Redirect("/absolute/path.jsp", "https");
167 		redirect.execute(action, MockAction.class, method, request,
168 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
169 					public void assertDispatchPath(final String path) {
170 						assertEquals(
171 								"https://localhost/cubby/absolute/path.jsp",
172 								path);
173 					}
174 				}));
175 	}
176 
177 	public void testAbsoluteURL() throws Exception {
178 		final MockServletContext servletContext = this.getServletContext();
179 		servletContext.setServletContextName("/cubby");
180 		final MockHttpServletRequest request = this.getRequest();
181 		final MockHttpServletResponse response = this.getResponse();
182 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
183 				null);
184 
185 		final Redirect redirect = new Redirect("http://example.com/");
186 		redirect.execute(action, MockAction.class, method, request,
187 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
188 					public void assertDispatchPath(final String path) {
189 						assertEquals("http://example.com/", path);
190 					}
191 				}));
192 	}
193 
194 	public void testRootContextPath() throws Exception {
195 		final MockServletContext servletContext = this.getServletContext();
196 		servletContext.setServletContextName("/");
197 		final MockHttpServletRequest request = this.getRequest();
198 		final MockHttpServletResponse response = this.getResponse();
199 		final Method method = ClassUtil.getMethod(action.getClass(), "dummy1",
200 				null);
201 
202 		final Redirect redirect = new Redirect("path.jsp");
203 		redirect.execute(action, MockAction.class, method, request,
204 				new RequestDispatcherAssertionWrapper(response, new Asserter() {
205 					public void assertDispatchPath(final String path) {
206 						assertEquals("/mock/path.jsp", path);
207 					}
208 				}));
209 	}
210 
211 	public void testRedirectByClassAndMethod1() throws Exception {
212 		final Redirect redirect = new Redirect(MockAction.class, "dummy1");
213 		assertEquals("/routing/test", redirect.getPath("UTF-8"));
214 	}
215 
216 	public void testRedirectByClassAndMethod2() throws Exception {
217 		final Map<String, String[]> values = new LinkedHashMap<String, String[]>();
218 		values.put("value1", new String[] { "123" });
219 		values.put("value2", new String[] { "456" });
220 
221 		final Redirect redirect = new Redirect(MockAction.class, "dummy1",
222 				values);
223 		assertEquals("/routing/test?value1=123&value2=456", redirect
224 				.getPath("UTF-8"));
225 	}
226 
227 	public void testRedirectByClassAndMethod3() throws Exception {
228 		final Map<String, String[]> values = new LinkedHashMap<String, String[]>();
229 		values.put("value1", new String[] { "123" });
230 		values.put("value2", new String[] { "456" });
231 		final Redirect redirect = new Redirect(MockAction.class, "dummy2",
232 				values);
233 		assertEquals("/routing/test/123/456", redirect.getPath("UTF-8"));
234 	}
235 
236 	public void testRedirectByClassAndMethod4() throws Exception {
237 		final Map<String, String[]> values = new LinkedHashMap<String, String[]>();
238 		values.put("value1", new String[] { "123" });
239 		values.put("value2", new String[] { "456" });
240 		values.put("value3", new String[] { "789" });
241 		final Redirect redirect = new Redirect(MockAction.class, "dummy2",
242 				values);
243 		assertEquals("/routing/test/123/456?value3=789", redirect
244 				.getPath("UTF-8"));
245 	}
246 
247 	public void testRedirectByClassAndMethod5() throws Exception {
248 		final Redirect redirect1 = new Redirect(MockAction.class, "index");
249 		assertEquals("/routing/", redirect1.getPath("UTF-8"));
250 		final Redirect redirect2 = new Redirect(MockAction.class);
251 		assertEquals("/routing/", redirect2.getPath("UTF-8"));
252 	}
253 
254 	public void testRedirectByClassAndMethodFailureNoRouting() throws Exception {
255 		try {
256 			new Redirect(MockAction.class, "none").getPath("UTF-8");
257 			fail();
258 		} catch (final ActionRuntimeException e) {
259 			// ok
260 		}
261 	}
262 
263 	public void testRedirectByClassAndMethodFailureLessParameter()
264 			throws Exception {
265 		try {
266 			new Redirect(MockAction.class, "dummy2").getPath("UTF-8");
267 			fail();
268 		} catch (final ActionRuntimeException e) {
269 			// ok
270 		}
271 	}
272 
273 	public void testRedirectByClassAndMethodFailureUnmatchParameter()
274 			throws Exception {
275 		final Map<String, String[]> values = new LinkedHashMap<String, String[]>();
276 		values.put("value1", new String[] { "abc" });
277 		values.put("value2", new String[] { "456" });
278 		try {
279 			new Redirect(MockAction.class, "dummy2", values).getPath("UTF-8");
280 			fail();
281 		} catch (final ActionRuntimeException e) {
282 			// ok
283 		}
284 	}
285 
286 	public void testGetPath() throws Exception {
287 		final Redirect redirect = new Redirect("/absolute/redirect");
288 		assertEquals("/absolute/redirect", redirect.getPath("UTF-8"));
289 	}
290 
291 	public void testParam1() throws Exception {
292 		final Redirect redirect = new Redirect(MockAction.class, "dummy1")
293 				.param("value1", "123").param("value2", "456");
294 		assertEquals("/routing/test?value1=123&value2=456", redirect
295 				.getPath("UTF-8"));
296 	}
297 
298 	public void testParam2() throws Exception {
299 		Map<String, String[]> params = new HashMap<String, String[]>();
300 		params.put("value1", new String[] { "123" });
301 		final Redirect redirect = new Redirect(MockAction.class, "dummy1",
302 				params).param("value2", "456");
303 		assertEquals("/routing/test?value1=123&value2=456", redirect
304 				.getPath("UTF-8"));
305 	}
306 
307 	public void testParam3() throws Exception {
308 		Redirect redirect = new Redirect("hoge").param("value1", "123").param(
309 				"value2", "456");
310 		assertEquals("hoge?value1=123&value2=456", redirect.getPath("UTF-8"));
311 	}
312 
313 	interface Asserter {
314 		void assertDispatchPath(String path);
315 	}
316 
317 	class RequestDispatcherAssertionWrapper extends HttpServletResponseWrapper {
318 
319 		private final Asserter asserter;
320 
321 		public RequestDispatcherAssertionWrapper(
322 				final HttpServletResponse response, final Asserter asserter) {
323 			super(response);
324 			this.asserter = asserter;
325 		}
326 
327 		@Override
328 		public void sendRedirect(final String location) throws IOException {
329 			asserter.assertDispatchPath(location);
330 			super.sendRedirect(location);
331 		}
332 
333 	}
334 
335 }