/* * Copyright 2011 ArcBees Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.gwtplatform.mvp.client; import javax.inject.Inject; import javax.inject.Named; import org.jukito.JukitoModule; import org.jukito.JukitoRunner; import org.jukito.TestSingleton; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.junit.GWTMockUtilities; import com.google.gwt.user.client.ui.Widget; import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.HandlerRegistration; import com.gwtplatform.mvp.client.presenter.slots.Slot; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Unit tests for {@link PresenterWidget}. */ @RunWith(JukitoRunner.class) public class PresenterWidgetTest { /** * Guice test module. */ public static class Module extends JukitoModule { @Override protected void configureTest() { GWTMockUtilities.disarm(); forceMock(Widget.class); } } @TestSingleton static class PresenterWidgetA extends PresenterWidgetSpy<View> { @Inject PresenterWidgetA(EventBus eventBus, @Named("A") View view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetB extends PresenterWidgetSpy<View> { @Inject PresenterWidgetB(EventBus eventBus, @Named("B") View view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetC extends PresenterWidgetSpy<View> { @Inject PresenterWidgetC(EventBus eventBus, @Named("C") View view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetD extends PresenterWidget<View> { @Inject PresenterWidgetD(@Named("EventBusA") EventBus eventBus, @Named("A") PopupView view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetE extends PresenterWidgetSpy<View> { @Inject PresenterWidgetE(EventBus eventBus, @Named("E") View view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetF extends PresenterWidgetSpy<View> { @Inject PresenterWidgetF(EventBus eventBus, @Named("F") View view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetPopupB extends PresenterWidgetSpy<PopupView> { @Inject PresenterWidgetPopupB(EventBus eventBus, @Named("PopupB") PopupView view) { super(eventBus, view); } } @TestSingleton static class PresenterWidgetPopupC extends PresenterWidgetSpy<PopupView> { @Inject PresenterWidgetPopupC(EventBus eventBus, @Named("PopupC") PopupView view) { super(eventBus, view); } } // Simple subclasses of PresenterWidget abstract static class PresenterWidgetSpy<V extends View> extends PresenterWidget<V> { public int onHideMethodCalled; public int onResetMethodCalled; public int onRevealMethodCalled; PresenterWidgetSpy(EventBus eventBus, V view) { super(eventBus, view); } @Override protected void onHide() { super.onHide(); onHideMethodCalled++; } @Override protected void onReset() { super.onReset(); onResetMethodCalled++; } @Override protected void onReveal() { super.onReveal(); onRevealMethodCalled++; } } @Inject @Named("A") Widget widgetA; @Inject @Named("B") Widget widgetB; @Inject @Named("C") Widget widgetC; @Inject @Named("PopupB") Widget widgetPopupB; @Inject @Named("PopupC") Widget widgetPopupC; @Inject @Named("A") View viewA; @Inject @Named("B") View viewB; @Inject @Named("C") View viewC; @Inject @Named("PopupB") PopupView popupViewB; @Inject @Named("PopupC") PopupView popupViewC; @Inject @Named("EventBusA") EventBus eventBusA; @Inject GwtEvent.Type<EventHandler> typeA; @Inject EventHandler handlerA; @Inject HandlerRegistration registrationA; @Before public void arrange() { when(viewA.asWidget()).thenReturn(widgetA); when(viewB.asWidget()).thenReturn(widgetB); when(viewC.asWidget()).thenReturn(widgetC); when(popupViewB.asWidget()).thenReturn(widgetPopupB); when(popupViewC.asWidget()).thenReturn(widgetPopupC); when(eventBusA.addHandler(typeA, handlerA)).thenReturn(registrationA); } @Test public void onRevealMakesPresenterWidgetVisible( PresenterWidgetA presenterWidget) { // When presenterWidget.internalReveal(); // Then assertTrue(presenterWidget.isVisible()); } @Test public void presenterWidgetIsInitiallyNotVisible( PresenterWidgetA presenterWidget) { // Then assertEquals(0, presenterWidget.onRevealMethodCalled); assertEquals(0, presenterWidget.onHideMethodCalled); assertFalse(presenterWidget.isVisible()); } @Test public void shouldHidePopupWhenPopupPresenterRemoved( PresenterWidgetA presenterWidgetA, PresenterWidgetPopupB popupContentB) { // Given presenterWidgetA.internalReveal(); // When presenterWidgetA.addToPopupSlot(popupContentB); // Then verify(popupContentB.getView()).showAndReposition(); assertEquals(1, popupContentB.onRevealMethodCalled); assertTrue(popupContentB.isVisible()); // and When presenterWidgetA.removeFromPopupSlot(popupContentB); // Then verify(popupContentB.getView()).hide(); assertEquals(1, popupContentB.onHideMethodCalled); assertFalse(popupContentB.isVisible()); } @Test public void testAddAndRemoveVisibleHandler( PresenterWidgetD presenterWidgetD) { // Given assertFalse(presenterWidgetD.isVisible()); presenterWidgetD.addVisibleHandler(typeA, handlerA); // when presenterWidgetD.internalReveal(); // Then verify(eventBusA).addHandler(typeA, handlerA); // and then When presenterWidgetD.internalHide(); // Then verify(registrationA).removeHandler(); } @Test public void testAddPopupOnInitiallyInvisiblePresenter( PresenterWidgetA presenterWidgetA, PresenterWidgetPopupB popupContentB, PresenterWidgetPopupC popupContentC) { // Given // presenterWidget is NOT visible assertFalse(presenterWidgetA.isVisible()); // When presenterWidgetA.addToPopupSlot(popupContentB); presenterWidgetA.addToPopupSlot(popupContentC); // Then verify(popupContentB.getView(), times(0)).showAndReposition(); verify(popupContentC.getView(), times(0)).showAndReposition(); verify(popupContentB.getView(), times(0)).hide(); verify(popupContentC.getView(), times(0)).hide(); assertEquals(0, popupContentB.onRevealMethodCalled); assertEquals(0, popupContentC.onRevealMethodCalled); // and then When presenterWidgetA.internalReveal(); // Then assertEquals(1, popupContentB.onRevealMethodCalled); assertEquals(1, popupContentC.onRevealMethodCalled); verify(popupContentB.getView()).showAndReposition(); verify(popupContentC.getView()).showAndReposition(); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, popupContentB.onRevealMethodCalled); assertEquals(1, popupContentC.onRevealMethodCalled); assertEquals(1, popupContentB.onHideMethodCalled); assertEquals(1, popupContentC.onHideMethodCalled); verify(popupContentB.getView()).showAndReposition(); verify(popupContentC.getView()).showAndReposition(); verify(popupContentB.getView()).hide(); verify(popupContentC.getView()).hide(); } // TODO Make sure the calls happen in the right order // parent then child for onReveal and onReset // child then parent for onHide @Test public void testAddToSlotToSlot( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentC) { // Given Slot<PresenterWidget<?>> slotBC = new Slot<>(); presenterWidgetA.internalReveal(); // When presenterWidgetA.addToSlot(slotBC, contentB); presenterWidgetA.addToSlot(slotBC, contentC); // Then verify(viewA).addToSlot(slotBC, contentB); verify(viewA).addToSlot(slotBC, contentC); assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentC.onRevealMethodCalled); // and When presenterWidgetA.clearSlot(slotBC); // Then verify(viewA).setInSlot(slotBC, null); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentC.onHideMethodCalled); } @Test public void testAddVisibleHandlerOnVisiblePresenter( PresenterWidgetD presenterWidgetD) { // Given assertFalse(presenterWidgetD.isVisible()); // and presenterWidgetD.internalReveal(); // when presenterWidgetD.addVisibleHandler(typeA, handlerA); // Then verify(eventBusA).addHandler(typeA, handlerA); // and then When presenterWidgetD.internalHide(); // Then verify(registrationA).removeHandler(); } @Test public void testClearContentInSlot( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB) { // Given Slot<PresenterWidget<?>> slotB = new Slot<>(); presenterWidgetA.internalReveal(); presenterWidgetA.setInSlot(slotB, contentB); // When presenterWidgetA.clearSlot(slotB); // Then verify(viewA).setInSlot(slotB, null); assertEquals(1, contentB.onHideMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onHideMethodCalled); } @Test public void testPresenterWidgetCannotBeInMultipleSlots( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB) { // Given Slot<PresenterWidget<?>> slotA = new Slot<>(); Slot<PresenterWidget<?>> slotB = new Slot<>(); presenterWidgetA.internalReveal(); // When presenterWidgetA.setInSlot(slotA, contentB); presenterWidgetA.setInSlot(slotB, contentB); presenterWidgetA.clearSlot(slotB); contentB.internalReveal(); presenterWidgetA.internalHide(); // Then assertTrue(contentB.isVisible()); } @Test public void testRemoveFromSlotFromSlot( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentC) { // Given Slot<PresenterWidget<?>> slotBC = new Slot<>(); presenterWidgetA.internalReveal(); presenterWidgetA.addToSlot(slotBC, contentB); presenterWidgetA.addToSlot(slotBC, contentC); // When presenterWidgetA.removeFromSlot(slotBC, contentB); // Then verify(viewA).removeFromSlot(slotBC, contentB); assertEquals(1, contentB.onHideMethodCalled); assertEquals(0, contentC.onHideMethodCalled); } @Test public void testSetInSlotHierarchyInEmptySlotOnInitiallyInvisiblePresenter1( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentCinB) { // Given // slot is empty in presenterWidgets, and it is NOT visible Slot<PresenterWidget<?>> slotB = new Slot<>(); Slot<PresenterWidget<?>> slotC = new Slot<>(); assertFalse(presenterWidgetA.isVisible()); assertFalse(contentB.isVisible()); // When presenterWidgetA.setInSlot(slotB, contentB); contentB.setInSlot(slotC, contentCinB); // Then verify(viewA).setInSlot(slotB, contentB); verify(viewB).setInSlot(slotC, contentCinB); assertEquals(0, contentB.onRevealMethodCalled); assertEquals(0, contentCinB.onRevealMethodCalled); // and then When presenterWidgetA.internalReveal(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentCinB.onHideMethodCalled); } @Test public void testSetInSlotHierarchyInEmptySlotOnInitiallyInvisiblePresenter2( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentCinB) { // Given // slot is empty in presenterWidgets, and it is NOT visible Slot<PresenterWidget<?>> slotB = new Slot<>(); Slot<PresenterWidget<?>> slotC = new Slot<>(); assertFalse(presenterWidgetA.isVisible()); assertFalse(contentB.isVisible()); // When contentB.setInSlot(slotC, contentCinB); // Then verify(viewB).setInSlot(slotC, contentCinB); assertEquals(0, contentCinB.onRevealMethodCalled); // and then When presenterWidgetA.setInSlot(slotB, contentB); // Then verify(viewA).setInSlot(slotB, contentB); assertEquals(0, contentB.onRevealMethodCalled); // and then When presenterWidgetA.internalReveal(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentCinB.onHideMethodCalled); } @Test public void testSetInSlotHierarchyInEmptySlotOnInitiallyVisiblePresenter( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentCinB) { // Given Slot<PresenterWidget<?>> slotB = new Slot<>(); Slot<PresenterWidget<?>> slotC = new Slot<>(); presenterWidgetA.internalReveal(); // When presenterWidgetA.setInSlot(slotB, contentB); contentB.setInSlot(slotC, contentCinB); // Then verify(viewA).setInSlot(slotB, contentB); verify(viewB).setInSlot(slotC, contentCinB); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentCinB.onRevealMethodCalled); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentCinB.onHideMethodCalled); } @Test public void testSetInSlotInEmptySlotOnInitiallyInvisiblePresenter( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentC) { // Given // slot is empty in presenterWidget, and it is NOT visible Slot<PresenterWidget<?>> slotB = new Slot<>(); Slot<PresenterWidget<?>> slotC = new Slot<>(); assertFalse(presenterWidgetA.isVisible()); // When presenterWidgetA.setInSlot(slotB, contentB); presenterWidgetA.setInSlot(slotC, contentC); // Then verify(viewA).setInSlot(slotB, contentB); verify(viewA).setInSlot(slotC, contentC); assertEquals(0, contentB.onRevealMethodCalled); assertEquals(0, contentC.onRevealMethodCalled); // and then When presenterWidgetA.internalReveal(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentC.onRevealMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentC.onRevealMethodCalled); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentC.onHideMethodCalled); } @Test public void testSetInSlotInEmptySlotOnInitiallyVisiblePresenter( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB, PresenterWidgetC contentC) { // Given Slot<PresenterWidget<?>> slotB = new Slot<>(); Slot<PresenterWidget<?>> slotC = new Slot<>(); presenterWidgetA.internalReveal(); // When presenterWidgetA.setInSlot(slotB, contentB); presenterWidgetA.setInSlot(slotC, contentC); // Then verify(viewA).setInSlot(slotB, contentB); verify(viewA).setInSlot(slotC, contentC); assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentC.onRevealMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onRevealMethodCalled); assertEquals(1, contentC.onRevealMethodCalled); assertEquals(1, contentB.onHideMethodCalled); assertEquals(1, contentC.onHideMethodCalled); } @Test public void testSetNullContentInSlot( PresenterWidgetA presenterWidgetA, PresenterWidgetB contentB) { // Given Slot<PresenterWidget<?>> slotB = new Slot<>(); presenterWidgetA.internalReveal(); presenterWidgetA.setInSlot(slotB, contentB); // When presenterWidgetA.setInSlot(slotB, null); // Then verify(viewA).setInSlot(slotB, null); assertEquals(1, contentB.onHideMethodCalled); // and then When presenterWidgetA.internalHide(); // Then assertEquals(1, contentB.onHideMethodCalled); } @Test public void testSwitchPopupToAnotherPresenter1( PresenterWidgetA presenterWidgetA, PresenterWidgetB presenterWidgetB, PresenterWidgetPopupC popupContentC) { // Given presenterWidgetA.internalReveal(); presenterWidgetB.internalReveal(); presenterWidgetA.addToPopupSlot(popupContentC); // When presenterWidgetB.addToPopupSlot(popupContentC); presenterWidgetB.internalHide(); // Then assertFalse(popupContentC.isVisible()); } @Test public void testSwitchPopupToAnotherPresenter2( PresenterWidgetA presenterWidgetA, PresenterWidgetB presenterWidgetB, PresenterWidgetPopupC popupContentC) { // Given presenterWidgetA.internalReveal(); presenterWidgetB.internalReveal(); presenterWidgetA.addToPopupSlot(popupContentC); // When presenterWidgetB.addToPopupSlot(popupContentC); presenterWidgetB.internalHide(); presenterWidgetA.addToPopupSlot(popupContentC); // Then assertTrue(popupContentC.isVisible()); } @Test public void testSwitchPresenterWidgetToAnotherPresenter1( PresenterWidgetA presenterWidgetA, PresenterWidgetB presenterWidgetB, PresenterWidgetC contentC) { // Given Slot<PresenterWidget<?>> slotCinA = new Slot<>(); Slot<PresenterWidget<?>> slotCinB = new Slot<>(); presenterWidgetA.internalReveal(); presenterWidgetB.internalReveal(); // When presenterWidgetA.setInSlot(slotCinA, contentC); presenterWidgetB.setInSlot(slotCinB, contentC); presenterWidgetB.internalHide(); // Then assertFalse(contentC.isVisible()); } @Test public void testSwitchPresenterWidgetToAnotherPresenter2( PresenterWidgetA presenterWidgetA, PresenterWidgetB presenterWidgetB, PresenterWidgetC contentC) { // Given Slot<PresenterWidget<?>> slotCinA = new Slot<>(); Slot<PresenterWidget<?>> slotCinB = new Slot<>(); presenterWidgetA.internalReveal(); presenterWidgetB.internalReveal(); // When presenterWidgetA.setInSlot(slotCinA, contentC); presenterWidgetB.setInSlot(slotCinB, contentC); presenterWidgetB.internalHide(); presenterWidgetA.setInSlot(slotCinA, contentC); // Then assertTrue(contentC.isVisible()); } }