/* * 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.proxy; import java.util.List; import javax.inject.Inject; import javax.inject.Provider; import org.jukito.JukitoModule; import org.jukito.JukitoRunner; import org.jukito.TestEagerSingleton; import org.jukito.TestMockSingleton; import org.jukito.TestSingleton; import org.junit.Test; import org.junit.runner.RunWith; import com.google.gwt.junit.GWTMockUtilities; import com.google.gwt.user.client.Command; import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.SimpleEventBus; import com.gwtplatform.common.client.StandardProvider; import com.gwtplatform.mvp.client.Presenter; import com.gwtplatform.mvp.client.View; import com.gwtplatform.mvp.shared.proxy.PlaceRequest; import com.gwtplatform.tester.DeferredCommandManager; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; /** * Unit tests for {@link PlaceManagerImpl}. */ @RunWith(JukitoRunner.class) public class PlaceManagerImplTest { /** * Guice test module. */ public static class Module extends JukitoModule { @Override protected void configureTest() { GWTMockUtilities.disarm(); bind(DeferredCommandManager.class).in(TestSingleton.class); bind(EventBus.class).to(SimpleEventBus.class).in(TestSingleton.class); bind(PlaceManager.class).to(PlaceManagerTestUtil.class).in(TestSingleton.class); bind(DummyPresenterRedirect.class); bind(DummyPresenterRedirectNoHistory.class); bind(DummyProxyBasic.class); bind(DummyProxyPlaceBasic.class); bind(DummyProxyRedirect.class); bind(DummyProxyPlaceRedirect.class); bind(DummyProxyRedirectNoHistory.class); bind(DummyProxyPlaceRedirectNoHistory.class); } } @TestMockSingleton abstract static class DummyPresenterBasic extends Presenter<View, DummyProxyPlaceBasic> { @Inject DummyPresenterBasic(EventBus eventBus, View view, DummyProxyPlaceBasic proxy) { super(eventBus, view, proxy); } @Override public final boolean isVisible() { return super.isVisible(); } } @TestEagerSingleton static class DummyProxyBasic extends ProxyImpl<DummyPresenterBasic> { @Inject DummyProxyBasic(Provider<DummyPresenterBasic> presenter) { this.presenter = new StandardProvider<>(presenter); } } abstract static class ProxyPlaceBase<P extends Presenter<?, ?>> extends ProxyPlaceImpl<P> { private final DeferredCommandManager deferredCommandManager; ProxyPlaceBase(Place place, Proxy<P> proxy, DeferredCommandManager deferredCommandManager) { super(); super.setPlace(place); super.setProxy(proxy); this.deferredCommandManager = deferredCommandManager; } @Override void addDeferredCommand(Command command) { deferredCommandManager.addCommand(command); } } @TestEagerSingleton static class DummyProxyPlaceBasic extends ProxyPlaceBase<DummyPresenterBasic> { @Inject DummyProxyPlaceBasic(DummyProxyBasic proxy, DeferredCommandManager deferredCommandManager) { super(new PlaceImpl("dummyNameTokenBasic"), proxy, deferredCommandManager); } } /** * This presenter automatically redirects in prepareFromRequest to PresenterBasic. */ @TestEagerSingleton static class DummyPresenterRedirect extends Presenter<View, DummyProxyPlaceBasic> { public PlaceRequest preparedRequest; public int prepareFromRequestCalls; public int revealInParentCalls; private final PlaceManager placeManager; @Inject DummyPresenterRedirect(EventBus eventBus, DummyProxyPlaceBasic proxy, PlaceManager placeManager) { super(eventBus, mock(View.class), proxy); this.placeManager = placeManager; } @Override public void prepareFromRequest(PlaceRequest request) { super.prepareFromRequest(request); ++prepareFromRequestCalls; preparedRequest = request; placeManager.revealPlace(new PlaceRequest.Builder().nameToken("dummyNameTokenBasic").build()); } @Override protected void revealInParent() { ++revealInParentCalls; } } @TestEagerSingleton static class DummyProxyRedirect extends ProxyImpl<DummyPresenterRedirect> { @Inject DummyProxyRedirect(Provider<DummyPresenterRedirect> presenter) { this.presenter = new StandardProvider<>(presenter); } } @TestEagerSingleton static class DummyProxyPlaceRedirect extends ProxyPlaceBase<DummyPresenterRedirect> { @Inject DummyProxyPlaceRedirect(DummyProxyRedirect proxy, DeferredCommandManager deferredCommandManager) { super(new PlaceImpl("dummyNameTokenRedirect"), proxy, deferredCommandManager); } } @TestEagerSingleton static class DummyPresenterRedirectNoHistory extends Presenter<View, DummyProxyPlaceRedirectNoHistory> { private static final String TOKEN = "dummyNameTokenRedirectNoHistory"; private final PlaceManager placeManager; @Inject DummyPresenterRedirectNoHistory(EventBus eventBus, DummyProxyPlaceRedirectNoHistory proxy, PlaceManager placeManager) { super(eventBus, mock(View.class), proxy); this.placeManager = placeManager; } @Override public void prepareFromRequest(PlaceRequest request) { super.prepareFromRequest(request); // This call is deferred by GWTP placeManager.revealPlace(new PlaceRequest.Builder().nameToken("dummyNameTokenBasic").build(), false); } @Override protected void revealInParent() { } } @TestEagerSingleton static class DummyProxyRedirectNoHistory extends ProxyImpl<DummyPresenterRedirectNoHistory> { @Inject DummyProxyRedirectNoHistory(Provider<DummyPresenterRedirectNoHistory> presenter) { this.presenter = new StandardProvider<>(presenter); } } @TestEagerSingleton static class DummyProxyPlaceRedirectNoHistory extends ProxyPlaceBase<DummyPresenterRedirectNoHistory> { @Inject DummyProxyPlaceRedirectNoHistory(DummyProxyRedirectNoHistory proxy, DeferredCommandManager deferredCommandManager) { super(new PlaceImpl(DummyPresenterRedirectNoHistory.TOKEN), proxy, deferredCommandManager); } } @TestSingleton static class NavigationEventSpy implements NavigationHandler { int navCount; NavigationEvent lastEvent; @Override public void onNavigation(NavigationEvent navigationEvent) { navCount++; lastEvent = navigationEvent; } } // SUT @Inject PlaceManager placeManager; @Inject DeferredCommandManager deferredCommandManager; @Inject PlaceManagerWindowMethodsTestUtil gwtWindowMethods; @Inject NavigationEventSpy navigationHandler; @Inject EventBus eventBus; @Test public void placeManagerRevealPlaceStandard( DummyPresenterBasic presenter) { // Given eventBus.addHandler(NavigationEvent.getType(), navigationHandler); // When placeManager.revealPlace(new PlaceRequest.Builder().nameToken("dummyNameTokenBasic").with("dummyParam", "dummyValue").build()); deferredCommandManager.pump(); // Then List<PlaceRequest> placeHierarchy = placeManager.getCurrentPlaceHierarchy(); assertEquals(1, placeHierarchy.size()); PlaceRequest placeRequest = placeManager.getCurrentPlaceRequest(); assertEquals(placeHierarchy.get(0), placeRequest); assertEquals("dummyNameTokenBasic", placeRequest.getNameToken()); assertEquals(1, placeRequest.getParameterNames().size()); assertEquals("dummyValue", placeRequest.getParameter("dummyParam", null)); verify(presenter).prepareFromRequest(placeRequest); verify(presenter).forceReveal(); verify(gwtWindowMethods).setBrowserHistoryToken(any(String.class), eq(false)); assertEquals(1, navigationHandler.navCount); placeRequest = navigationHandler.lastEvent.getRequest(); assertEquals("dummyNameTokenBasic", placeRequest.getNameToken()); assertEquals(1, placeRequest.getParameterNames().size()); assertEquals("dummyValue", placeRequest.getParameter("dummyParam", null)); } /** * DummyPresenterRedirectNoHistory makes a call to revealPlace in prepareFromRequest. This call * is deferred but useBrowserUrl must be preserved and the history token must be set only once. */ @Test public void placeManagerRevealPlaceRedirectInPrepareFromRequestNoHistory() { // Given PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken(DummyPresenterRedirectNoHistory.TOKEN).build(); // When placeManager.revealPlace(placeRequest); deferredCommandManager.pump(); // Then // assert called only once verify(gwtWindowMethods, times(1)).setBrowserHistoryToken(any(String.class), eq(false)); PlaceRequest finalPlaceRequest = placeManager.getCurrentPlaceRequest(); assertEquals("dummyNameTokenBasic", finalPlaceRequest.getNameToken()); } @Test public void placeManagerRevealPlaceRedirectInPrepareFromRequest( DummyPresenterRedirect presenter, DummyPresenterBasic otherPresenter) { // Given PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken("dummyNameTokenRedirect").with("dummyParam", "dummyValue").build(); // When placeManager.revealPlace(placeRequest); deferredCommandManager.pump(); // Then List<PlaceRequest> placeHierarchy = placeManager.getCurrentPlaceHierarchy(); assertEquals(1, placeHierarchy.size()); PlaceRequest finalPlaceRequest = placeManager.getCurrentPlaceRequest(); assertEquals(placeHierarchy.get(0), finalPlaceRequest); assertEquals("dummyNameTokenBasic", finalPlaceRequest.getNameToken()); assertEquals(0, finalPlaceRequest.getParameterNames().size()); assertEquals(1, presenter.prepareFromRequestCalls); assertEquals(placeRequest, presenter.preparedRequest); assertEquals(0, presenter.revealInParentCalls); verify(otherPresenter).prepareFromRequest(finalPlaceRequest); verify(otherPresenter).forceReveal(); } @Test public void placeManagerUserUpdateHistoryWhenRevealPlace( DummyPresenterRedirect presenter, DummyPresenterBasic otherPresenter) { // Given PlaceRequest placeRequest = new PlaceRequest.Builder().nameToken("dummyNameTokenRedirect").with("dummyParam", "dummyValue").build(); // When placeManager.revealPlace(placeRequest); deferredCommandManager.pump(); // Then List<PlaceRequest> placeHierarchy = placeManager.getCurrentPlaceHierarchy(); assertEquals(1, placeHierarchy.size()); PlaceRequest finalPlaceRequest = placeManager.getCurrentPlaceRequest(); assertEquals(placeHierarchy.get(0), finalPlaceRequest); assertEquals("dummyNameTokenBasic", finalPlaceRequest.getNameToken()); assertEquals(0, finalPlaceRequest.getParameterNames().size()); assertEquals(1, presenter.prepareFromRequestCalls); assertEquals(placeRequest, presenter.preparedRequest); assertEquals(0, presenter.revealInParentCalls); verify(otherPresenter).prepareFromRequest(finalPlaceRequest); verify(otherPresenter).forceReveal(); } }