1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import static org.easymock.EasyMock.anyObject;
22 import static org.easymock.EasyMock.aryEq;
23 import static org.easymock.EasyMock.eq;
24 import static org.easymock.EasyMock.expect;
25 import static org.easymock.EasyMock.getCurrentArguments;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.fail;
29
30 import java.lang.reflect.Method;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.Locale;
36 import java.util.Map;
37
38 import javax.el.ELContext;
39 import javax.el.MethodExpression;
40 import javax.faces.FactoryFinder;
41 import javax.faces.application.Application;
42 import javax.faces.application.ProjectStage;
43 import javax.faces.application.ViewHandler;
44 import javax.faces.context.ExternalContext;
45 import javax.faces.event.AbortProcessingException;
46 import javax.faces.event.ActionEvent;
47 import javax.faces.event.ActionListener;
48 import javax.faces.event.PhaseEvent;
49 import javax.faces.event.PhaseId;
50 import javax.faces.event.PhaseListener;
51 import javax.faces.lifecycle.Lifecycle;
52 import javax.faces.lifecycle.LifecycleFactory;
53 import javax.faces.webapp.FacesServlet;
54
55 import org.apache.myfaces.TestRunner;
56 import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
57 import org.apache.myfaces.test.mock.MockFacesContext12;
58 import org.easymock.IAnswer;
59 import org.easymock.classextension.EasyMock;
60 import org.easymock.classextension.IMocksControl;
61 import org.junit.After;
62 import org.junit.Before;
63 import org.junit.Test;
64
65 public class UIViewRootTest extends AbstractJsfTestCase
66 {
67 private Map<PhaseId, Class<? extends PhaseListener>> phaseListenerClasses;
68 private IMocksControl _mocksControl;
69 private MockFacesContext12 _facesContext;
70 private UIViewRoot _testimpl;
71 private ExternalContext _externalContext;
72 private Application _application;
73 private Lifecycle _lifecycle;
74 private LifecycleFactory _lifecycleFactory;
75 private ViewHandler _viewHandler;
76 private ELContext _elContext;
77
78 private static ThreadLocal<LifecycleFactory> LIFECYCLEFACTORY = new ThreadLocal<LifecycleFactory>();
79
80 @Before
81 public void setUp() throws Exception
82 {
83 super.setUp();
84 phaseListenerClasses = new HashMap<PhaseId, Class<? extends PhaseListener>>();
85 phaseListenerClasses.put(PhaseId.APPLY_REQUEST_VALUES, ApplyRequesValuesPhaseListener.class);
86 phaseListenerClasses.put(PhaseId.PROCESS_VALIDATIONS, ProcessValidationsPhaseListener.class);
87 phaseListenerClasses.put(PhaseId.UPDATE_MODEL_VALUES, UpdateModelValuesPhaseListener.class);
88 phaseListenerClasses.put(PhaseId.INVOKE_APPLICATION, InvokeApplicationPhaseListener.class);
89 phaseListenerClasses.put(PhaseId.RENDER_RESPONSE, RenderResponsePhaseListener.class);
90
91 _mocksControl = EasyMock.createControl();
92 _externalContext = _mocksControl.createMock(ExternalContext.class);
93 _facesContext = (MockFacesContext12) facesContext;
94 _application = _mocksControl.createMock(Application.class);
95 _lifecycleFactory = _mocksControl.createMock(LifecycleFactory.class);
96 _testimpl = new UIViewRoot();
97 _lifecycle = _mocksControl.createMock(Lifecycle.class);
98 _elContext = _mocksControl.createMock(ELContext.class);
99 _viewHandler = _mocksControl.createMock(ViewHandler.class);
100 _facesContext.setELContext(_elContext);
101
102 LIFECYCLEFACTORY.set(_lifecycleFactory);
103 FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifeCycleFactory.class.getName());
104 servletContext.addInitParameter(ProjectStage.PROJECT_STAGE_PARAM_NAME, ProjectStage.UnitTest.name());
105
106 }
107
108 @After
109 public void tearDown() throws Exception
110 {
111 super.tearDown();
112 _mocksControl.reset();
113 }
114
115 @Test
116 public void testSuperClass() throws Exception
117 {
118 assertEquals(UIComponentBase.class, UIViewRoot.class.getSuperclass());
119 }
120
121 @Test
122 public void testComponentType() throws Exception
123 {
124 assertEquals("javax.faces.ViewRoot", UIViewRoot.COMPONENT_TYPE);
125 }
126
127 @Test
128 public void testLocale() throws Exception
129 {
130 expect(_application.getViewHandler()).andReturn(_viewHandler).anyTimes();
131 expect(_viewHandler.calculateLocale(_facesContext)).andReturn(null).anyTimes();
132 _mocksControl.replay();
133
134 _facesContext.setApplication(_application);
135 assertNull(_testimpl.getLocale());
136 _testimpl.setLocale(Locale.JAPANESE);
137 assertEquals(Locale.JAPANESE, _testimpl.getLocale());
138 _mocksControl.verify();
139 }
140
141
142
143
144 @Test
145 public void testCreateUniqueId()
146 {
147
148
149
150
151
152
153
154
155 _mocksControl.replay();
156 Collection<String> createdIds = new HashSet<String>();
157 for (int i = 0; i < 10000; i++)
158 {
159 if (!createdIds.add(_testimpl.createUniqueId()))
160 {
161 fail("duplicate id created");
162 }
163 }
164 _mocksControl.verify();
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435 private void testProcessXXX(TestRunner runner, PhaseId phaseId, boolean expectSuperCall, boolean checkBefore,
436 boolean checkAfter) throws Throwable
437 {
438 expect(_lifecycleFactory.getLifecycle(eq(LifecycleFactory.DEFAULT_LIFECYCLE))).andReturn(_lifecycle);
439 expect(_externalContext.getInitParameter(eq(FacesServlet.LIFECYCLE_ID_ATTR))).andReturn(null).anyTimes();
440
441 PhaseEvent event = new PhaseEvent(_facesContext, phaseId, _lifecycle);
442
443 if (expectSuperCall)
444 {
445 _testimpl = _mocksControl.createMock(UIViewRoot.class, new Method[]{UIViewRoot.class.getMethod(
446 "isRendered", new Class[0])});
447 }
448
449 MethodExpression beforeListener = _mocksControl.createMock(MethodExpression.class);
450 _testimpl.setBeforePhaseListener(beforeListener);
451
452 MethodExpression afterListener = _mocksControl.createMock(MethodExpression.class);
453 _testimpl.setAfterPhaseListener(afterListener);
454
455 Method[] mockedMethods = new Method[] {
456 PhaseListener.class.getMethod("beforePhase", new Class[] { PhaseEvent.class }),
457 PhaseListener.class.getMethod("afterPhase", new Class[] { PhaseEvent.class }) };
458 PhaseListener phaseListener = _mocksControl.createMock(phaseListenerClasses.get(phaseId), mockedMethods);
459 _testimpl.addPhaseListener(phaseListener);
460
461 PhaseListener anyPhaseListener = _mocksControl.createMock(AnyPhasePhaseListener.class, mockedMethods);
462 _testimpl.addPhaseListener(anyPhaseListener);
463
464 PhaseListener restoreViewPhaseListener = _mocksControl.createMock(RestoreViewPhasePhaseListener.class,
465 mockedMethods);
466 _testimpl.addPhaseListener(restoreViewPhaseListener);
467
468 _mocksControl.checkOrder(true);
469
470 if (checkBefore)
471 {
472 expect(beforeListener.invoke(eq(_facesContext.getELContext()), aryEq(new Object[] { event }))).andReturn(
473 null);
474 phaseListener.beforePhase(eq(event));
475 anyPhaseListener.beforePhase(eq(event));
476 }
477
478 if (expectSuperCall)
479 {
480 expect(_testimpl.isRendered()).andReturn(false);
481 }
482
483 if (checkAfter)
484 {
485 expect(afterListener.invoke(eq(_facesContext.getELContext()), aryEq(new Object[] { event }))).andReturn(
486 null);
487 phaseListener.afterPhase(eq(event));
488 anyPhaseListener.afterPhase(eq(event));
489 }
490
491 _mocksControl.replay();
492 runner.run();
493 _mocksControl.verify();
494 }
495
496 private final class ActionListenerImplementation implements ActionListener
497 {
498 public int invocationCount = 0;
499
500 public ActionEvent newActionEventFromListener;
501
502 public ActionListenerImplementation(UICommand otherUiCommand)
503 {
504
505
506 newActionEventFromListener = new ActionEvent(otherUiCommand);
507 }
508
509 public void processAction(ActionEvent actionEvent)
510 throws AbortProcessingException
511 {
512 invocationCount++;
513
514 newActionEventFromListener.queue();
515
516
517 actionEvent.queue();
518 }
519 }
520
521 public static class MockLifeCycleFactory extends LifecycleFactory
522 {
523
524 @Override
525 public void addLifecycle(String lifecycleId, Lifecycle lifecycle)
526 {
527 LIFECYCLEFACTORY.get().addLifecycle(lifecycleId, lifecycle);
528 }
529
530 @Override
531 public Lifecycle getLifecycle(String lifecycleId)
532 {
533 return LIFECYCLEFACTORY.get().getLifecycle(lifecycleId);
534 }
535
536 @Override
537 public Iterator<String> getLifecycleIds()
538 {
539 return LIFECYCLEFACTORY.get().getLifecycleIds();
540 }
541
542 }
543
544 public static abstract class ApplyRequesValuesPhaseListener implements PhaseListener
545 {
546 public PhaseId getPhaseId()
547 {
548 return PhaseId.APPLY_REQUEST_VALUES;
549 }
550 }
551
552 public static abstract class ProcessValidationsPhaseListener implements PhaseListener
553 {
554 public PhaseId getPhaseId()
555 {
556 return PhaseId.PROCESS_VALIDATIONS;
557 }
558 }
559
560 public static abstract class UpdateModelValuesPhaseListener implements PhaseListener
561 {
562 public PhaseId getPhaseId()
563 {
564 return PhaseId.UPDATE_MODEL_VALUES;
565 }
566 }
567
568 public static abstract class InvokeApplicationPhaseListener implements PhaseListener
569 {
570 public PhaseId getPhaseId()
571 {
572 return PhaseId.INVOKE_APPLICATION;
573 }
574 }
575
576 public static abstract class AnyPhasePhaseListener implements PhaseListener
577 {
578 public PhaseId getPhaseId()
579 {
580 return PhaseId.ANY_PHASE;
581 }
582 }
583
584 public static abstract class RestoreViewPhasePhaseListener implements PhaseListener
585 {
586 public PhaseId getPhaseId()
587 {
588 return PhaseId.RESTORE_VIEW;
589 }
590 }
591
592 public static abstract class RenderResponsePhaseListener implements PhaseListener
593 {
594 public PhaseId getPhaseId()
595 {
596 return PhaseId.RENDER_RESPONSE;
597 }
598 }
599
600 @Test
601 public void testBroadcastEvents()
602 {
603
604 UICommand uiCommand = new UICommand();
605 uiCommand.setId("idOfCommandOne");
606 facesContext.getViewRoot().getChildren().add(uiCommand);
607
608
609
610
611 UICommand differentUiCommand = new UICommand();
612 uiCommand.setId("idOfdifferentUiCommand");
613 facesContext.getViewRoot().getChildren().add(differentUiCommand);
614
615
616 ActionListenerImplementation actionListener = new ActionListenerImplementation(differentUiCommand);
617 uiCommand.addActionListener(actionListener);
618
619 ActionListener differentActionListener = org.easymock.EasyMock.createNiceMock(ActionListener.class);
620 differentActionListener.processAction(actionListener.newActionEventFromListener);
621 org.easymock.EasyMock.expectLastCall().times(1);
622 org.easymock.EasyMock.replay(differentActionListener);
623 differentUiCommand.addActionListener(differentActionListener);
624
625
626 ActionEvent invokeApplicationEvent = new ActionEvent(uiCommand);
627 invokeApplicationEvent.queue();
628
629
630
631 facesContext.getViewRoot().broadcastEvents(facesContext, PhaseId.INVOKE_APPLICATION);
632
633 assertEquals(15, actionListener.invocationCount);
634 org.easymock.EasyMock.verify(differentActionListener);
635 }
636
637 }