View Javadoc

1   /*
2    * $Id: Jsr168DispatcherTest.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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         //mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
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         //mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
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         //mockSession.expects(once()).method("setAttribute").with(new Constraint[]{eq(PortletActionConstants.LAST_MODE), eq(PortletMode.VIEW)});
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 }