View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.renderkit.html.behavior;
20  
21  import javax.faces.component.UIComponent;
22  import javax.faces.component.behavior.AjaxBehavior;
23  import javax.faces.component.behavior.ClientBehaviorHolder;
24  import javax.faces.context.ResponseWriter;
25  
26  import org.apache.myfaces.shared.renderkit.html.HtmlResponseWriterImpl;
27  import org.apache.myfaces.shared.util.FastWriter;
28  import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
29  import org.apache.myfaces.test.config.ConfigParser;
30  import org.junit.Assert;
31  import org.junit.Test;
32  
33  /**
34   * @author Leonardo Uribe (latest modification by $Author: bommel $)
35   * @version $Revision: 1187701 $ $Date: 2011-10-22 07:21:54 -0500 (Sat, 22 Oct 2011) $
36   */
37  public abstract class AbstractClientBehaviorTestCase extends AbstractJsfTestCase
38  {
39      protected ResponseWriter writer;
40      protected FastWriter outputWriter; 
41      protected ConfigParser parser;
42      
43      //protected abstract UIComponent getComponentToTest();
44      
45      protected abstract HtmlRenderedClientEventAttr[] getClientBehaviorHtmlRenderedAttributes();
46      
47      protected abstract UIComponent createComponentToTest();
48  
49      @Override
50      protected void setUpJSFObjects() throws Exception
51      {
52          super.setUpJSFObjects();
53          outputWriter = new FastWriter();
54          writer = new HtmlResponseWriterImpl(outputWriter, null, null);
55          facesContext.setResponseWriter(writer);
56          facesContext.getAttributes().put("org.apache.myfaces.RENDERED_JSF_JS", true);
57      }
58      
59      @Override
60      protected void setUpApplication() throws Exception
61      {
62          super.setUpApplication();
63      }
64  
65      @Override
66      protected void setUpRenderKit() throws Exception
67      {
68          super.setUpRenderKit();
69          parser = new ConfigParser();
70          parser.parse(parser.getPlatformURLs());
71          //parser.parse(this.getClass().getResource("/META-INF/faces-config.xml"));        
72      }
73  
74      /**
75       * Components that render client behaviors should always render "id" and "name" attribute
76       */
77      @Test
78      public void testClientBehaviorHolderRendersIdAndName() 
79      {
80          HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
81          
82          for (int i = 0; i < attrs.length; i++)
83          {
84              UIComponent component = createComponentToTest();
85              ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
86              clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
87              try 
88              {
89                  component.encodeAll(facesContext);
90                  String output = outputWriter.toString();
91                  Assert.assertTrue(output.indexOf(" id=\""+component.getClientId(facesContext)+"\"") > -1);
92                  Assert.assertTrue(output.indexOf(" name=\""+component.getClientId(facesContext)+"\"") > -1);
93                  outputWriter.reset();
94              }
95              catch (Exception e)
96              {
97                  Assert.fail(e.getMessage());
98              }
99          }
100     }
101     
102     @Test
103     public void testClientBehaviorRendered() 
104     {
105         HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
106         
107         for (int i = 0; i < attrs.length; i++)
108         {
109             UIComponent component = createComponentToTest();
110             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
111             clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
112             try 
113             {
114                 component.encodeAll(facesContext);
115                 String output = outputWriter.toString();
116                 //jsf.ajax.request('j_id0',event,{'javax.faces.behavior.event':'click'})
117                 //Only check if the property starts with jsf.ajax.request( is enough 
118                 //Assert.assertTrue("output does not match expected output jsf.ajax.request(.... for property "+attrs[i].getName(),
119                 //        output.matches(".+ "+attrs[i].getName()+"=\"jsf\\.ajax\\.request\\(.+"));
120                 int index = checkClientBehaviorRenderedOnClientEventProperty(output, 0, attrs[i]);
121                 outputWriter.reset();
122             }
123             catch (Exception e)
124             {
125                 Assert.fail(e.getMessage());
126             }
127         }
128     }
129     
130     public int checkClientBehaviorRenderedOnClientEventProperty(String output, int start, HtmlRenderedClientEventAttr attr)
131     {
132         String propStart = " "+attr.getName()+"=\"";
133         int propIndex = output.indexOf(propStart, start);
134         if (propIndex > -1)
135         {
136             int c = '"';
137             int startPropIndex = propIndex + propStart.length(); 
138             int endPropIndex = output.indexOf('"' , startPropIndex );
139             String propertyValue = output.substring(startPropIndex, endPropIndex);
140             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("jsf.ajax.request("));
141             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("javax.faces.behavior.event"));
142             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(attr.getClientEvent()));
143             return endPropIndex + 1;
144         }
145         else
146         {
147             Assert.fail("Property " + attr.getName() + "not found");
148             return -1;
149         }
150     }
151     
152     @Test
153     public void testClientBehaviorRenderedWithHtmlAttribute() 
154     {
155         HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
156         
157         for (int i = 0; i < attrs.length; i++)
158         {
159             UIComponent component = createComponentToTest();
160             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
161             clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
162             component.getAttributes().put(attrs[i].getName(), "htmlValue");
163             try 
164             {
165                 component.encodeAll(facesContext);
166                 String output = outputWriter.toString();
167                 //jsf.ajax.request('j_id0',event,{'javax.faces.behavior.event':'click'})
168                 //Only check if the property starts with jsf.ajax.request( is enough 
169                 //Assert.assertTrue("output does not match expected output jsf.ajax.request(.... for property "+attrs[i].getName(),
170                 //        output.matches(".+ "+attrs[i].getName()+"=\"jsf\\.ajax\\.request\\(.+"));
171                 int index = checkClientBehaviorRenderedOnClientEventPropertyAndHtmlValue(output, 0, attrs[i], "htmlValue");
172                 outputWriter.reset();
173             }
174             catch (Exception e)
175             {
176                 Assert.fail(e.getMessage());
177             }
178         }
179     }
180     
181     public int checkClientBehaviorRenderedOnClientEventPropertyAndHtmlValue(String output, int start, HtmlRenderedClientEventAttr attr, String value)
182     {
183         String propStart = " "+attr.getName()+"=\"";
184         int propIndex = output.indexOf(propStart, start);
185         if (propIndex > -1)
186         {
187             int c = '"';
188             int startPropIndex = propIndex + propStart.length(); 
189             int endPropIndex = output.indexOf('"' , startPropIndex );
190             String propertyValue = output.substring(startPropIndex, endPropIndex);
191             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.startsWith("jsf.util.chain("));
192             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("jsf.ajax.request("));
193             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("javax.faces.behavior.event"));
194             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(attr.getClientEvent()));
195             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(value));
196             return endPropIndex + 1;
197         }
198         else
199         {
200             Assert.fail("Property " + attr.getName() + "not found"+" Output: "+output);
201             return -1;
202         }
203     }
204 }