1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.portlet.dispatcher;
23
24 import java.io.File;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.ListResourceBundle;
29 import java.util.Locale;
30 import java.util.Map;
31
32 import javax.portlet.ActionRequest;
33 import javax.portlet.ActionResponse;
34 import javax.portlet.PortletConfig;
35 import javax.portlet.PortletContext;
36 import javax.portlet.PortletMode;
37 import javax.portlet.PortletSession;
38 import javax.portlet.RenderRequest;
39 import javax.portlet.RenderResponse;
40 import javax.portlet.WindowState;
41
42 import org.apache.struts2.StrutsConstants;
43 import org.apache.struts2.dispatcher.mapper.ActionMapping;
44 import org.apache.struts2.portlet.PortletActionConstants;
45 import org.easymock.EasyMock;
46 import org.jmock.Mock;
47 import org.jmock.cglib.MockObjectTestCase;
48 import org.jmock.core.Constraint;
49 import org.springframework.mock.web.portlet.MockActionRequest;
50 import org.springframework.mock.web.portlet.MockActionResponse;
51 import org.springframework.mock.web.portlet.MockPortletConfig;
52 import org.springframework.mock.web.portlet.MockPortletContext;
53
54 import com.opensymphony.xwork2.Action;
55 import com.opensymphony.xwork2.ActionInvocation;
56 import com.opensymphony.xwork2.ActionProxy;
57 import com.opensymphony.xwork2.ActionProxyFactory;
58 import com.opensymphony.xwork2.util.ValueStack;
59
60 /***
61 * Jsr168DispatcherTest. Insert description.
62 *
63 */
64 public class Jsr168DispatcherTest extends MockObjectTestCase implements PortletActionConstants {
65
66 private final String MULTIPART_REQUEST = "-----------------------------4827543632391\r\n"
67 + "Content-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\n"
68 + "Content-Type: text/plain\r\n"
69 + "\r\n"
70 + "This is a test file\r\n"
71 + "-----------------------------4827543632391\r\n"
72 + "Content-Disposition: form-data; name=\"caption\"\r\n"
73 + "\r\n"
74 + "TestCaption\r\n"
75 + "-----------------------------4827543632391--";
76
77 Jsr168Dispatcher dispatcher = null;
78 Mock mockConfig = null;
79 Mock mockCtx = null;
80 Mock mockRequest = null;
81 Mock mockSession = null;
82 Mock mockActionFactory = null;
83 Mock mockActionProxy = null;
84 Mock mockAction = null;
85 Mock mockInvocation = null;
86
87 public void setUp() {
88 dispatcher = new Jsr168Dispatcher();
89 }
90
91 private void initPortletConfig(final Map initParams, final Map attributes) {
92 mockConfig = mock(PortletConfig.class);
93 mockCtx = mock(PortletContext.class);
94 mockConfig.stubs().method(ANYTHING);
95 mockCtx.stubs().method(ANYTHING);
96 setupStub(initParams, mockConfig, "getInitParameter");
97 mockCtx.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(attributes.keySet())));
98 setupStub(attributes, mockCtx, "getAttribute");
99 mockConfig.stubs().method("getPortletContext").will(returnValue(mockCtx.proxy()));
100 mockCtx.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet())));
101 setupStub(initParams, mockCtx, "getInitParameter");
102 mockConfig.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet())));
103 setupStub(initParams, mockConfig, "getInitParameter");
104 mockConfig.stubs().method("getResourceBundle").will(returnValue(new ListResourceBundle() {
105 protected Object[][] getContents() {
106 return new String[][]{{"javax.portlet.title", "MyTitle"}};
107 }
108 }));
109 }
110
111 private void setupActionFactory(String namespace, String actionName, String result, ValueStack stack) {
112 if(mockActionFactory == null) {
113 mockActionFactory = mock(ActionProxyFactory.class);
114 }
115 mockAction = mock(Action.class);
116 mockActionProxy = mock(ActionProxy.class);
117 mockInvocation = mock(ActionInvocation.class);
118
119 mockActionFactory.expects(once()).method("createActionProxy").with(new Constraint[]{eq(namespace), eq(actionName), NULL, isA(Map.class)}).will(returnValue(mockActionProxy.proxy()));
120 mockActionProxy.stubs().method("getAction").will(returnValue(mockAction.proxy()));
121 mockActionProxy.expects(once()).method("execute").will(returnValue(result));
122 mockActionProxy.expects(once()).method("getInvocation").will(returnValue(mockInvocation.proxy()));
123 mockInvocation.stubs().method("getStack").will(returnValue(stack));
124
125 }
126
127 public void testParseConfigWithBang() {
128 MockPortletContext portletContext = new MockPortletContext();
129 MockPortletConfig portletConfig = new MockPortletConfig(portletContext);
130
131 portletConfig.addInitParameter("viewNamespace", "/view");
132 portletConfig.addInitParameter("defaultViewAction", "index!input");
133
134 Map<PortletMode, ActionMapping> actionMap = new HashMap<PortletMode, ActionMapping>();
135
136 dispatcher.parseModeConfig(actionMap, portletConfig, PortletMode.VIEW, "viewNamespace", "defaultViewAction");
137
138 ActionMapping mapping = actionMap.get(PortletMode.VIEW);
139 assertEquals("index", mapping.getName());
140 assertEquals("/view", mapping.getNamespace());
141 assertEquals("input", mapping.getMethod());
142 }
143
144 public void testRender_ok() {
145 final Mock mockResponse = mock(RenderResponse.class);
146 mockResponse.stubs().method(ANYTHING);
147
148 PortletMode mode = PortletMode.VIEW;
149
150 Map requestParams = new HashMap();
151 requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
152 requestParams.put(EVENT_ACTION, new String[]{"true"});
153 requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
154
155 Map sessionMap = new HashMap();
156
157
158
159 Map initParams = new HashMap();
160 initParams.put("viewNamespace", "/view");
161 initParams.put(StrutsConstants.STRUTS_ALWAYS_SELECT_FULL_NAMESPACE, "true");
162
163 initPortletConfig(initParams, new HashMap());
164 initRequest(requestParams, new HashMap(), sessionMap, new HashMap(), PortletMode.VIEW, WindowState.NORMAL, false, null);
165 setupActionFactory("/view", "testAction", "success", EasyMock.createNiceMock(ValueStack.class));
166
167 mockInvocation.expects(once()).method("getStack").will(
168 returnValue(null));
169
170 try {
171 dispatcher
172 .setActionProxyFactory((ActionProxyFactory) mockActionFactory
173 .proxy());
174 dispatcher.init((PortletConfig) mockConfig.proxy());
175 dispatcher.render((RenderRequest) mockRequest.proxy(),
176 (RenderResponse) mockResponse.proxy());
177 } catch (Exception e) {
178 e.printStackTrace();
179 fail("Error occured");
180 }
181 }
182
183 public void testProcessAction_ok() {
184 final Mock mockResponse = mock(ActionResponse.class);
185
186 PortletMode mode = PortletMode.VIEW;
187 Map initParams = new HashMap();
188 initParams.put("viewNamespace", "/view");
189
190 Map requestParams = new HashMap();
191 requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
192 requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{mode.toString()});
193
194 initParams.put(StrutsConstants.STRUTS_ALWAYS_SELECT_FULL_NAMESPACE, "true");
195 initPortletConfig(initParams, new HashMap());
196 initRequest(requestParams, new HashMap(), new HashMap(), new HashMap(), PortletMode.VIEW, WindowState.NORMAL, true, null);
197 setupActionFactory("/view", "testAction", "success", EasyMock.createNiceMock(ValueStack.class));
198
199 try {
200 dispatcher
201 .setActionProxyFactory((ActionProxyFactory) mockActionFactory
202 .proxy());
203 dispatcher.init((PortletConfig) mockConfig.proxy());
204 dispatcher.processAction((ActionRequest) mockRequest.proxy(),
205 (ActionResponse) mockResponse.proxy());
206 } catch (Exception e) {
207 e.printStackTrace();
208 fail("Error occured");
209 }
210 }
211
212 /***
213 * Initialize the mock request (and as a result, the mock session)
214 * @param requestParams The request parameters
215 * @param requestAttributes The request attributes
216 * @param sessionParams The session attributes
217 * @param renderParams The render parameters. Will only be set if <code>isEvent</code> is <code>true</code>
218 * @param mode The portlet mode
219 * @param state The portlet window state
220 * @param isEvent <code>true</code> when the request is an ActionRequest.
221 * @param locale The locale. If <code>null</code>, the request will return <code>Locale.getDefault()</code>
222 */
223 private void initRequest(Map requestParams, Map requestAttributes, Map sessionParams, Map renderParams, PortletMode mode, WindowState state, boolean isEvent, Locale locale) {
224 mockRequest = isEvent ? mock(ActionRequest.class) : mock(RenderRequest.class);
225 mockSession = mock(PortletSession.class);
226 mockSession.stubs().method(ANYTHING);
227 mockRequest.stubs().method(ANYTHING);
228 setupStub(sessionParams, mockSession, "getAttribute");
229 mockSession.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(sessionParams.keySet())));
230 setupParamStub(requestParams, mockRequest, "getParameter");
231 setupStub(requestAttributes, mockRequest, "getAttribute");
232 mockRequest.stubs().method("getAttributeNames").will(returnValue(Collections.enumeration(requestAttributes.keySet())));
233 mockRequest.stubs().method("getParameterMap").will(returnValue(requestParams));
234 mockRequest.stubs().method("getParameterNames").will(returnValue(Collections.enumeration(requestParams.keySet())));
235 mockRequest.stubs().method("getPortletSession").will(returnValue(mockSession.proxy()));
236 if(locale != null) {
237 mockRequest.stubs().method("getLocale").will(returnValue(locale));
238 }
239 else {
240 mockRequest.stubs().method("getLocale").will(returnValue(Locale.getDefault()));
241 }
242 mockRequest.stubs().method("getPortletMode").will(returnValue(mode));
243 mockRequest.stubs().method("getWindowState").will(returnValue(state));
244 }
245
246 private void setupParamStub(Map requestParams, Mock mockRequest, String method) {
247 Map newMap = new HashMap();
248 Iterator it = requestParams.keySet().iterator();
249 while(it.hasNext()) {
250 Object key = it.next();
251 String[] val = (String[])requestParams.get(key);
252 newMap.put(key, val[0]);
253 }
254 setupStub(newMap, mockRequest, method);
255
256 }
257
258 /***
259 * Set up stubs for the mock.
260 * @param map The map containing the <code>key</code> and <code>values</code>. The key is the
261 * expected parameter to <code>method</code>, and value is the value that should be returned from
262 * the stub.
263 * @param mock The mock to initialize.
264 * @param method The name of the method to stub.
265 */
266 private void setupStub(Map map, Mock mock, String method) {
267 Iterator it = map.keySet().iterator();
268 while(it.hasNext()) {
269 Object key = it.next();
270 Object val = map.get(key);
271 mock.stubs().method(method).with(eq(key)).will(returnValue(val));
272 }
273 }
274
275 public void testModeChangeUsingPortletWidgets() {
276 final Mock mockResponse = mock(RenderResponse.class);
277 mockResponse.stubs().method(ANYTHING);
278 PortletMode mode = PortletMode.EDIT;
279
280 Map requestParams = new HashMap();
281 requestParams.put(PortletActionConstants.ACTION_PARAM, new String[]{"/view/testAction"});
282 requestParams.put(EVENT_ACTION, new String[]{"false"});
283 requestParams.put(PortletActionConstants.MODE_PARAM, new String[]{PortletMode.VIEW.toString()});
284
285 Map sessionMap = new HashMap();
286
287 Map initParams = new HashMap();
288 initParams.put("viewNamespace", "/view");
289 initParams.put("editNamespace", "/edit");
290
291 initPortletConfig(initParams, new HashMap());
292 initRequest(requestParams, new HashMap(), sessionMap, new HashMap(), mode, WindowState.NORMAL, false, null);
293 setupActionFactory("/edit", "default", "success", EasyMock.createNiceMock(ValueStack.class));
294
295 mockInvocation.expects(once()).method("getStack").will(
296 returnValue(null));
297
298 try {
299 dispatcher
300 .setActionProxyFactory((ActionProxyFactory) mockActionFactory
301 .proxy());
302 dispatcher.init((PortletConfig) mockConfig.proxy());
303 dispatcher.render((RenderRequest) mockRequest.proxy(),
304 (RenderResponse) mockResponse.proxy());
305 } catch (Exception e) {
306 e.printStackTrace();
307 fail("Error occured");
308 }
309 }
310
311 public void testMultipartRequest_parametersAreCopiedToActionInvocation() throws Exception {
312 MockPortletContext ctx = new MockPortletContext();
313 ctx.setAttribute("javax.servlet.context.tempdir", new File("target").getAbsoluteFile());
314 MockActionRequest request = new MockActionRequest(ctx);
315 request.setContent(MULTIPART_REQUEST.getBytes("US-ASCII"));
316 request.setContentType("multipart/form-data; boundary=---------------------------4827543632391");
317 request.setProperty("Content-Length", "" + MULTIPART_REQUEST.length());
318 MockActionResponse response = new MockActionResponse();
319 Map<String, Object> requestMap = new HashMap<String, Object>();
320 Map<String, String[]> paramMap = new HashMap<String, String[]>();
321 Map<String, Object> sessionMap = new HashMap<String, Object>();
322 Map<String, Object> applicationMap = new HashMap<String, Object>();
323 initPortletConfig(new HashMap(), new HashMap());
324 MockPortletConfig config = new MockPortletConfig(ctx);
325 dispatcher.init(config);
326 dispatcher.createContextMap(requestMap, paramMap, sessionMap, applicationMap, request, response, config, PortletActionConstants.EVENT_PHASE);
327 assertNotNull("Caption was not found in parameter map!", paramMap.get("caption"));
328 assertEquals("TestCaption", paramMap.get("caption")[0]);
329 }
330 }