View Javadoc

1   /*
2    * $Id: UrlHelperTest.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.views.util;
23  
24  import com.mockobjects.dynamic.C;
25  import com.mockobjects.dynamic.Mock;
26  import com.opensymphony.xwork2.ActionContext;
27  import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
28  import com.opensymphony.xwork2.inject.Container;
29  import com.opensymphony.xwork2.inject.Scope.Strategy;
30  import com.opensymphony.xwork2.util.ValueStack;
31  
32  import java.util.HashMap;
33  import java.util.LinkedHashMap;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.TreeMap;
37  
38  import javax.servlet.http.HttpServletRequest;
39  import javax.servlet.http.HttpServletResponse;
40  
41  import org.apache.struts2.StrutsConstants;
42  import org.apache.struts2.StrutsTestCase;
43  
44  
45  /***
46   * Test case for UrlHelper.
47   *
48   */
49  public class UrlHelperTest extends StrutsTestCase {
50      
51      private StubContainer stubContainer;
52  
53      public void testForceAddSchemeHostAndPort() throws Exception {
54          String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
55  
56          Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
57          mockHttpServletRequest.expectAndReturn("getScheme", "http");
58          mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
59          mockHttpServletRequest.expectAndReturn("getContextPath", "/contextPath");
60          mockHttpServletRequest.expectAndReturn("getServerPort", 80);
61  
62          Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
63          mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
64  
65          String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, true);
66          assertEquals(expectedUrl, result);
67          mockHttpServletRequest.verify();
68      }
69  
70      public void testDoNotForceAddSchemeHostAndPort() throws Exception {
71          String expectedUrl = "/contextPath/path1/path2/myAction.action";
72  
73          Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
74          mockHttpServletRequest.expectAndReturn("getScheme", "http");
75          mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
76          mockHttpServletRequest.expectAndReturn("getContextPath", "/contextPath");
77  
78          Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
79          mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
80  
81          String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest)mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, false);
82  
83          assertEquals(expectedUrl, result);
84      }
85  
86      public void testForceAddSchemeHostAndPortWithNonStandardPort() throws Exception {
87          String expectedUrl = "http://localhost:9090/contextPath/path1/path2/myAction.action";
88  
89          Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
90          mockHttpServletRequest.expectAndReturn("getScheme", "http");
91          mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
92          mockHttpServletRequest.expectAndReturn("getContextPath", "/contextPath");
93          mockHttpServletRequest.expectAndReturn("getServerPort", 9090);
94  
95          Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
96          mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
97  
98          String result = UrlHelper.buildUrl("/path1/path2/myAction.action", (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse)mockHttpServletResponse.proxy(), null, "http", true, true, true);
99          assertEquals(expectedUrl, result);
100         mockHttpServletRequest.verify();
101     }
102 
103     public void testBuildParametersStringWithUrlHavingSomeExistingParameters() throws Exception {
104         String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2";
105 
106         Map parameters = new LinkedHashMap();
107         parameters.put("param1", "value1");
108         parameters.put("param2", "value2");
109 
110         StringBuffer url = new StringBuffer("http://localhost:8080/myContext/myPage.jsp?initParam=initValue");
111 
112         UrlHelper.buildParametersString(parameters, url);
113 
114         assertEquals(
115            expectedUrl, url.toString());
116     }
117 
118     public void testForceAddNullSchemeHostAndPort() throws Exception {
119         String expectedUrl = "http://localhost/contextPath/path1/path2/myAction.action";
120 
121         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
122         mockHttpServletRequest.expectAndReturn("getScheme", "http");
123         mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
124         mockHttpServletRequest.expectAndReturn("getContextPath",
125             "/contextPath");
126 
127         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
128         mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl,
129             expectedUrl);
130 
131         String result = UrlHelper.buildUrl("/path1/path2/myAction.action",
132             (HttpServletRequest) mockHttpServletRequest.proxy(),
133             (HttpServletResponse) mockHttpServletResponse.proxy(), null,
134             null, true, true, true);
135         assertEquals(expectedUrl, result);
136         mockHttpServletRequest.verify();
137     }
138 
139     public void testBuildWithRootContext() {
140         String expectedUrl = "/MyAction.action";
141 
142         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
143         mockHttpServletRequest.expectAndReturn("getContextPath", "/");
144         mockHttpServletRequest.expectAndReturn("getScheme", "http");
145 
146         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
147         mockHttpServletResponse.expectAndReturn("encodeURL", expectedUrl, expectedUrl);
148 
149         String actualUrl = UrlHelper.buildUrl(expectedUrl, (HttpServletRequest) mockHttpServletRequest.proxy(),
150                 (HttpServletResponse) mockHttpServletResponse.proxy(), new HashMap());
151         assertEquals(expectedUrl, actualUrl);
152     }
153 
154     /***
155      * just one &, not &
156      */
157     public void testBuildUrlCorrectlyAddsAmp() {
158         String expectedString = "my.actionName?foo=bar&hello=world";
159         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
160         mockHttpServletRequest.expectAndReturn("getScheme", "http");
161         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
162         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
163 
164         String actionName = "my.actionName";
165         TreeMap params = new TreeMap();
166         params.put("hello", "world");
167         params.put("foo", "bar");
168 
169         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
170         assertEquals(expectedString, urlString);
171     }
172     
173     /***
174      * just one &, not &
175      */
176     public void testBuildUrlCorrectlyAddsDoNotEscapeAmp() {
177         String expectedString = "my.actionName?foo=bar&hello=world";
178         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
179         mockHttpServletRequest.expectAndReturn("getScheme", "http");
180         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
181         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
182 
183         String actionName = "my.actionName";
184         TreeMap params = new TreeMap();
185         params.put("hello", "world");
186         params.put("foo", "bar");
187 
188         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, null, true, true, false, false);
189         assertEquals(expectedString, urlString);
190     }
191 
192     public void testBuildUrlWithStringArray() {
193         String expectedString = "my.actionName?foo=bar&hello=earth&hello=mars";
194         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
195         mockHttpServletRequest.expectAndReturn("getScheme", "http");
196         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
197         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
198 
199         String actionName = "my.actionName";
200         TreeMap params = new TreeMap();
201         params.put("hello", new String[]{"earth", "mars"});
202         params.put("foo", "bar");
203 
204         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params);
205         assertEquals(expectedString, urlString);
206     }
207 
208     /***
209      * The UrlHelper should build a URL that starts with "https" followed by the server name when the scheme of the
210      * current request is "http" and the port for the "https" scheme is 443.
211      */
212     public void testSwitchToHttpsScheme() {
213         String expectedString = "https://www.mydomain.com/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars";
214 
215         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
216         mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com");
217         mockHttpServletRequest.expectAndReturn("getScheme", "http");
218         mockHttpServletRequest.expectAndReturn("getServerPort", 80);
219         mockHttpServletRequest.expectAndReturn("getContextPath", "/mywebapp");
220 
221         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
222         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
223 
224         String actionName = "/MyAction.action";
225         TreeMap params = new TreeMap();
226         params.put("hello", new String[]{"earth", "mars"});
227         params.put("foo", "bar");
228 
229         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
230         assertEquals(expectedString, urlString);
231     }
232 
233     /***
234      * The UrlHelper should build a URL that starts with "http" followed by the server name when the scheme of the
235      * current request is "https" and the port for the "http" scheme is 80.
236      */
237     public void testSwitchToHttpScheme() {
238         String expectedString = "http://www.mydomain.com/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars";
239 
240         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
241         mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com");
242         mockHttpServletRequest.expectAndReturn("getScheme", "https");
243         mockHttpServletRequest.expectAndReturn("getServerPort", 443);
244         mockHttpServletRequest.expectAndReturn("getContextPath", "/mywebapp");
245 
246         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
247         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
248 
249         String actionName = "/MyAction.action";
250         TreeMap params = new TreeMap();
251         params.put("hello", new String[]{"earth", "mars"});
252         params.put("foo", "bar");
253 
254         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
255         assertEquals(expectedString, urlString);
256     }
257 
258     /***
259      * This test is similar to {@link #testSwitchToHttpsScheme()} with the HTTP port equal to 7001 and the HTTPS port
260      * equal to 7002.
261      */
262     public void testSwitchToHttpsNonDefaultPort() {
263 
264         String expectedString = "https://www.mydomain.com:7002/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars";
265 
266         setProp(StrutsConstants.STRUTS_URL_HTTP_PORT, "7001");
267         setProp(StrutsConstants.STRUTS_URL_HTTPS_PORT, "7002");
268 
269         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
270         mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com");
271         mockHttpServletRequest.expectAndReturn("getScheme", "http");
272         mockHttpServletRequest.expectAndReturn("getServerPort", 7001);
273         mockHttpServletRequest.expectAndReturn("getContextPath", "/mywebapp");
274 
275         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
276         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
277 
278         String actionName = "/MyAction.action";
279         TreeMap params = new TreeMap();
280         params.put("hello", new String[]{"earth", "mars"});
281         params.put("foo", "bar");
282 
283         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
284         assertEquals(expectedString, urlString);
285     }
286 
287     /***
288      * This test is similar to {@link #testSwitchToHttpScheme()} with the HTTP port equal to 7001 and the HTTPS port
289      * equal to port 7002.
290      */
291     public void testSwitchToHttpNonDefaultPort() {
292 
293         String expectedString = "http://www.mydomain.com:7001/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars";
294 
295         setProp(StrutsConstants.STRUTS_URL_HTTP_PORT, "7001");
296         setProp(StrutsConstants.STRUTS_URL_HTTPS_PORT, "7002");
297 
298         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
299         mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com");
300         mockHttpServletRequest.expectAndReturn("getScheme", "https");
301         mockHttpServletRequest.expectAndReturn("getServerPort", 7002);
302         mockHttpServletRequest.expectAndReturn("getContextPath", "/mywebapp");
303 
304         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
305         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
306 
307         String actionName = "/MyAction.action";
308         TreeMap params = new TreeMap();
309         params.put("hello", new String[]{"earth", "mars"});
310         params.put("foo", "bar");
311 
312         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "http", true, true);
313         assertEquals(expectedString, urlString);
314     }
315 
316     /***
317      * The UrlHelper should build a URL that starts with "https" followed by the server name when the scheme of the
318      * current request is "http" and the port for the "https" scheme is 443. When the request has been forwarded
319      * in a Servlet 2.4 container, the UrlHelper should use the javax.servlet.forward.request_uri request attribute
320      * instead of a call to HttpServletRequest#getRequestURI().
321      */
322     public void testForwardedRequest() {
323         String expectedString = "https://www.example.com/mywebapp/product/widget/promo.html";
324 
325         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
326         mockHttpServletRequest.expectAndReturn("getServerName", "www.example.com");
327         mockHttpServletRequest.expectAndReturn("getScheme", "http");
328         mockHttpServletRequest.expectAndReturn("getServerPort", 80);
329         mockHttpServletRequest.expectAndReturn("getContextPath", "/mywebapp");
330         mockHttpServletRequest.expectAndReturn("getAttribute", "javax.servlet.forward.request_uri", "/mywebapp/product/widget/");
331         mockHttpServletRequest.expectAndReturn("getRequestURI", "/mywebapp/");
332 
333         Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
334         mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, expectedString);
335 
336         String actionName = "promo.html";
337         Map params = new TreeMap();
338 
339         String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) mockHttpServletResponse.proxy(), params, "https", true, true);
340         assertEquals(expectedString, urlString);
341     }
342 
343 
344     public void testParseQuery() throws Exception {
345         Map result = UrlHelper.parseQueryString("aaa=aaaval&bbb=bbbval&ccc=");
346 
347         assertEquals(result.get("aaa"), "aaaval");
348         assertEquals(result.get("bbb"), "bbbval");
349         assertEquals(result.get("ccc"), "");
350     }
351 
352     public void testParseEmptyQuery() throws Exception {
353         Map result = UrlHelper.parseQueryString("");
354 
355         assertNotNull(result);
356         assertEquals(result.size(), 0);
357     }
358 
359     public void testParseNullQuery() throws Exception {
360         Map result = UrlHelper.parseQueryString(null);
361 
362         assertNotNull(result);
363         assertEquals(result.size(), 0);
364     }
365 
366 
367     public void testTranslateAndEncode() throws Exception {
368         setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
369         String result = UrlHelper.translateAndEncode("\u65b0\u805e");
370         String expectedResult = "%E6%96%B0%E8%81%9E";
371 
372         assertEquals(result, expectedResult);
373     }
374 
375     public void testTranslateAndDecode() throws Exception {
376         setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
377         String result = UrlHelper.translateAndDecode("%E6%96%B0%E8%81%9E");
378         String expectedResult = "\u65b0\u805e";
379 
380         assertEquals(result, expectedResult);
381     }
382     
383     public void setUp() throws Exception {
384         super.setUp();
385         stubContainer = new StubContainer(container);
386         ActionContext.getContext().put(ActionContext.CONTAINER, stubContainer);
387     }
388     
389     private void setProp(String key, String val) {
390         stubContainer.overrides.put(key, val);
391     }
392     
393     class StubContainer implements Container {
394 
395         Container parent;
396         
397         public StubContainer(Container parent) {
398             super();
399             this.parent = parent;
400         }
401         
402         public Map<String, Object> overrides = new HashMap<String,Object>();
403         public <T> T getInstance(Class<T> type, String name) {
404             if (String.class.isAssignableFrom(type) && overrides.containsKey(name)) {
405                 return (T) overrides.get(name);
406             } else {
407                 return parent.getInstance(type, name);
408             }
409         }
410 
411         public <T> T getInstance(Class<T> type) {
412             return parent.getInstance(type);
413         }
414 
415         public Set<String> getInstanceNames(Class<?> type) {
416             return parent.getInstanceNames(type);
417         }
418 
419         public void inject(Object o) {
420             parent.inject(o);
421         }
422 
423         public <T> T inject(Class<T> implementation) {
424             return parent.inject(implementation);
425         }
426 
427         public void removeScopeStrategy() {
428             parent.removeScopeStrategy();
429             
430         }
431 
432         public void setScopeStrategy(Strategy scopeStrategy) {
433             parent.setScopeStrategy(scopeStrategy);
434         }
435     }
436 }