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.lang.reflect.Method;
19  import java.util.Map;
20  
21  import javax.servlet.RequestDispatcher;
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletRequestWrapper;
24  
25  import org.seasar.cubby.CubbyConstants;
26  import org.seasar.cubby.routing.Routing;
27  import org.seasar.extension.unit.S2TestCase;
28  import org.seasar.framework.mock.servlet.MockHttpServletRequest;
29  import org.seasar.framework.mock.servlet.MockHttpServletResponse;
30  import org.seasar.framework.mock.servlet.MockServletContext;
31  import org.seasar.framework.util.ClassUtil;
32  
33  public class ForwardTest extends S2TestCase {
34  
35  	public MockAction action;
36  
37  	@Override
38  	protected void setUp() throws Exception {
39  		include(this.getClass().getName().replaceAll("\\.", "/") + ".dicon");
40  	}
41  
42  	public void testBasicSequence() throws Exception {
43  		MockServletContext servletContext = this.getServletContext();
44  		servletContext.setServletContextName("/cubby");
45  		MockHttpServletRequest request = this.getRequest();
46  		MockHttpServletResponse response = this.getResponse();
47  		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
48  
49  		Forward forward = new Forward("path.jsp");
50  		forward.execute(action, MockAction.class, method,
51  				new RequestDispatcherAssertionWrapper(request, new Asserter() {
52  					public void assertDispatchPath(String path) {
53  						assertTrue(action.isPrerendered());
54  						assertEquals("/mock/path.jsp", path);
55  					}
56  				}), response);
57  		assertTrue(action.isPostrendered());
58  	}
59  
60  	public void testRelativePath() throws Exception {
61  		MockServletContext servletContext = this.getServletContext();
62  		servletContext.setServletContextName("/cubby");
63  		MockHttpServletRequest request = this.getRequest();
64  		MockHttpServletResponse response = this.getResponse();
65  		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
66  
67  		Forward forward = new Forward("page.jsp");
68  		forward.execute(action, MockAction.class, method,
69  				new RequestDispatcherAssertionWrapper(request, new Asserter() {
70  					public void assertDispatchPath(String path) {
71  						assertEquals("/mock/page.jsp", path);
72  					}
73  				}), response);
74  	}
75  
76  	public void testAbsolutePath() throws Exception {
77  		MockServletContext servletContext = this.getServletContext();
78  		servletContext.setServletContextName("/cubby");
79  		MockHttpServletRequest request = this.getRequest();
80  		MockHttpServletResponse response = this.getResponse();
81  		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
82  
83  		Forward forward = new Forward("/absolute/path.jsp");
84  		forward.execute(action, MockAction.class, method,
85  				new RequestDispatcherAssertionWrapper(request, new Asserter() {
86  					public void assertDispatchPath(String path) {
87  						assertEquals("/absolute/path.jsp", path);
88  					}
89  				}), response);
90  	}
91  
92  	public void testGetPath() throws Exception {
93  		Forward forward = new Forward("/absolute/path.jsp");
94  		assertEquals("/absolute/path.jsp", forward.getPath("UTF-8"));
95  	}
96  
97  	public void testParam() throws Exception {
98  		Forward forward = new Forward("/absolute/path.jsp").param("value1",
99  				"123").param("value2", "456");
100 		assertEquals("/absolute/path.jsp?value1=123&value2=456", forward
101 				.getPath("UTF-8"));
102 	}
103 
104 	@SuppressWarnings("unchecked")
105 	public void testForwardByClassAndMethodName() throws Exception {
106 		MockServletContext servletContext = this.getServletContext();
107 		servletContext.setServletContextName("/cubby");
108 		MockHttpServletRequest request = this.getRequest();
109 		MockHttpServletResponse response = this.getResponse();
110 		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
111 
112 		Forward forward = new Forward(MockAction.class, "dummy2");
113 		forward.execute(action, MockAction.class, method,
114 				new RequestDispatcherAssertionWrapper(request, new Asserter() {
115 					public void assertDispatchPath(String path) {
116 						assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY,
117 								path);
118 					}
119 				}), response);
120 		Map<String, Routing> routings = (Map<String, Routing>) request
121 				.getAttribute(CubbyConstants.ATTR_ROUTINGS);
122 		assertNotNull(routings);
123 		assertEquals(1, routings.size());
124 		Routing routing = routings.get(null);
125 		assertNotNull(routing);
126 		assertEquals(MockAction.class, routing.getActionClass());
127 		Method forwardMethod = ClassUtil.getMethod(action.getClass(), "dummy2",
128 				null);
129 		assertEquals(forwardMethod, routing.getMethod());
130 	}
131 
132 	@SuppressWarnings("unchecked")
133 	public void testForwardByClassAndIndex() throws Exception {
134 		MockServletContext servletContext = this.getServletContext();
135 		servletContext.setServletContextName("/cubby");
136 		MockHttpServletRequest request = this.getRequest();
137 		MockHttpServletResponse response = this.getResponse();
138 		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
139 
140 		Forward forward = new Forward(MockAction.class);
141 		forward.execute(action, MockAction.class, method,
142 				new RequestDispatcherAssertionWrapper(request, new Asserter() {
143 					public void assertDispatchPath(String path) {
144 						assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY,
145 								path);
146 					}
147 				}), response);
148 		Map<String, Routing> routings = (Map<String, Routing>) request
149 				.getAttribute(CubbyConstants.ATTR_ROUTINGS);
150 		assertNotNull(routings);
151 		assertEquals(1, routings.size());
152 		Routing routing = routings.get(null);
153 		assertNotNull(routing);
154 		assertEquals(MockAction.class, routing.getActionClass());
155 		Method forwardMethod = ClassUtil.getMethod(action.getClass(), "index",
156 				null);
157 		assertEquals(forwardMethod, routing.getMethod());
158 	}
159 
160 	@SuppressWarnings("unchecked")
161 	public void testForwardByClassAndMethodNameWithParam() throws Exception {
162 		MockServletContext servletContext = this.getServletContext();
163 		servletContext.setServletContextName("/cubby");
164 		MockHttpServletRequest request = this.getRequest();
165 		MockHttpServletResponse response = this.getResponse();
166 		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
167 
168 		Forward forward = new Forward(MockAction.class, "dummy2").param(
169 				"value1", "123").param("value2", "456");
170 		forward.execute(action, MockAction.class, method,
171 				new RequestDispatcherAssertionWrapper(request, new Asserter() {
172 					public void assertDispatchPath(String path) {
173 						assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY
174 								+ "?value1=123&value2=456", path);
175 					}
176 				}), response);
177 		Map<String, Routing> routings = (Map<String, Routing>) request
178 				.getAttribute(CubbyConstants.ATTR_ROUTINGS);
179 		assertNotNull(routings);
180 		assertEquals(1, routings.size());
181 		Routing routing = routings.get(null);
182 		assertNotNull(routing);
183 		assertEquals(MockAction.class, routing.getActionClass());
184 		Method forwardMethod = ClassUtil.getMethod(action.getClass(), "dummy2",
185 				null);
186 		assertEquals(forwardMethod, routing.getMethod());
187 	}
188 
189 	interface Asserter {
190 		void assertDispatchPath(String path);
191 	}
192 
193 	class RequestDispatcherAssertionWrapper extends HttpServletRequestWrapper {
194 
195 		private Asserter asserter;
196 
197 		public RequestDispatcherAssertionWrapper(HttpServletRequest request,
198 				Asserter asserter) {
199 			super(request);
200 			this.asserter = asserter;
201 		}
202 
203 		@Override
204 		public RequestDispatcher getRequestDispatcher(String path) {
205 			asserter.assertDispatchPath(path);
206 			return super.getRequestDispatcher(path);
207 		}
208 
209 	}
210 
211 }