2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.util;
19  
20  import java.io.StringWriter;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Locale;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import javax.faces.application.FacesMessage;
28  import javax.faces.component.UIComponent;
29  import javax.faces.component.UIInput;
30  import javax.faces.component.UIViewRoot;
31  import javax.faces.context.ResponseWriter;
32  
33  import junit.framework.Test;
34  import junit.framework.TestSuite;
35  
36  import org.apache.shale.component.Token;
37  import org.apache.shale.renderer.TokenRenderer;
38  import org.apache.shale.test.base.AbstractJsfTestCase;
39  
40  /***
41   * <p>Test case for <code>TokenProcessor</code>.</p>
42   */
43  public class TokenProcessorTestCase extends AbstractJsfTestCase {
44      
45  
46      // ------------------------------------------------------------ Constructors
47  
48  
49      // Construct a new instance of this test case.
50      public TokenProcessorTestCase(String name) {
51          super(name);
52      }
53  
54  
55      // ---------------------------------------------------- Overall Test Methods
56  
57  
58      // Set up instance variables required by this test case.
59      protected void setUp() throws Exception {
60  
61          super.setUp();
62  
63          // Set up the instance we will be testing
64          tp = new TokenProcessor();
65          
66          //register the Token component
67          application.addComponent("org.apache.shale.Token", "org.apache.shale.component.Token");
68          facesContext.getRenderKit().addRenderer("org.apache.shale.Token", 
69                  "org.apache.shale.Token",
70                  new TokenRenderer());
71      }
72  
73  
74      // Return the tests included in this test case.
75      public static Test suite() {
76  
77          return (new TestSuite(TokenProcessorTestCase.class));
78  
79      }
80  
81  
82      // Tear down instance variables required by this test case.
83      protected void tearDown() throws Exception {
84  
85          tp = null;
86          super.tearDown();
87  
88      }
89  
90  
91      // ------------------------------------------------------ Instance Variables
92  
93  
94      // The instance to be tested
95      TokenProcessor tp = null;
96  
97  
98      // ------------------------------------------------------------ Test Methods
99  
100 
101     // Test generation of multiple tokens and the ability to validate them
102     public void testMultiple() {
103 
104         Set set = new HashSet();
105 
106         // Create a bunch of tokens
107         for (int i = 0; i < 1000; i++) {
108             String token = null;
109             while (true) {
110                 token = tp.generate(facesContext);
111                 if (!set.contains(token)) {
112                     break;
113                 }
114             }
115             set.add(token);
116         }
117 
118         // Ensure that we can verify all of them
119         Iterator tokens = set.iterator();
120         while (tokens.hasNext()) {
121             String token = (String) tokens.next();
122             assertTrue("Cannot verify token '" + token + "'", tp.verify(facesContext, token));
123         }
124         
125     }
126 
127 
128     // Test a pristine instance
129     public void testPristine() {
130 
131         assertNotNull(tp);
132 
133     }
134 
135     public void testMessagePropertyOverride() throws Exception {
136 
137        final String SUMMARY_MESSAGE = "This page is dirty.  Evil browser back button."; 
138        final String DETAIL_MESSAGE = "This page has been mark as having durability of a single submit and this contract has been violated by the submission of a dirty page.";
139 
140        Token token = (Token) facesContext.getApplication().createComponent("org.apache.shale.Token");
141        assertNotNull(token);
142        
143        UIViewRoot root = facesContext.getViewRoot();
144        assertNotNull(root);
145        
146        // add token to the component tree
147        root.getChildren().add(root.getChildCount(), token);
148              
149        token.setId("messagePropertyOverride");
150        token.setMessageSummary(SUMMARY_MESSAGE);
151        token.setMessageDetail(DETAIL_MESSAGE);
152        
153        StringBuffer htmlSnippet = encode(token);       
154        // check rendered markup
155        String id = getAttribute(htmlSnippet, "id");
156        assertEquals("id", token.getClientId(facesContext), id);
157 
158        String name = getAttribute(htmlSnippet, "name");
159        assertEquals("id", token.getClientId(facesContext), name);
160 
161        String type = getAttribute(htmlSnippet, "type");
162        assertEquals("id", "hidden", type);
163 
164        String value = getAttribute(htmlSnippet, "value");
165        assertNotNull("value", value);
166        
167        // simulate form post on dirty page
168        Map map = facesContext.getExternalContext().getRequestParameterMap();
169        map.put(id, value);
170        
171        // simulate apply values
172        token.decode(facesContext);
173        assertEquals("value", value, token.getSubmittedValue());
174         
175        // simulate validation and invalidates token
176        token.validate(facesContext);
177        
178        checkNoMessages(token);
179        
180        // simulate double post
181        token.validate(facesContext);
182        
183        // check for the custom message
184        checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
185        
186     }
187         
188     public void testMessageFacesConfigBundleOverride() throws Exception {
189         
190         // simulate a faces config resource bundle override
191         application.setDefaultLocale(new Locale("en", "US"));
192         application.setMessageBundle("org.apache.shale.util.TestBundle");
193 
194         //value of the "token.invalid" key in the "org.apache.shale.util.TestBundle"
195         final String SUMMARY_MESSAGE = "Invalid resubmit of the same form is bad news Lucy Luo"; 
196         final String DETAIL_MESSAGE = "This page has been mark as having durability of a single submit and this contract has been violated by the submission of a dirty page.";
197                 
198         Token token = (Token) facesContext.getApplication().createComponent("org.apache.shale.Token");
199         assertNotNull(token);
200         
201         UIViewRoot root = facesContext.getViewRoot();
202         assertNotNull(root);
203         
204         // add token to the component tree
205         root.getChildren().add(root.getChildCount(), token);
206               
207         token.setId("messageFacesConfigBundleOverride");
208         token.setMessageSummary(null);  // no message property override
209         token.setMessageDetail(null);   // no message property override
210         
211         
212         StringBuffer htmlSnippet = encode(token);       
213         // check rendered markup
214         String id = getAttribute(htmlSnippet, "id");
215         assertEquals("id", token.getClientId(facesContext), id);
216 
217         String name = getAttribute(htmlSnippet, "name");
218         assertEquals("id", token.getClientId(facesContext), name);
219 
220         String type = getAttribute(htmlSnippet, "type");
221         assertEquals("id", "hidden", type);
222 
223         String value = getAttribute(htmlSnippet, "value");
224         assertNotNull("value", value);
225         
226         // simulate form post on dirty page
227         Map map = facesContext.getExternalContext().getRequestParameterMap();
228         map.put(id, value);
229         
230         // simulate apply values
231         token.decode(facesContext);
232         assertEquals("value", value, token.getSubmittedValue());
233          
234         // simulate validation and invalidates token
235         token.validate(facesContext);
236         
237         checkNoMessages(token);
238         
239         // simulate double post
240         token.validate(facesContext);
241         
242         // check for the custom message
243         checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
244         
245      }
246 
247     public void testMessageDefault() throws Exception {
248         
249         //value of the "token.invalid" key in the "org.apache.shale.resources.Bundle"
250         final String SUMMARY_MESSAGE = "Invalid resubmit of the same form"; 
251         final String DETAIL_MESSAGE = "Invalid resubmit of the same form";
252                 
253         Token token = (Token) facesContext.getApplication().createComponent("org.apache.shale.Token");
254         assertNotNull(token);
255         
256         UIViewRoot root = facesContext.getViewRoot();
257         assertNotNull(root);
258         
259         // add token to the component tree
260         root.getChildren().add(root.getChildCount(), token);
261               
262         token.setId("messageDefault");
263         token.setMessageSummary(null);  // no message property override
264         
265         StringBuffer htmlSnippet = encode(token);       
266         // check rendered markup
267         String id = getAttribute(htmlSnippet, "id");
268         assertEquals("id", token.getClientId(facesContext), id);
269 
270         String name = getAttribute(htmlSnippet, "name");
271         assertEquals("id", token.getClientId(facesContext), name);
272 
273         String type = getAttribute(htmlSnippet, "type");
274         assertEquals("id", "hidden", type);
275 
276         String value = getAttribute(htmlSnippet, "value");
277         assertNotNull("value", value);
278         
279         // simulate form post on dirty page
280         Map map = facesContext.getExternalContext().getRequestParameterMap();
281         map.put(id, value);
282         
283         // simulate apply values
284         token.decode(facesContext);
285         assertEquals("value", value, token.getSubmittedValue());
286          
287         // simulate validation and invalidates token
288         token.validate(facesContext);
289         
290         checkNoMessages(token);
291         
292         // simulate double post
293         token.validate(facesContext);
294         
295         // check for the custom message
296         checkMessage(SUMMARY_MESSAGE, DETAIL_MESSAGE, token);
297         
298      }
299     
300     
301     
302     //looks for an html attribute in a markup snippet
303     private String getAttribute(StringBuffer htmlSnippet, String attributeName) {
304         String sarg = attributeName + "=\"";
305         int s = htmlSnippet.indexOf(sarg);
306         String value = null;
307         if (s > -1) {
308            s += sarg.length();
309            int e = htmlSnippet.indexOf("\"", s);
310            if (e > -1 && e > s) {
311               value = htmlSnippet.substring(s, e);
312            }
313            
314         }
315         return value;
316     }
317     
318     //looks for an error message added in validation 
319     private void checkMessage(String expectedSummary, String expectedDetail, UIInput component) {
320         String id = component.getClientId(facesContext);
321         Iterator mi = facesContext.getMessages(id);
322         boolean hasMessage = false;
323         while (mi.hasNext()) {
324            FacesMessage message = (FacesMessage) mi.next();    
325            String summary = message.getSummary();
326            String detail = message.getDetail();
327            assertEquals(expectedSummary, summary);
328            assertEquals(expectedDetail, detail);
329            hasMessage = true;
330         }
331         
332         assertTrue(id + " has messages", hasMessage);   
333     }
334     
335     //checks to make sure there are no error messages after validation
336     private void checkNoMessages(UIInput component) {
337         String id = component.getClientId(facesContext);
338         Iterator mi = facesContext.getMessages(id);
339         boolean hasMessage = false;
340         while (mi.hasNext()) {
341            hasMessage = true;
342         }
343         
344         assertFalse(id + " has messages", hasMessage);   
345        
346     }
347 
348     
349     //render and return the results
350     private StringBuffer encode(UIComponent component) throws Exception {
351         //builds a buffer to write the page to
352         StringWriter writer = new StringWriter();
353         //create a buffered response writer
354         ResponseWriter buffResponsewriter = facesContext.getRenderKit()
355                         .createResponseWriter(writer, null, response.getCharacterEncoding());
356         //push buffered writer to the faces context
357         facesContext.setResponseWriter(buffResponsewriter);
358         //start a document
359         buffResponsewriter.startDocument();
360         
361         //render HTML
362         component.encodeBegin(facesContext);
363         component.encodeChildren(facesContext);
364         component.encodeEnd(facesContext);
365         
366         //end the document
367         buffResponsewriter.endDocument();
368         
369         return writer.getBuffer();
370     }
371 
372     
373     
374 }