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 javax.faces.component;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  
26  import javax.faces.component.html.HtmlPanelGroup;
27  import javax.faces.component.visit.VisitCallback;
28  import javax.faces.component.visit.VisitContext;
29  import javax.faces.component.visit.VisitHint;
30  import javax.faces.component.visit.VisitResult;
31  import javax.faces.context.FacesContext;
32  import javax.faces.event.AbortProcessingException;
33  import javax.faces.event.FacesEvent;
34  import javax.faces.event.PhaseId;
35  import javax.faces.render.Renderer;
36  
37  import org.apache.myfaces.Assert;
38  import org.apache.myfaces.TestRunner;
39  import org.apache.myfaces.mock.MockRenderedValueExpression;
40  import org.apache.myfaces.test.base.AbstractJsfTestCase;
41  import org.easymock.classextension.EasyMock;
42  import org.easymock.classextension.IMocksControl;
43  
44  /**
45   * @author Mathias Broekelmann (latest modification by $Author: lu4242 $)
46   * @version $Revision: 1150983 $ $Date: 2011-07-25 23:07:49 -0500 (Mon, 25 Jul 2011) $
47   */
48  public class UIDataTest extends AbstractJsfTestCase
49  {
50      public UIDataTest(String name)
51      {
52          super(name);
53      }
54  
55      private IMocksControl _mocksControl;
56      private UIData _testImpl;
57  
58      @Override
59      protected void setUp() throws Exception
60      {
61          super.setUp();
62          _mocksControl = EasyMock.createControl();
63          _testImpl = new UIData();
64      }
65  
66      /**
67       * Test method for
68       * {@link javax.faces.component.UIData#setValueExpression(java.lang.String, javax.el.ValueExpression)}.
69       */
70      public void testValueExpression()
71      {
72          assertSetValueExpressionException(IllegalArgumentException.class, "rowIndex");
73          assertSetValueExpressionException(NullPointerException.class, null);
74      }
75  
76      private void assertSetValueExpressionException(Class<? extends Throwable> expected, final String name)
77      {
78          Assert.assertException(expected, new TestRunner()
79          {
80              public void run() throws Throwable
81              {
82                  _testImpl.setValueExpression(name, null);
83              }
84          });
85      }
86  
87      /**
88       * Test method for {@link javax.faces.component.UIData#getClientId(javax.faces.context.FacesContext)}.
89       */
90      public void testGetClientId()
91      {
92          _testImpl.setId("xxx");
93          Renderer renderer = _mocksControl.createMock(Renderer.class);
94          renderKit.addRenderer(UIData.COMPONENT_FAMILY, UIData.COMPONENT_TYPE, renderer);
95          assertEquals("xxx", _testImpl.getClientId(facesContext));
96          _testImpl.setRowIndex(99);
97          //MYFACES-2744 UIData.getClientId() should not append rowIndex, instead use UIData.getContainerClientId()
98          assertEquals("xxx", _testImpl.getClientId(facesContext)); 
99          assertEquals("xxx:99", _testImpl.getContainerClientId(facesContext));
100     }
101 
102     /**
103      * Test method for
104      * {@link javax.faces.component.UIData#invokeOnComponent(javax.faces.context.FacesContext, java.lang.String, javax.faces.component.ContextCallback)}
105      * .
106      * Tests, if invokeOnComponent also checks the facets of the h:column children (MYFACES-2370)
107      */
108     public void testInvokeOnComponentFacesContextStringContextCallback()
109     {
110         /**
111          * Concrete class of ContextCallback needed to test invokeOnComponent. 
112          * @author Jakob Korherr
113          */
114         final class MyContextCallback implements ContextCallback
115         {
116             
117             private boolean invoked = false;
118 
119             public void invokeContextCallback(FacesContext context,
120                     UIComponent target)
121             {
122                 this.invoked = true;
123             }
124             
125         }
126         
127         UIComponent facet = new UIOutput();
128         facet.setId("facet");
129         UIColumn column = new UIColumn();
130         column.setId("column");
131         column.getFacets().put("header", facet);
132         _testImpl.setId("uidata");
133         _testImpl.getChildren().add(column);
134         
135         MyContextCallback callback = new MyContextCallback();
136         _testImpl.invokeOnComponent(facesContext, facet.getClientId(facesContext), callback);
137         // the callback should have been invoked
138         assertTrue(callback.invoked);
139     }
140 
141     /**
142      * Test method for {@link javax.faces.component.UIData#broadcast(javax.faces.event.FacesEvent)}.
143      */
144     public void testBroadcastFacesEvent()
145     {
146         // create event mock
147         final FacesEvent originalEvent = _mocksControl.createMock(FacesEvent.class);
148         
149         // create the component for the event
150         UIComponent eventComponent = new UICommand()
151         {
152 
153             @Override
154             public void broadcast(FacesEvent event)
155                     throws AbortProcessingException
156             {
157                 // the event must be the originalEvent
158                 assertEquals(originalEvent, event);
159                 
160                 // the current row index must be the row index from the time the event was queued
161                 assertEquals(5, _testImpl.getRowIndex());
162                 
163                 // the current component must be this (pushComponentToEL() must have happened)
164                 assertEquals(this, UIComponent.getCurrentComponent(facesContext));
165                 
166                 // to be able to verify that broadcast() really has been called
167                 getAttributes().put("broadcastCalled", Boolean.TRUE);
168             }
169             
170         };
171         
172         // set component on event
173         EasyMock.expect(originalEvent.getComponent()).andReturn(eventComponent).anyTimes();
174         // set phase on event
175         EasyMock.expect(originalEvent.getPhaseId()).andReturn(PhaseId.INVOKE_APPLICATION).anyTimes();
176         _mocksControl.replay();
177         
178         // set PhaseId for event processing
179         facesContext.setCurrentPhaseId(PhaseId.INVOKE_APPLICATION);
180         // set row index for event
181         _testImpl.setRowIndex(5);
182         // UIData must be a child of UIViewRoot to queue and event
183         facesContext.getViewRoot().getChildren().add(_testImpl);
184         // queue event (this will create a FacesEventWrapper with the current row index)
185         _testImpl.queueEvent(originalEvent);
186         // change the current row index
187         _testImpl.setRowIndex(0);
188         // now broadcast the event (this will call UIData.broadcast())
189         facesContext.getViewRoot().broadcastEvents(facesContext, PhaseId.INVOKE_APPLICATION);
190         
191         // -= Assertions =-
192         
193         // the current component must be null (popComponentFromEL() must have happened)
194         assertNull(UIComponent.getCurrentComponent(facesContext));
195         
196         // the row index must now be 0 (at broadcast() it must be 5)
197         assertEquals(0, _testImpl.getRowIndex());
198         
199         // verify mock behavior
200         _mocksControl.verify();
201         
202         // verify that broadcast() really has been called
203         assertEquals(Boolean.TRUE, eventComponent.getAttributes().get("broadcastCalled"));
204     }
205 
206     /**
207      * Test method for {@link javax.faces.component.UIData#encodeBegin(javax.faces.context.FacesContext)}.
208      */
209     public void testEncodeBeginFacesContext()
210     {
211         // TODO
212     }
213 
214     /**
215      * Test method for {@link javax.faces.component.UIData#encodeEnd(javax.faces.context.FacesContext)}.
216      */
217     public void testEncodeEndFacesContext()
218     {
219         // TODO
220     }
221 
222     /**
223      * Test method for {@link javax.faces.component.UIData#queueEvent(javax.faces.event.FacesEvent)}.
224      */
225     public void testQueueEventFacesEvent()
226     {
227         // TODO
228     }
229 
230     /**
231      * Test method for {@link javax.faces.component.UIData#processDecodes(javax.faces.context.FacesContext)}.
232      */
233     public void testProcessDecodesFacesContext()
234     {
235         // TODO
236     }
237 
238     /**
239      * Test method for {@link javax.faces.component.UIData#processValidators(javax.faces.context.FacesContext)}.
240      */
241     public void testProcessValidatorsFacesContext()
242     {
243         // TODO
244     }
245 
246     /**
247      * Test method for {@link javax.faces.component.UIData#processUpdates(javax.faces.context.FacesContext)}.
248      */
249     public void testProcessUpdatesFacesContext()
250     {
251         // TODO
252     }
253 
254     /**
255      * Test method for {@link javax.faces.component.UIData#saveState(javax.faces.context.FacesContext)}.
256      */
257     public void testSaveState()
258     {
259         // TODO
260     }
261 
262     /**
263      * Test method for
264      * {@link javax.faces.component.UIData#restoreState(javax.faces.context.FacesContext, java.lang.Object)}.
265      */
266     public void testRestoreState()
267     {
268         // TODO
269     }
270 
271     /**
272      * Test method for {@link javax.faces.component.UIData#UIData()}.
273      */
274     public void testUIData()
275     {
276         // TODO
277     }
278 
279     /**
280      * Test method for {@link javax.faces.component.UIData#setFooter(javax.faces.component.UIComponent)}.
281      */
282     public void testSetFooter()
283     {
284         // TODO
285     }
286 
287     /**
288      * Test method for {@link javax.faces.component.UIData#getFooter()}.
289      */
290     public void testGetFooter()
291     {
292         // TODO
293     }
294 
295     /**
296      * Test method for {@link javax.faces.component.UIData#setHeader(javax.faces.component.UIComponent)}.
297      */
298     public void testSetHeader()
299     {
300         // TODO
301     }
302 
303     /**
304      * Test method for {@link javax.faces.component.UIData#getHeader()}.
305      */
306     public void testGetHeader()
307     {
308         // TODO
309     }
310 
311     /**
312      * Test method for {@link javax.faces.component.UIData#isRowAvailable()}.
313      */
314     public void testIsRowAvailable()
315     {
316         // TODO
317     }
318 
319     /**
320      * Test method for {@link javax.faces.component.UIData#getRowCount()}.
321      */
322     public void testGetRowCount()
323     {
324         // TODO
325     }
326 
327     /**
328      * Test method for {@link javax.faces.component.UIData#getRowData()}.
329      */
330     public void testGetRowData()
331     {
332         // TODO
333     }
334 
335     /**
336      * Test method for {@link javax.faces.component.UIData#getRowIndex()}.
337      */
338     public void testGetRowIndex()
339     {
340         // TODO
341     }
342 
343     /**
344      * Test method for {@link javax.faces.component.UIData#setRowIndex(int)}.
345      */
346     public void testSetRowIndex()
347     {
348         // TODO
349     }
350 
351     /**
352      * Test method for {@link javax.faces.component.UIData#getDataModel()}.
353      */
354     public void testGetDataModel()
355     {
356         // TODO
357     }
358 
359     /**
360      * Test method for {@link javax.faces.component.UIData#setDataModel(javax.faces.model.DataModel)}.
361      */
362     public void testSetDataModel()
363     {
364         // TODO
365     }
366 
367     /**
368      * Test method for {@link javax.faces.component.UIData#setValue(java.lang.Object)}.
369      */
370     public void testSetValue()
371     {
372         // TODO
373     }
374 
375     /**
376      * Test method for {@link javax.faces.component.UIData#setRows(int)}.
377      */
378     public void testSetRows()
379     {
380         // TODO
381     }
382 
383     /**
384      * Test method for {@link javax.faces.component.UIData#setFirst(int)}.
385      */
386     public void testSetFirst()
387     {
388         // TODO
389     }
390 
391     /**
392      * Test method for {@link javax.faces.component.UIData#getValue()}.
393      */
394     public void testGetValue()
395     {
396         // TODO
397     }
398 
399     /**
400      * Test method for {@link javax.faces.component.UIData#getVar()}.
401      */
402     public void testGetVar()
403     {
404         // TODO
405     }
406 
407     /**
408      * Test method for {@link javax.faces.component.UIData#setVar(java.lang.String)}.
409      */
410     public void testSetVar()
411     {
412         // TODO
413     }
414 
415     /**
416      * Test method for {@link javax.faces.component.UIData#getRows()}.
417      */
418     public void testGetRows()
419     {
420         // TODO
421     }
422 
423     /**
424      * Test method for {@link javax.faces.component.UIData#getFirst()}.
425      */
426     public void testGetFirst()
427     {
428         // TODO
429     }
430 
431     /**
432      * Test method for {@link javax.faces.component.UIData#getFamily()}.
433      */
434     public void testGetFamily()
435     {
436         // TODO
437     }
438     
439     /**
440      * Test method for 
441      * {@link javax.faces.component.UIData#visitTree(javax.faces.component.visit.VisitContext, javax.faces.component.visit.VisitCallback)}.
442      */
443     public void testVisitTree() {
444         UIData uidata = new UIData();
445         // value
446         Collection<String> value = new ArrayList<String>();
447         value.add("value#1");
448         value.add("value#2");
449         uidata.setValue(value);
450         // header facet
451         UIComponent headerFacet = new HtmlPanelGroup();
452         uidata.setHeader(headerFacet);
453         // footer facet
454         UIComponent footerFacet = new HtmlPanelGroup();
455         uidata.setFooter(footerFacet);
456         // first child
457         UIComponent child1 = new UIColumn();
458         // facet of first child
459         UIComponent facetOfChild1 = new HtmlPanelGroup();
460         child1.getFacets().put("someFacet", facetOfChild1);
461         // child of first child
462         UIOutput childOfChild1 = new UIOutput();
463         child1.getChildren().add(childOfChild1);
464         uidata.getChildren().add(child1);
465         // second child (should not be processed --> != UIColumn)
466         UIComponent child2 = new HtmlPanelGroup(); 
467         uidata.getChildren().add(child2);
468         VisitCallback callback = null;
469         
470         IMocksControl control = EasyMock.createControl();
471         VisitContext visitContextMock = control.createMock(VisitContext.class);
472         EasyMock.expect(visitContextMock.getFacesContext()).andReturn(facesContext).anyTimes();
473         EasyMock.expect(visitContextMock.getHints()).andReturn(Collections.<VisitHint>emptySet()).anyTimes();
474         Collection<String> subtreeIdsToVisit = new ArrayList<String>();
475         subtreeIdsToVisit.add("1");
476         EasyMock.expect(visitContextMock.getSubtreeIdsToVisit(uidata)).andReturn(subtreeIdsToVisit);
477         EasyMock.expect(visitContextMock.invokeVisitCallback(uidata, callback)).andReturn(VisitResult.ACCEPT);
478         EasyMock.expect(visitContextMock.invokeVisitCallback(headerFacet, callback)).andReturn(VisitResult.ACCEPT);
479         EasyMock.expect(visitContextMock.invokeVisitCallback(footerFacet, callback)).andReturn(VisitResult.ACCEPT);
480         EasyMock.expect(visitContextMock.invokeVisitCallback(facetOfChild1, callback)).andReturn(VisitResult.ACCEPT);
481         EasyMock.expect(visitContextMock.invokeVisitCallback(child1, callback)).andReturn(VisitResult.ACCEPT);
482         EasyMock.expect(visitContextMock.invokeVisitCallback(childOfChild1, callback)).andReturn(VisitResult.ACCEPT).times(2);
483         control.replay();
484         
485         uidata.visitTree(visitContextMock, callback);
486         
487         control.verify();        
488     }
489     
490     public void testProcessDecodesRenderedFalse() throws Exception {
491         UIData uiData = new VerifyNoLifecycleMethodComponent();
492         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
493         
494         uiData.processDecodes(facesContext);
495         
496         assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
497         
498     }
499     
500     public void testProcessDecodesRenderedTrue() throws Exception {
501         
502         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
503         _addColumn();
504         
505         _testImpl.processDecodes(facesContext);
506         
507         assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
508     }
509     
510     
511     public void testProcessValidatorsRenderedFalse() throws Exception {
512         UIData uiData = new VerifyNoLifecycleMethodComponent();
513         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
514         
515         uiData.processValidators(facesContext);
516         
517         assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
518         
519     }
520     
521     public void testProcessValidatorsRenderedTrue() throws Exception {
522         
523         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
524         _addColumn();
525         
526         _testImpl.processValidators(facesContext);
527         
528         assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
529     }
530     
531     public void testProcessUpdatesRenderedFalse() throws Exception {
532         UIData uiData = new VerifyNoLifecycleMethodComponent();
533         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
534         
535         uiData.processUpdates(facesContext);
536         
537         assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
538         
539     }
540     
541     public void testProcessUpdatesRenderedTrue() throws Exception {
542         
543         UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
544         _addColumn();
545         
546         _testImpl.processUpdates(facesContext);
547         
548         assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
549     }
550 
551     private void _addColumn() {
552         UIColumn uiColumn = new UIColumn();
553         uiColumn.setId("testId");
554         _testImpl.getChildren().add(uiColumn);
555         MockRenderedValueExpression ve = new MockRenderedValueExpression("#{component.is eq 'testId'}", Boolean.class, uiColumn, true);
556         uiColumn.setValueExpression("rendered", ve);
557     }
558     
559 
560     /** Verifies no call to encode* and process* methods */
561     public class VerifyNoLifecycleMethodComponent extends UIData
562     {
563         public void setRowIndex(int rowIndex) {
564             fail();
565         }
566         public void decode(FacesContext context) {
567             fail();
568         }
569         public void validate(FacesContext context) {
570             fail();
571         }
572         public void updateModel(FacesContext context) {
573             fail();
574         }
575         public void encodeBegin(FacesContext context) throws IOException {
576             fail();
577         }
578         public void encodeChildren(FacesContext context) throws IOException {
579             fail();
580         }
581         public void encodeEnd(FacesContext context) throws IOException {
582             fail();
583         }
584     }   
585 }