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());
95  	}
96  
97  	public void testParam() throws Exception {
98  		Forward forward = new Forward("/absolute/path.jsp").param("value1", "123").param("value2", "456");
99  		assertEquals("/absolute/path.jsp?value1=123&value2=456", forward.getPath());
100 	}
101 
102 	@SuppressWarnings("unchecked")
103 	public void testForwardByClassAndMethodName() throws Exception {
104 		MockServletContext servletContext = this.getServletContext();
105 		servletContext.setServletContextName("/cubby");
106 		MockHttpServletRequest request = this.getRequest();
107 		MockHttpServletResponse response = this.getResponse();
108 		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
109 
110 		Forward forward = new Forward(MockAction.class, "dummy2");
111 		forward.execute(action, MockAction.class, method,
112 				new RequestDispatcherAssertionWrapper(request, new Asserter() {
113 					public void assertDispatchPath(String path) {
114 						assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY, path);
115 					}
116 				}), response);
117 		Map<String, Routing> routings = (Map<String, Routing>) request
118 				.getAttribute(CubbyConstants.ATTR_ROUTINGS);
119 		assertNotNull(routings);
120 		assertEquals(1, routings.size());
121 		Routing routing = routings.get(null);
122 		assertNotNull(routing);
123 		assertEquals(MockAction.class, routing.getActionClass());
124 		Method forwardMethod = ClassUtil.getMethod(action.getClass(), "dummy2", null);
125 		assertEquals(forwardMethod, routing.getMethod());
126 	}
127 
128 	@SuppressWarnings("unchecked")
129 	public void testForwardByClassAndMethodNameWithParam() throws Exception {
130 		MockServletContext servletContext = this.getServletContext();
131 		servletContext.setServletContextName("/cubby");
132 		MockHttpServletRequest request = this.getRequest();
133 		MockHttpServletResponse response = this.getResponse();
134 		Method method = ClassUtil.getMethod(action.getClass(), "dummy1", null);
135 
136 		Forward forward = new Forward(MockAction.class, "dummy2").param("value1", "123").param("value2", "456");
137 		forward.execute(action, MockAction.class, method,
138 				new RequestDispatcherAssertionWrapper(request, new Asserter() {
139 					public void assertDispatchPath(String path) {
140 						assertEquals(CubbyConstants.INTERNAL_FORWARD_DIRECTORY + "?value1=123&value2=456", path);
141 					}
142 				}), response);
143 		Map<String, Routing> routings = (Map<String, Routing>) request
144 				.getAttribute(CubbyConstants.ATTR_ROUTINGS);
145 		assertNotNull(routings);
146 		assertEquals(1, routings.size());
147 		Routing routing = routings.get(null);
148 		assertNotNull(routing);
149 		assertEquals(MockAction.class, routing.getActionClass());
150 		Method forwardMethod = ClassUtil.getMethod(action.getClass(), "dummy2", null);
151 		assertEquals(forwardMethod, routing.getMethod());
152 	}
153 
154 	interface Asserter {
155 		void assertDispatchPath(String path);
156 	}
157 
158 	class RequestDispatcherAssertionWrapper extends HttpServletRequestWrapper {
159 
160 		private Asserter asserter;
161 
162 		public RequestDispatcherAssertionWrapper(HttpServletRequest request,
163 				Asserter asserter) {
164 			super(request);
165 			this.asserter = asserter;
166 		}
167 
168 		@Override
169 		public RequestDispatcher getRequestDispatcher(String path) {
170 			asserter.assertDispatchPath(path);
171 			return super.getRequestDispatcher(path);
172 		}
173 
174 	}
175 
176 }