1   /*
2    * Copyright 2006 The Apache Software Foundation
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, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.chain.web.portlet;
17  
18  
19  import junit.framework.Test;
20  import junit.framework.TestSuite;
21  import org.apache.commons.chain.Context;
22  import org.apache.commons.chain.impl.ContextBaseTestCase;
23  import org.apache.commons.chain.web.WebContext;
24  
25  import javax.portlet.PortletContext;
26  import javax.portlet.PortletRequest;
27  import javax.portlet.PortletResponse;
28  import javax.portlet.PortletSession;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.Map;
32  import java.util.Set;
33  import java.util.Collection;
34  
35  
36  /***
37   * Extension of <code>ContextBaseTestCase</code> to validate the
38   * extra functionality of this implementation.
39   */
40  
41  public class PortletWebContextTestCase extends ContextBaseTestCase {
42  
43  
44      // ---------------------------------------------------------- Constructors
45  
46      /***
47       * Construct a new instance of this test case.
48       *
49       * @param name Name of the test case
50       */
51      public PortletWebContextTestCase(String name) {
52          super(name);
53      }
54  
55  
56      // ----------------------------------------------------- Instance Variables
57  
58  
59      // Portlet API Objects
60      protected PortletContext pcontext = null;
61      protected PortletRequest request = null;
62      protected PortletResponse response = null;
63      protected PortletSession session = null;
64  
65  
66      // -------------------------------------------------- Overall Test Methods
67  
68  
69      /***
70       * Set up instance variables required by this test case.
71       */
72      public void setUp() {
73          pcontext = new MockPortletContext();
74          pcontext.setAttribute("akey1", "avalue1");
75          pcontext.setAttribute("akey2", "avalue2");
76          pcontext.setAttribute("akey3", "avalue3");
77          pcontext.setAttribute("akey4", "avalue4");
78          ((MockPortletContext) pcontext).addInitParameter("ikey1", "ivalue1");
79          ((MockPortletContext) pcontext).addInitParameter("ikey2", "ivalue2");
80          ((MockPortletContext) pcontext).addInitParameter("ikey3", "ivalue3");
81          session = new MockPortletSession(pcontext);
82          session.setAttribute("skey1", "svalue1");
83          session.setAttribute("skey2", "svalue2");
84          session.setAttribute("skey3", "svalue3");
85          request = new MockPortletRequest(null, pcontext, session);
86          request.setAttribute("rkey1", "rvalue1");
87          request.setAttribute("rkey2", "rvalue2");
88          ((MockPortletRequest) request).addParameter("pkey1", "pvalue1");
89          ((MockPortletRequest) request).addParameter("pkey2", "pvalue2a");
90          ((MockPortletRequest) request).addParameter("pkey2", "pvalue2b");
91          context = createContext();
92      }
93  
94  
95      /***
96       * Return the tests included in this test suite.
97       */
98      public static Test suite() {
99          return (new TestSuite(PortletWebContextTestCase.class));
100     }
101 
102 
103     /***
104      * Tear down instance variables required by this test case.
105      */
106     public void tearDown() {
107         pcontext = null;
108         session = null;
109         request = null;
110         response = null;
111         context = null;
112     }
113 
114 
115     // ------------------------------------------------ Individual Test Methods
116 
117 
118     // Test getApplicationScope()
119     public void testApplicationScope() {
120 
121         Map map = ((WebContext) context).getApplicationScope();
122         assertNotNull(map);
123 
124         // Initial contents
125         checkMapSize(map, 4);
126         assertEquals("avalue1", (String) map.get("akey1"));
127         assertEquals("avalue2", (String) map.get("akey2"));
128         assertEquals("avalue3", (String) map.get("akey3"));
129         assertEquals("avalue4", (String) map.get("akey4"));
130 
131         // Transparency - entrySet()
132         checkEntrySet(map, true);
133  
134         // Transparency - removal via web object
135         pcontext.removeAttribute("akey1");
136         checkMapSize(map, 3);
137         assertNull(map.get("akey1"));
138 
139         // Transparency - removal via map
140         map.remove("akey2");
141         checkMapSize(map, 2);
142         assertNull(pcontext.getAttribute("akey2"));
143 
144         // Transparency - addition via web object
145         pcontext.setAttribute("akeyA", "avalueA");
146         checkMapSize(map, 3);
147         assertEquals("avalueA", (String) map.get("akeyA"));
148 
149         // Transparency - addition via map
150         map.put("akeyB", "avalueB");
151         checkMapSize(map, 4);
152         assertEquals("avalueB", (String) pcontext.getAttribute("akeyB"));
153 
154         // Transparency - replacement via web object
155         pcontext.setAttribute("akeyA", "newvalueA");
156         checkMapSize(map, 4);
157         assertEquals("newvalueA", (String) map.get("akeyA"));
158 
159         // Transparency - replacement via map
160         map.put("akeyB", "newvalueB");
161         assertEquals(4, map.size());
162         assertEquals("newvalueB", (String) pcontext.getAttribute("akeyB"));
163 
164         // Clearing the map
165         map.clear();
166         checkMapSize(map, 0);
167 
168     }
169 
170 
171     // Test equals() and hashCode()
172     // Copied from ContextBaseTestCase with customized creation of "other"
173     public void testEquals() {
174 
175         // Compare to self
176         assertTrue(context.equals(context));
177         assertTrue(context.hashCode() == context.hashCode());
178 
179         // Compare to equivalent instance
180         Context other = new PortletWebContext(pcontext, request, response);
181         // assertTrue(context.equals(other));
182         assertTrue(context.hashCode() == other.hashCode());
183 
184         // Compare to non-equivalent instance - other modified
185         other.put("bop", "bop value");
186         // assertTrue(!context.equals(other));
187         assertTrue(context.hashCode() != other.hashCode());
188 
189         // Compare to non-equivalent instance - self modified
190         other = new PortletWebContext(pcontext, request, response);
191         context.put("bop", "bop value");
192         // assertTrue(!context.equals(other));
193         assertTrue(context.hashCode() != other.hashCode());
194 
195     }        
196 
197 
198     // Test getHeader()
199     public void testHeader() {
200 
201         Map map = ((WebContext) context).getHeader();
202         assertNotNull("Header Map Null", map);
203 
204         // Initial contents
205         checkMapSize(map, 0);
206 
207         try {
208             map.put("hkey3", "hvalue3");
209             fail("Should have thrown UnsupportedOperationException");
210         } catch (UnsupportedOperationException e) {
211             ; // expected result
212         }
213 
214     }
215 
216 
217     // Test getHeaderValues()
218     public void testHeaderValues() {
219 
220         Map map = ((WebContext) context).getHeaderValues();
221         assertNotNull("HeaderValues Map Null", map);
222 
223         // Initial contents
224         checkMapSize(map, 0);
225  
226         try {
227             map.put("hkey3", "ABC");
228             fail("Should have thrown UnsupportedOperationException");
229         } catch (UnsupportedOperationException e) {
230             ; // expected result
231         }
232 
233     }
234 
235 
236     // Test getInitParam()
237     public void testInitParam() {
238 
239         Map map = ((WebContext) context).getInitParam();
240         assertNotNull(map);
241 
242         // Initial contents
243         checkMapSize(map, 3);
244         assertEquals("ivalue1", (String) map.get("ikey1"));
245         assertEquals("ivalue2", (String) map.get("ikey2"));
246         assertEquals("ivalue3", (String) map.get("ikey3"));
247         assertTrue(map.containsKey("ikey1"));
248         assertTrue(map.containsKey("ikey2"));
249         assertTrue(map.containsKey("ikey3"));
250         assertTrue(map.containsValue("ivalue1"));
251         assertTrue(map.containsValue("ivalue2"));
252         assertTrue(map.containsValue("ivalue3"));
253 
254         // Transparency - entrySet()
255         checkEntrySet(map, false);
256  
257         // Unsupported operations on read-only map
258         try {
259             map.clear();
260             fail("Should have thrown UnsupportedOperationException");
261         } catch (UnsupportedOperationException e) {
262             ; // expected result
263         }
264         try {
265             map.put("ikey4", "ivalue4");
266             fail("Should have thrown UnsupportedOperationException");
267         } catch (UnsupportedOperationException e) {
268             ; // expected result
269         }
270         try {
271             map.putAll(new HashMap());
272             fail("Should have thrown UnsupportedOperationException");
273         } catch (UnsupportedOperationException e) {
274             ; // expected result
275         }
276         try {
277             map.remove("ikey1");
278             fail("Should have thrown UnsupportedOperationException");
279         } catch (UnsupportedOperationException e) {
280             ; // expected result
281         }
282 
283     }
284 
285 
286     // Test getParam()
287     public void testParam() {
288 
289         Map map = ((WebContext) context).getParam();
290         assertNotNull(map);
291 
292         // Initial contents
293         checkMapSize(map, 2);
294         assertEquals("pvalue1", (String) map.get("pkey1"));
295         assertEquals("pvalue2a", (String) map.get("pkey2"));
296         assertTrue(map.containsKey("pkey1"));
297         assertTrue(map.containsKey("pkey2"));
298         assertTrue(map.containsValue("pvalue1"));
299         assertTrue(map.containsValue("pvalue2a"));
300 
301         checkEntrySet(map, false);
302 
303         // Unsupported operations on read-only map
304         try {
305             map.clear();
306             fail("Should have thrown UnsupportedOperationException");
307         } catch (UnsupportedOperationException e) {
308             ; // expected result
309         }
310         try {
311             map.put("pkey3", "pvalue3");
312             fail("Should have thrown UnsupportedOperationException");
313         } catch (UnsupportedOperationException e) {
314             ; // expected result
315         }
316         try {
317             map.putAll(new HashMap());
318             fail("Should have thrown UnsupportedOperationException");
319         } catch (UnsupportedOperationException e) {
320             ; // expected result
321         }
322         try {
323             map.remove("pkey1");
324             fail("Should have thrown UnsupportedOperationException");
325         } catch (UnsupportedOperationException e) {
326             ; // expected result
327         }
328 
329     }
330 
331 
332     // Test getParamValues()
333     public void testParamValues() {
334 
335         Map map = ((WebContext) context).getParamValues();
336         assertNotNull(map);
337 
338         // Initial contents
339         checkMapSize(map, 2);
340         Object value1 = map.get("pkey1");
341         assertNotNull(value1);
342         assertTrue(value1 instanceof String[]);
343         String values1[] = (String[]) value1;
344         assertEquals(1, values1.length);
345         assertEquals("pvalue1", values1[0]);
346         Object value2 = map.get("pkey2");
347         assertNotNull(value2);
348         assertTrue(value2 instanceof String[]);
349         String values2[] = (String[]) value2;
350         assertEquals(2, values2.length);
351         assertEquals("pvalue2a", values2[0]);
352         assertEquals("pvalue2b", values2[1]);
353         assertTrue(map.containsKey("pkey1"));
354         assertTrue(map.containsKey("pkey2"));
355         assertTrue(map.containsValue(values1));
356         assertTrue(map.containsValue(values2));
357 
358         // Unsupported operations on read-only map
359         try {
360             map.clear();
361             fail("Should have thrown UnsupportedOperationException");
362         } catch (UnsupportedOperationException e) {
363             ; // expected result
364         }
365         try {
366             map.put("pkey3", values2);
367             fail("Should have thrown UnsupportedOperationException");
368         } catch (UnsupportedOperationException e) {
369             ; // expected result
370         }
371         try {
372             map.putAll(new HashMap());
373             fail("Should have thrown UnsupportedOperationException");
374         } catch (UnsupportedOperationException e) {
375             ; // expected result
376         }
377         try {
378             map.remove("pkey1");
379             fail("Should have thrown UnsupportedOperationException");
380         } catch (UnsupportedOperationException e) {
381             ; // expected result
382         }
383 
384     }
385 
386 
387     // Test getCookies()
388     public void testCookies() {
389 
390         Map map = ((WebContext) context).getCookies();
391         assertNotNull(map);
392 
393         // Initial contents
394         checkMapSize(map, 0);
395 
396         try {
397             map.put("ckey3", "XXX");
398             fail("map.put() Should have thrown UnsupportedOperationException");
399         } catch (UnsupportedOperationException e) {
400             ; // expected result
401         }
402     }
403 
404     // Test state of newly created instance
405     public void testPristine() {
406 
407         super.testPristine();
408         PortletWebContext pwcontext = (PortletWebContext) context;
409 
410         // Properties should all be non-null
411         assertNotNull(pwcontext.getApplicationScope());
412         assertNotNull(pwcontext.getHeader());
413         assertNotNull(pwcontext.getHeaderValues());
414         assertNotNull(pwcontext.getInitParam());
415         assertNotNull(pwcontext.getParam());
416         assertNotNull(pwcontext.getParamValues());
417         assertNotNull(pwcontext.getCookies());
418         assertNotNull(pwcontext.getRequestScope());
419         assertNotNull(pwcontext.getSessionScope());
420 
421         // Attribute-property transparency
422         assertTrue(pwcontext.getApplicationScope() ==
423                      pwcontext.get("applicationScope"));
424         assertTrue(pwcontext.getHeader() ==
425                      pwcontext.get("header"));
426         assertTrue(pwcontext.getHeaderValues() ==
427                      pwcontext.get("headerValues"));
428         assertTrue(pwcontext.getInitParam() ==
429                      pwcontext.get("initParam"));
430         assertTrue(pwcontext.getParam() ==
431                      pwcontext.get("param"));
432         assertTrue(pwcontext.getParamValues() ==
433                      pwcontext.get("paramValues"));
434         assertTrue(pwcontext.getCookies() ==
435                      pwcontext.get("cookies"));
436         assertTrue(pwcontext.getRequestScope() ==
437                      pwcontext.get("requestScope"));
438         assertTrue(pwcontext.getSessionScope() ==
439                      pwcontext.get("sessionScope"));
440 
441     }
442 
443 
444     // Test release()
445     public void testRelease() {
446 
447         PortletWebContext pwcontext = (PortletWebContext) context;
448         pwcontext.release();
449 
450         // Properties should all be null
451         assertNull("getApplicationScope()", pwcontext.getApplicationScope());
452         assertNull("getHeader()", pwcontext.getHeader());
453         assertNull("getHeaderValues()", pwcontext.getHeaderValues());
454         assertNull("getInitParam()", pwcontext.getInitParam());
455         assertNull("getParam()", pwcontext.getParam());
456         assertNull("getParamValues()", pwcontext.getParamValues());
457         assertNull("getRequestScope()", pwcontext.getRequestScope());
458         assertNull("getSessionScope()", pwcontext.getSessionScope());
459 
460         // Attributes should all be null
461         assertNull("applicationScope", pwcontext.get("applicationScope"));
462         assertNull("header", pwcontext.get("header"));
463         assertNull("headerValues", pwcontext.get("headerValues"));
464         assertNull("initParam", pwcontext.get("initParam"));
465         assertNull("param", pwcontext.get("param"));
466         assertNull("paramValues", pwcontext.get("paramValues"));
467         assertNull("requestScope", pwcontext.get("requestScope"));
468         assertNull("sessionScope", pwcontext.get("sessionScope"));
469 
470     }
471 
472 
473     // Test getRequestScope()
474     public void testRequestScope() {
475 
476         Map map = ((WebContext) context).getRequestScope();
477         assertNotNull(map);
478 
479         // Initial contents
480         checkMapSize(map, 2);
481         assertEquals("rvalue1", (String) map.get("rkey1"));
482         assertEquals("rvalue2", (String) map.get("rkey2"));
483 
484         // Transparency - entrySet()
485         checkEntrySet(map, true);
486  
487         // Transparency - removal via web object
488         request.removeAttribute("rkey1");
489         checkMapSize(map, 1);
490         assertNull(map.get("rkey1"));
491 
492         // Transparency - removal via map
493         map.remove("rkey2");
494         checkMapSize(map, 0);
495         assertNull(request.getAttribute("rkey2"));
496 
497         // Transparency - addition via web object
498         request.setAttribute("rkeyA", "rvalueA");
499         checkMapSize(map, 1);
500         assertEquals("rvalueA", (String) map.get("rkeyA"));
501 
502         // Transparency - addition via map
503         map.put("rkeyB", "rvalueB");
504         checkMapSize(map, 2);
505         assertEquals("rvalueB", (String) request.getAttribute("rkeyB"));
506 
507         // Transparency - replacement via web object
508         request.setAttribute("rkeyA", "newvalueA");
509         checkMapSize(map, 2);
510         assertEquals("newvalueA", (String) map.get("rkeyA"));
511 
512         // Transparency - replacement via map
513         map.put("rkeyB", "newvalueB");
514         checkMapSize(map, 2);
515         assertEquals("newvalueB", (String) request.getAttribute("rkeyB"));
516 
517         // Clearing the map
518         map.clear();
519         checkMapSize(map, 0);
520 
521     }
522 
523 
524     // Test getSessionScope()
525     public void testSessionScope() {
526 
527         Map map = ((WebContext) context).getSessionScope();
528         assertNotNull(map);
529 
530         // Initial contents
531         checkMapSize(map, 3);
532         assertEquals("svalue1", (String) map.get("skey1"));
533         assertEquals("svalue2", (String) map.get("skey2"));
534         assertEquals("svalue3", (String) map.get("skey3"));
535 
536         // Transparency - entrySet()
537         checkEntrySet(map, true);
538  
539         // Transparency - removal via web object
540         session.removeAttribute("skey1");
541         checkMapSize(map, 2);
542         assertNull(map.get("skey1"));
543 
544         // Transparency - removal via map
545         map.remove("skey2");
546         checkMapSize(map, 1);
547         assertNull(session.getAttribute("skey2"));
548 
549         // Transparency - addition via web object
550         session.setAttribute("skeyA", "svalueA");
551         checkMapSize(map, 2);
552         assertEquals("svalueA", (String) map.get("skeyA"));
553 
554         // Transparency - addition via map
555         map.put("skeyB", "svalueB");
556         checkMapSize(map, 3);
557         assertEquals("svalueB", (String) session.getAttribute("skeyB"));
558 
559         // Transparency - replacement via web object
560         session.setAttribute("skeyA", "newvalueA");
561         checkMapSize(map, 3);
562         assertEquals("newvalueA", (String) map.get("skeyA"));
563 
564         // Transparency - replacement via map
565         map.put("skeyB", "newvalueB");
566         checkMapSize(map, 3);
567         assertEquals("newvalueB", (String) session.getAttribute("skeyB"));
568 
569         // Clearing the map
570         map.clear();
571         checkMapSize(map, 0);
572 
573     }
574 
575 
576     // Test getSessionScope() without Session
577     public void testSessionScopeWithoutSession() {
578 
579         // Create a Context without a session
580         PortletWebContext ctx = new PortletWebContext(pcontext, 
581            new MockPortletRequest(), response);
582         assertNull("Session(A)", ctx.getRequest().getPortletSession(false));
583 
584         // Get the session Map & check session doesn't exist
585         Map sessionMap = ctx.getSessionScope();
586         assertNull("Session(B)", ctx.getRequest().getPortletSession(false));
587         assertNotNull("Session Map(A)", sessionMap);
588 
589         // test clear()
590         sessionMap.clear();
591         assertNull("Session(C)", ctx.getRequest().getPortletSession(false));
592 
593         // test containsKey()
594         assertFalse("containsKey()", sessionMap.containsKey("ABC"));
595         assertNull("Session(D)", ctx.getRequest().getPortletSession(false));
596 
597         // test containsValue()
598         assertFalse("containsValue()", sessionMap.containsValue("ABC"));
599         assertNull("Session(E)", ctx.getRequest().getPortletSession(false));
600 
601         // test entrySet()
602         Set entrySet = sessionMap.entrySet();
603         assertNotNull("entrySet", entrySet);
604         assertEquals("entrySet Size", 0, entrySet.size());
605         assertNull("Session(F)", ctx.getRequest().getPortletSession(false));
606 
607         // test equals()
608         assertFalse("equals()", sessionMap.equals("ABC"));
609         assertNull("Session(G)", ctx.getRequest().getPortletSession(false));
610 
611         // test get()
612         assertNull("get()", sessionMap.get("ABC"));
613         assertNull("Session(H)", ctx.getRequest().getPortletSession(false));
614 
615         // test hashCode()
616         sessionMap.hashCode();
617         assertNull("Session(I)", ctx.getRequest().getPortletSession(false));
618 
619         // test isEmpty()
620         assertTrue("isEmpty()", sessionMap.isEmpty());
621         assertNull("Session(J)", ctx.getRequest().getPortletSession(false));
622 
623         // test keySet()
624         Set keySet = sessionMap.keySet();
625         assertNotNull("keySet", keySet);
626         assertEquals("keySet Size", 0, keySet.size());
627         assertNull("Session(K)", ctx.getRequest().getPortletSession(false));
628 
629         // test putAll() with an empty Map
630         sessionMap.putAll(new HashMap());
631         assertNull("Session(L)", ctx.getRequest().getPortletSession(false));
632 
633         // test remove()
634         assertNull("remove()", sessionMap.remove("ABC"));
635         assertNull("Session(M)", ctx.getRequest().getPortletSession(false));
636 
637         // test size()
638         assertEquals("size() Size", 0, sessionMap.size());
639         assertNull("Session(N)", ctx.getRequest().getPortletSession(false));
640 
641         // test values()
642         Collection values = sessionMap.values();
643         assertNotNull("values", values);
644         assertEquals("values Size", 0, values.size());
645         assertNull("Session(O)", ctx.getRequest().getPortletSession(false));
646 
647         // test put()
648         try {
649             assertNull("put()", sessionMap.put("ABC", "XYZ"));
650             assertNotNull("Session(P)", ctx.getRequest().getPortletSession(false));
651         } catch(UnsupportedOperationException ex) {
652             // expected: currently MockPortletRequest throws this
653             //           when trying to create a PortletSession
654         }
655 
656     }
657 
658 
659     // ------------------------------------------------------- Protected Methods
660 
661 
662     protected void checkMapSize(Map map, int size) {
663         // Check reported size of the map
664         assertEquals("checkMapSize(A)", size, map.size());
665         // Iterate over key set
666         int nk = 0;
667         Iterator keys = map.keySet().iterator();
668         while (keys.hasNext()) {
669             keys.next();
670             nk++;
671         }
672         assertEquals("checkMapSize(B)", size, nk);
673         // Iterate over entry set
674         int nv = 0;
675         Iterator values = map.entrySet().iterator();
676         while (values.hasNext()) {
677             values.next();
678             nv++;
679         }
680         assertEquals("checkMapSize(C)", size, nv);
681         // Count the values
682         assertEquals("checkMapSize(D)", size, map.values().size());
683     }
684 
685     // Test to ensure proper entrySet() and are modifiable optionally
686     protected void checkEntrySet(Map map, boolean modifiable) {
687         assertTrue("checkEntrySet(A)", map.size() > 1);
688         Set entries = map.entrySet();
689         assertTrue(map.size() == entries.size());
690         Object o = entries.iterator().next();
691 
692         assertTrue("checkEntrySet(B)", o instanceof Map.Entry);
693 
694         if (!modifiable) {
695             try {
696                 ((Map.Entry)o).setValue(new Object());
697                 fail("Should have thrown UnsupportedOperationException");
698             } catch (UnsupportedOperationException e) {
699                 ; // expected result
700             }
701         } else {
702             // Should pass and not throw UnsupportedOperationException
703             Map.Entry e = (Map.Entry)o;
704             e.setValue(e.setValue(new Object()));
705         }    
706     }    
707 
708     // Create a new instance of the appropriate Context type for this test case
709     protected Context createContext() {
710         return (new PortletWebContext(pcontext, request, response));
711     }
712 
713 
714 }