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.component.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_tomahawk.config.MyfacesConfig;
27  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlResponseWriterImpl;
28  import org.apache.myfaces.shared_tomahawk.util.FastWriter;
29  import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
30  import org.apache.myfaces.test.config.ConfigParser;
31  import org.junit.Assert;
32  import org.junit.Test;
33  
34  public abstract class AbstractClientBehaviorTestCase extends AbstractJsfTestCase
35  {
36      protected ResponseWriter writer;
37      protected FastWriter outputWriter; 
38      protected ConfigParser parser;
39      
40      //protected abstract UIComponent getComponentToTest();
41      
42      protected abstract HtmlRenderedClientEventAttr[] getClientBehaviorHtmlRenderedAttributes();
43      
44      protected abstract UIComponent createComponentToTest();
45  
46      protected void dettachFromView()
47      {
48      }
49      
50      @Override
51      protected void setUpServletObjects() throws Exception
52      {
53          super.setUpServletObjects();
54          
55          servletContext.setAttribute("org.apache.myfaces.shared_tomahawk.config.MyfacesConfig", new MyfacesConfig());
56      }
57  
58      @Override
59      protected void setUpJSFObjects() throws Exception
60      {
61          super.setUpJSFObjects();
62          outputWriter = new FastWriter();
63          writer = new HtmlResponseWriterImpl(outputWriter, null, null);
64          facesContext.setResponseWriter(writer);
65          facesContext.getAttributes().put("org.apache.myfaces.RENDERED_JSF_JS", true);
66      }
67      
68      @Override
69      protected void setUpApplication() throws Exception
70      {
71          super.setUpApplication();
72      }
73  
74      @Override
75      protected void setUpRenderKit() throws Exception
76      {
77          super.setUpRenderKit();
78          parser = new ConfigParser();
79          parser.parse(parser.getPlatformURLs());
80          parser.parse(this.getClass().getResource("/META-INF/faces-config.xml"));        
81      }
82  
83      /**
84       * Components that render client behaviors should always render "id" and "name" attribute
85       */
86      @Test
87      public void testClientBehaviorHolderRendersId() 
88      {
89          HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
90          
91          for (int i = 0; i < attrs.length; i++)
92          {
93              UIComponent component = createComponentToTest();
94              ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
95              clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
96              try 
97              {
98                  component.encodeAll(facesContext);
99                  String output = outputWriter.toString();
100                 Assert.assertTrue(output.indexOf(" id=\""+component.getClientId(facesContext)+"\"") > -1);
101                 outputWriter.reset();
102             }
103             catch (Exception e)
104             {
105                 Assert.fail(e.getMessage());
106             }
107             dettachFromView();
108         }
109     }    
110     
111     /**
112      * Components that render client behaviors should always render "id" and "name" attribute
113      */
114     @Test
115     public void testClientBehaviorHolderRendersName() 
116     {
117         HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
118         
119         for (int i = 0; i < attrs.length; i++)
120         {
121             UIComponent component = createComponentToTest();
122             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
123             clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
124             try 
125             {
126                 component.encodeAll(facesContext);
127                 String output = outputWriter.toString();
128                 Assert.assertTrue(output.indexOf(" name=\""+component.getClientId(facesContext)+"\"") > -1);
129                 outputWriter.reset();
130             }
131             catch (Exception e)
132             {
133                 Assert.fail(e.getMessage());
134             }
135             dettachFromView();
136         }
137     }
138     
139     @Test
140     public void testClientBehaviorRendered() 
141     {
142         HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
143         
144         for (int i = 0; i < attrs.length; i++)
145         {
146             UIComponent component = createComponentToTest();
147             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
148             clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
149             try 
150             {
151                 component.encodeAll(facesContext);
152                 String output = outputWriter.toString();
153                 //jsf.ajax.request('j_id0',event,{'javax.faces.behavior.event':'click'})
154                 //Only check if the property starts with jsf.ajax.request( is enough 
155                 //Assert.assertTrue("output does not match expected output jsf.ajax.request(.... for property "+attrs[i].getName(),
156                 //        output.matches(".+ "+attrs[i].getName()+"=\"jsf\\.ajax\\.request\\(.+"));
157                 int index = checkClientBehaviorRenderedOnClientEventProperty(output, 0, attrs[i]);
158                 outputWriter.reset();
159             }
160             catch (Exception e)
161             {
162                 Assert.fail(e.getMessage());
163             }
164             dettachFromView();
165         }
166     }
167     
168     public int checkClientBehaviorRenderedOnClientEventProperty(String output, int start, HtmlRenderedClientEventAttr attr)
169     {
170         String propStart = " "+attr.getName()+"=\"";
171         int propIndex = output.indexOf(propStart, start);
172         if (propIndex > -1)
173         {
174             int c = '"';
175             int startPropIndex = propIndex + propStart.length(); 
176             int endPropIndex = output.indexOf('"' , startPropIndex );
177             String propertyValue = output.substring(startPropIndex, endPropIndex);
178             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("jsf.ajax.request("));
179             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("javax.faces.behavior.event"));
180             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(attr.getClientEvent()));
181             return endPropIndex + 1;
182         }
183         else
184         {
185             Assert.fail("Property " + attr.getName() + "not found");
186             return -1;
187         }
188     }
189     
190     @Test
191     public void testClientBehaviorRenderedWithHtmlAttribute() 
192     {
193         HtmlRenderedClientEventAttr[] attrs = getClientBehaviorHtmlRenderedAttributes();
194         
195         for (int i = 0; i < attrs.length; i++)
196         {
197             UIComponent component = createComponentToTest();
198             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
199             clientBehaviorHolder.addClientBehavior(attrs[i].getClientEvent(), new AjaxBehavior());
200             component.getAttributes().put(attrs[i].getName(), "htmlValue");
201             try 
202             {
203                 component.encodeAll(facesContext);
204                 String output = outputWriter.toString();
205                 //jsf.ajax.request('j_id0',event,{'javax.faces.behavior.event':'click'})
206                 //Only check if the property starts with jsf.ajax.request( is enough 
207                 //Assert.assertTrue("output does not match expected output jsf.ajax.request(.... for property "+attrs[i].getName(),
208                 //        output.matches(".+ "+attrs[i].getName()+"=\"jsf\\.ajax\\.request\\(.+"));
209                 int index = checkClientBehaviorRenderedOnClientEventPropertyAndHtmlValue(output, 0, attrs[i], "htmlValue");
210                 outputWriter.reset();
211             }
212             catch (Exception e)
213             {
214                 Assert.fail(e.getMessage());
215             }
216             dettachFromView();
217         }
218     }
219     
220     public int checkClientBehaviorRenderedOnClientEventPropertyAndHtmlValue(String output, int start, HtmlRenderedClientEventAttr attr, String value)
221     {
222         String propStart = " "+attr.getName()+"=\"";
223         int propIndex = output.indexOf(propStart, start);
224         if (propIndex > -1)
225         {
226             int c = '"';
227             int startPropIndex = propIndex + propStart.length(); 
228             int endPropIndex = output.indexOf('"' , startPropIndex );
229             String propertyValue = output.substring(startPropIndex, endPropIndex);
230             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.startsWith("jsf.util.chain("));
231             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("jsf.ajax.request("));
232             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains("javax.faces.behavior.event"));
233             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(attr.getClientEvent()));
234             Assert.assertTrue("Property: " + attr.getName()+" Output: "+output, propertyValue.contains(value));
235             return endPropIndex + 1;
236         }
237         else
238         {
239             Assert.fail("Property " + attr.getName() + "not found"+" Output: "+output);
240             return -1;
241         }
242     }
243 }