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 org.apache.myfaces.TestRunner;
22  import org.apache.shale.test.mock.MockFacesContext12;
23  import static org.easymock.EasyMock.*;
24  import org.easymock.IAnswer;
25  import org.easymock.classextension.EasyMock;
26  import org.easymock.classextension.IMocksControl;
27  import static org.testng.Assert.*;
28  import org.testng.annotations.AfterMethod;
29  import org.testng.annotations.BeforeMethod;
30  import org.testng.annotations.Test;
31  
32  import javax.el.ELContext;
33  import javax.el.MethodExpression;
34  import javax.faces.FactoryFinder;
35  import javax.faces.application.Application;
36  import javax.faces.application.ViewHandler;
37  import javax.faces.context.ExternalContext;
38  import javax.faces.event.*;
39  import javax.faces.lifecycle.Lifecycle;
40  import javax.faces.lifecycle.LifecycleFactory;
41  import javax.faces.webapp.FacesServlet;
42  import java.lang.reflect.Method;
43  import java.util.*;
44  
45  /**
46   * @author Mathias Broekelmann (latest modification by $Author: lu4242 $)
47   * @version $Revision: 1080407 $ $Date: 2011-03-10 19:30:02 -0500 (Thu, 10 Mar 2011) $
48   */
49  public class UIViewRootTest
50  {
51      private Map<PhaseId, Class<? extends PhaseListener>> phaseListenerClasses;
52      private IMocksControl _mocksControl;
53      private MockFacesContext12 _facesContext;
54      private UIViewRoot _testimpl;
55      private ExternalContext _externalContext;
56      private Application _application;
57      private Lifecycle _lifecycle;
58      private LifecycleFactory _lifecycleFactory;
59      private ViewHandler _viewHandler;
60      private ELContext _elContext;
61  
62      private static ThreadLocal<LifecycleFactory> LIFECYCLEFACTORY = new ThreadLocal<LifecycleFactory>();
63  
64      @BeforeMethod(alwaysRun=true)
65      protected void setUp() throws Exception
66      {
67          phaseListenerClasses = new HashMap<PhaseId, Class<? extends PhaseListener>>();
68          phaseListenerClasses.put(PhaseId.APPLY_REQUEST_VALUES, ApplyRequesValuesPhaseListener.class);
69          phaseListenerClasses.put(PhaseId.PROCESS_VALIDATIONS, ProcessValidationsPhaseListener.class);
70          phaseListenerClasses.put(PhaseId.UPDATE_MODEL_VALUES, UpdateModelValuesPhaseListener.class);
71          phaseListenerClasses.put(PhaseId.INVOKE_APPLICATION, InvokeApplicationPhaseListener.class);
72          phaseListenerClasses.put(PhaseId.RENDER_RESPONSE, RenderResponsePhaseListener.class);
73  
74          _mocksControl = EasyMock.createControl();
75          _externalContext = _mocksControl.createMock(ExternalContext.class);
76          _facesContext = new MockFacesContext12(_externalContext);
77          _application = _mocksControl.createMock(Application.class);
78          _lifecycleFactory = _mocksControl.createMock(LifecycleFactory.class);
79          _testimpl = new UIViewRoot();
80          _lifecycle = _mocksControl.createMock(Lifecycle.class);
81          _elContext = _mocksControl.createMock(ELContext.class);
82          _viewHandler = _mocksControl.createMock(ViewHandler.class);
83          _facesContext.setELContext(_elContext);
84  
85          LIFECYCLEFACTORY.set(_lifecycleFactory);
86          FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifeCycleFactory.class.getName());
87      }
88  
89      @AfterMethod(alwaysRun=true)
90      protected void tearDown() throws Exception
91      {
92          _mocksControl.reset();
93      }
94  
95      @Test
96      public void testSuperClass() throws Exception
97      {
98          assertEquals(UIComponentBase.class, UIViewRoot.class.getSuperclass());
99      }
100 
101     @Test
102     public void testComponentType() throws Exception
103     {
104         assertEquals("javax.faces.ViewRoot", UIViewRoot.COMPONENT_TYPE);
105     }
106 
107     @Test
108     public void testLocale() throws Exception
109     {
110         expect(_application.getViewHandler()).andReturn(_viewHandler).anyTimes();
111         expect(_viewHandler.calculateLocale(_facesContext)).andReturn(null).anyTimes();
112         _mocksControl.replay();
113 
114         _facesContext.setApplication(_application);
115         assertNull(_testimpl.getLocale());
116         _testimpl.setLocale(Locale.JAPANESE);
117         assertEquals(Locale.JAPANESE, _testimpl.getLocale());
118         _mocksControl.verify();
119     }
120 
121     /**
122      * Test method for {@link javax.faces.component.UIViewRoot#createUniqueId()}.
123      */
124     @Test
125     public void testCreateUniqueId()
126     {
127         /*
128         expect(_externalContext.encodeNamespace((String) anyObject())).andAnswer(new IAnswer<String>()
129         {
130             public String answer() throws Throwable
131             {
132                 return (String) getCurrentArguments()[0];
133             }
134         }).anyTimes();
135         */
136         _mocksControl.replay();
137         Collection createdIds = new HashSet();
138         for (int i = 0; i < 10000; i++)
139         {
140             if (!createdIds.add(_testimpl.createUniqueId()))
141             {
142                 fail("duplicate id created");
143             }
144         }
145         _mocksControl.verify();
146     }
147 
148     /**
149      * Test method for {@link javax.faces.component.UIViewRoot#processDecodes(javax.faces.context.FacesContext)}.
150      * 
151      * @throws Throwable
152      */
153     @Test
154     public void testProcessDecodes() throws Throwable
155     {
156         testProcessXXX(new TestRunner()
157         {
158             public void run() throws Throwable
159             {
160                 _testimpl.processDecodes(_facesContext);
161             }
162         }, PhaseId.APPLY_REQUEST_VALUES, false, true, true);
163     }
164 
165     /**
166      * Test method for {@link javax.faces.component.UIViewRoot#processValidators(javax.faces.context.FacesContext)}.
167      * 
168      * @throws Throwable
169      */
170     @Test
171     public void testProcessValidators() throws Throwable
172     {
173         testProcessXXX(new TestRunner()
174         {
175             public void run() throws Throwable
176             {
177                 _testimpl.processValidators(_facesContext);
178             }
179         }, PhaseId.PROCESS_VALIDATIONS, false, true, true);
180     }
181 
182     /**
183      * Test method for {@link javax.faces.component.UIViewRoot#processUpdates(javax.faces.context.FacesContext)}.
184      * 
185      * @throws Throwable
186      */
187     @Test
188     public void testProcessUpdates() throws Throwable
189     {
190         testProcessXXX(new TestRunner()
191         {
192             public void run() throws Throwable
193             {
194                 _testimpl.processUpdates(_facesContext);
195             }
196         }, PhaseId.UPDATE_MODEL_VALUES, false, true, true);
197     }
198 
199     /**
200      * Test method for {@link javax.faces.component.UIViewRoot#processApplication(javax.faces.context.FacesContext)}.
201      * 
202      * @throws Throwable
203      */
204     @Test
205     public void testProcessApplication() throws Throwable
206     {
207         testProcessXXX(new TestRunner()
208         {
209             public void run() throws Throwable
210             {
211                 _testimpl.processApplication(_facesContext);
212             }
213         }, PhaseId.INVOKE_APPLICATION, false, true, true);
214     }
215 
216     /**
217      * Test method for {@link javax.faces.component.UIViewRoot#encodeBegin(javax.faces.context.FacesContext)}.
218      * 
219      * @throws Throwable
220      */
221     @Test
222     public void testEncodeBegin() throws Throwable
223     {
224         testProcessXXX(new TestRunner()
225         {
226             public void run() throws Throwable
227             {
228                 _testimpl.encodeBegin(_facesContext);
229             }
230         }, PhaseId.RENDER_RESPONSE, false, true, false);
231     }
232 
233     /**
234      * Test method for {@link javax.faces.component.UIViewRoot#encodeEnd(javax.faces.context.FacesContext)}.
235      * 
236      * @throws Throwable
237      */
238     @Test
239     public void testEncodeEnd() throws Throwable
240     {
241         testProcessXXX(new TestRunner()
242         {
243             public void run() throws Throwable
244             {
245                 _testimpl.encodeEnd(_facesContext);
246             }
247         }, PhaseId.RENDER_RESPONSE, false, false, true);
248     }
249 
250     @Test
251     public void testEventQueue() throws Exception
252     {
253         FacesEvent event = _mocksControl.createMock(FacesEvent.class);
254         expect(event.getPhaseId()).andReturn(PhaseId.APPLY_REQUEST_VALUES).anyTimes();
255         UIComponent component = _mocksControl.createMock(UIComponent.class);
256         expect(event.getComponent()).andReturn(component).anyTimes();
257         component.broadcast(same(event));
258         _testimpl.queueEvent(event);
259 
260         event = _mocksControl.createMock(FacesEvent.class);
261         expect(event.getPhaseId()).andReturn(PhaseId.PROCESS_VALIDATIONS).anyTimes();
262         _testimpl.queueEvent(event);
263 
264         _mocksControl.replay();
265         _testimpl.processDecodes(_facesContext);
266         _mocksControl.verify();
267     }
268 
269     @Test
270     public void testEventQueueWithAbortExcpetion() throws Exception
271     {
272         FacesEvent event = _mocksControl.createMock(FacesEvent.class);
273         expect(event.getPhaseId()).andReturn(PhaseId.INVOKE_APPLICATION).anyTimes();
274         UIComponent component = _mocksControl.createMock(UIComponent.class);
275         expect(event.getComponent()).andReturn(component).anyTimes();
276         component.broadcast(same(event));
277         expectLastCall().andThrow(new AbortProcessingException());
278         _testimpl.queueEvent(event);
279 
280         event = _mocksControl.createMock(FacesEvent.class);
281         expect(event.getPhaseId()).andReturn(PhaseId.INVOKE_APPLICATION).anyTimes();
282         _testimpl.queueEvent(event);
283 
284         _mocksControl.replay();
285         _testimpl.processApplication(_facesContext);
286         _mocksControl.verify();
287     }
288 
289     //
290     //
291     //
292     // /**
293     // * Test method for {@link javax.faces.component.UIViewRoot#saveState(javax.faces.context.FacesContext)}.
294     // */
295     // public void testSaveState()
296     // {
297     // fail("Not yet implemented"); // TODO
298     // }
299     //
300     // /**
301     // * Test method for
302     // * {@link javax.faces.component.UIViewRoot#restoreState(javax.faces.context.FacesContext, java.lang.Object)}.
303     // */
304     // public void testRestoreState()
305     // {
306     // fail("Not yet implemented"); // TODO
307     // }
308     //
309     // /**
310     // * Test method for {@link javax.faces.component.UIViewRoot#UIViewRoot()}.
311     // */
312     // public void testUIViewRoot()
313     // {
314     // fail("Not yet implemented"); // TODO
315     // }
316     //
317     //
318     // /**
319     // * Test method for {@link javax.faces.component.UIViewRoot#setLocale(java.util.Locale)}.
320     // */
321     // public void testSetLocale()
322     // {
323     // fail("Not yet implemented"); // TODO
324     // }
325     //
326     // /**
327     // * Test method for {@link javax.faces.component.UIViewRoot#getRenderKitId()}.
328     // */
329     // public void testGetRenderKitId()
330     // {
331     // fail("Not yet implemented"); // TODO
332     // }
333     //
334     // /**
335     // * Test method for {@link javax.faces.component.UIViewRoot#setRenderKitId(java.lang.String)}.
336     // */
337     // public void testSetRenderKitId()
338     // {
339     // fail("Not yet implemented"); // TODO
340     // }
341     //
342     // /**
343     // * Test method for {@link javax.faces.component.UIViewRoot#getViewId()}.
344     // */
345     // public void testGetViewId()
346     // {
347     // fail("Not yet implemented"); // TODO
348     // }
349     //
350     // /**
351     // * Test method for {@link javax.faces.component.UIViewRoot#setViewId(java.lang.String)}.
352     // */
353     // public void testSetViewId()
354     // {
355     // fail("Not yet implemented"); // TODO
356     // }
357     //
358     // /**
359     // * Test method for {@link javax.faces.component.UIViewRoot#addPhaseListener(javax.faces.event.PhaseListener)}.
360     // */
361     // public void testAddPhaseListener()
362     // {
363     // fail("Not yet implemented"); // TODO
364     // }
365     //
366     // /**
367     // * Test method for {@link javax.faces.component.UIViewRoot#removePhaseListener(javax.faces.event.PhaseListener)}.
368     // */
369     // public void testRemovePhaseListener()
370     // {
371     // fail("Not yet implemented"); // TODO
372     // }
373     //
374     // /**
375     // * Test method for {@link javax.faces.component.UIViewRoot#getBeforePhaseListener()}.
376     // */
377     // public void testGetBeforePhaseListener()
378     // {
379     // fail("Not yet implemented"); // TODO
380     // }
381     //
382     // /**
383     // * Test method for {@link javax.faces.component.UIViewRoot#setBeforePhaseListener(javax.el.MethodExpression)}.
384     // */
385     // public void testSetBeforePhaseListener()
386     // {
387     // fail("Not yet implemented"); // TODO
388     // }
389     //
390     // /**
391     // * Test method for {@link javax.faces.component.UIViewRoot#getAfterPhaseListener()}.
392     // */
393     // public void testGetAfterPhaseListener()
394     // {
395     // fail("Not yet implemented"); // TODO
396     // }
397     //
398     // /**
399     // * Test method for {@link javax.faces.component.UIViewRoot#setAfterPhaseListener(javax.el.MethodExpression)}.
400     // */
401     // public void testSetAfterPhaseListener()
402     // {
403     // fail("Not yet implemented"); // TODO
404     // }
405     //
406     // /**
407     // * Test method for {@link javax.faces.component.UIViewRoot#getFamily()}.
408     // */
409     // public void testGetFamily()
410     // {
411     // fail("Not yet implemented"); // TODO
412     // }
413     //
414 
415     private void testProcessXXX(TestRunner runner, PhaseId phaseId, boolean expectSuperCall, boolean checkBefore,
416             boolean checkAfter) throws Throwable
417     {
418         expect(_lifecycleFactory.getLifecycle(eq(LifecycleFactory.DEFAULT_LIFECYCLE))).andReturn(_lifecycle);
419         expect(_externalContext.getInitParameter(eq(FacesServlet.LIFECYCLE_ID_ATTR))).andReturn(null).anyTimes();
420 
421         PhaseEvent event = new PhaseEvent(_facesContext, phaseId, _lifecycle);
422 
423         if (expectSuperCall)
424             _testimpl = _mocksControl.createMock(UIViewRoot.class, new Method[] { UIViewRoot.class.getMethod(
425                     "isRendered", new Class[0]) });
426 
427         MethodExpression beforeListener = _mocksControl.createMock(MethodExpression.class);
428         _testimpl.setBeforePhaseListener(beforeListener);
429 
430         MethodExpression afterListener = _mocksControl.createMock(MethodExpression.class);
431         _testimpl.setAfterPhaseListener(afterListener);
432 
433         Method[] mockedMethods = new Method[] {
434                 PhaseListener.class.getMethod("beforePhase", new Class[] { PhaseEvent.class }),
435                 PhaseListener.class.getMethod("afterPhase", new Class[] { PhaseEvent.class }) };
436         PhaseListener phaseListener = _mocksControl.createMock(phaseListenerClasses.get(phaseId), mockedMethods);
437         _testimpl.addPhaseListener(phaseListener);
438 
439         PhaseListener anyPhaseListener = _mocksControl.createMock(AnyPhasePhaseListener.class, mockedMethods);
440         _testimpl.addPhaseListener(anyPhaseListener);
441 
442         PhaseListener restoreViewPhaseListener = _mocksControl.createMock(RestoreViewPhasePhaseListener.class,
443                 mockedMethods);
444         _testimpl.addPhaseListener(restoreViewPhaseListener);
445 
446         _mocksControl.checkOrder(true);
447 
448         if (checkBefore)
449         {
450             expect(beforeListener.invoke(eq(_facesContext.getELContext()), aryEq(new Object[] { event }))).andReturn(
451                     null);
452             phaseListener.beforePhase(eq(event));
453             anyPhaseListener.beforePhase(eq(event));
454         }
455 
456         if (expectSuperCall)
457             expect(_testimpl.isRendered()).andReturn(false);
458 
459         if (checkAfter)
460         {
461             expect(afterListener.invoke(eq(_facesContext.getELContext()), aryEq(new Object[] { event }))).andReturn(
462                     null);
463             phaseListener.afterPhase(eq(event));
464             anyPhaseListener.afterPhase(eq(event));
465         }
466 
467         _mocksControl.replay();
468         runner.run();
469         _mocksControl.verify();
470     }
471 
472     public static class MockLifeCycleFactory extends LifecycleFactory
473     {
474 
475         @Override
476         public void addLifecycle(String lifecycleId, Lifecycle lifecycle)
477         {
478             LIFECYCLEFACTORY.get().addLifecycle(lifecycleId, lifecycle);
479         }
480 
481         @Override
482         public Lifecycle getLifecycle(String lifecycleId)
483         {
484             return LIFECYCLEFACTORY.get().getLifecycle(lifecycleId);
485         }
486 
487         @Override
488         public Iterator<String> getLifecycleIds()
489         {
490             return LIFECYCLEFACTORY.get().getLifecycleIds();
491         }
492 
493     }
494 
495     public static abstract class ApplyRequesValuesPhaseListener implements PhaseListener
496     {
497         public PhaseId getPhaseId()
498         {
499             return PhaseId.APPLY_REQUEST_VALUES;
500         }
501     }
502 
503     public static abstract class ProcessValidationsPhaseListener implements PhaseListener
504     {
505         public PhaseId getPhaseId()
506         {
507             return PhaseId.PROCESS_VALIDATIONS;
508         }
509     }
510 
511     public static abstract class UpdateModelValuesPhaseListener implements PhaseListener
512     {
513         public PhaseId getPhaseId()
514         {
515             return PhaseId.UPDATE_MODEL_VALUES;
516         }
517     }
518 
519     public static abstract class InvokeApplicationPhaseListener implements PhaseListener
520     {
521         public PhaseId getPhaseId()
522         {
523             return PhaseId.INVOKE_APPLICATION;
524         }
525     }
526 
527     public static abstract class AnyPhasePhaseListener implements PhaseListener
528     {
529         public PhaseId getPhaseId()
530         {
531             return PhaseId.ANY_PHASE;
532         }
533     }
534 
535     public static abstract class RestoreViewPhasePhaseListener implements PhaseListener
536     {
537         public PhaseId getPhaseId()
538         {
539             return PhaseId.RESTORE_VIEW;
540         }
541     }
542 
543     public static abstract class RenderResponsePhaseListener implements PhaseListener
544     {
545         public PhaseId getPhaseId()
546         {
547             return PhaseId.RENDER_RESPONSE;
548         }
549     }
550 
551 }