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