PageRenderTime 59ms CodeModel.GetById 10ms app.highlight 44ms RepoModel.GetById 2ms app.codeStats 0ms

/sigmah/src/test/java/org/sigmah/client/page/NavigationHandlerTest.java

http://sigma-h.googlecode.com/
Java | 263 lines | 189 code | 70 blank | 4 comment | 1 complexity | 0a724a5c50e0dbf4e6a9ed7944622405 MD5 | raw file
  1/*
  2 * All Sigmah code is released under the GNU General Public License v3
  3 * See COPYRIGHT.txt and LICENSE.txt.
  4 */
  5
  6package org.sigmah.client.page;
  7
  8import com.google.gwt.user.client.rpc.AsyncCallback;
  9import org.easymock.Capture;
 10import org.easymock.IAnswer;
 11import org.junit.Assert;
 12import org.junit.Before;
 13import org.junit.Test;
 14import org.sigmah.client.dispatch.monitor.NullAsyncMonitor;
 15import org.sigmah.client.event.NavigationEvent;
 16import org.sigmah.client.event.NavigationEvent.NavigationError;
 17import org.sigmah.client.mock.MockEventBus;
 18
 19import java.util.Arrays;
 20import java.util.HashMap;
 21import java.util.List;
 22import java.util.Map;
 23
 24import static org.easymock.EasyMock.*;
 25
 26public class NavigationHandlerTest {
 27
 28
 29    private MockEventBus eventBus = new MockEventBus();
 30
 31    private Frame rootFrameSet = createMock("rootFrameSet", Frame.class);
 32
 33    private FrameId outerFrameSetId = new FrameId("outerFrameSet");
 34    private Frame outerFrameSet = createMock("outerFrameSet", Frame.class);
 35
 36    private PageId firstPageId = new PageId("page1");
 37    private Page firstPage = createMock("firstPage", Frame.class);
 38
 39    private PageId secondPageId = new PageId("page2");
 40    private Page secondPage = createMock("secondPage", Page.class);
 41
 42    private PageLoader pageLoader = createMock("pageLoader", PageLoader.class);
 43
 44    private PageState innerPlaceWithOuterFrame = new MockPageState(firstPageId, Arrays.asList(outerFrameSetId, firstPageId));
 45    private PageState secondInnerPlaceWithSameOuterFrame = new MockPageState(secondPageId, Arrays.asList(outerFrameSetId, secondPageId));
 46
 47    private PageState firstPlace = new MockPageState(firstPageId, Arrays.asList(firstPageId));
 48    private PageState secondPlace = new MockPageState(secondPageId, Arrays.asList(secondPageId));
 49
 50    private NavigationHandler pageManager;
 51
 52
 53    @Before
 54    public void setUp() {
 55
 56        expect(outerFrameSet.getPageId()).andReturn(outerFrameSetId).anyTimes();
 57        expect(firstPage.getPageId()).andReturn(firstPageId).anyTimes();
 58
 59        pageManager = new NavigationHandler(eventBus, rootFrameSet );
 60    }
 61
 62    @Test
 63    public void verifyThatAPageWithOneOuterContainerIsCorrectlyLoaded() {
 64
 65        thereIsNoActivePageIn(rootFrameSet);
 66        expectLoadingPlaceHolderToBeShown(rootFrameSet);
 67        expectAndCaptureLoadRequestFor(outerFrameSetId);
 68        expectPageToBeSetTo(rootFrameSet, outerFrameSet);
 69        thereIsNoActivePageIn(outerFrameSet);
 70        expectLoadingPlaceHolderToBeShown(outerFrameSet);
 71        expectAndCaptureLoadRequestFor(firstPageId);
 72        expectPageToBeSetTo(outerFrameSet, firstPage);
 73
 74        replayAll();
 75
 76        pageManager.registerPageLoader(outerFrameSetId, pageLoader);
 77        pageManager.registerPageLoader(firstPageId, pageLoader);
 78
 79        requestNavigationTo(innerPlaceWithOuterFrame);
 80        pageLoadFinishes(outerFrameSetId, outerFrameSet);
 81        pageLoadFinishes(firstPageId, firstPage);
 82
 83        verify(rootFrameSet, outerFrameSet, firstPage, pageLoader);
 84    }
 85
 86
 87    @Test
 88    public void innerPageCanCancelNavigation() {
 89        theRootPageIs(outerFrameSet);
 90        theOuterFrameSetIsShowing(firstPage);
 91
 92        navigationRequestWillBeRefusedBy(firstPage);
 93
 94        replayAll();
 95
 96        requestNavigationTo(secondInnerPlaceWithSameOuterFrame);
 97
 98        verify(outerFrameSet, firstPage);
 99
100        eventBus.assertNotFired(NavigationHandler.NavigationAgreed);
101    }
102
103    @Test
104    public void navigationProceedsUponApprovalOfInnerPage() {
105
106        theRootPageIs(outerFrameSet);
107        theOuterFrameSetIsShowing(firstPage);
108
109        expectAndAgreeToNavigationRequestionOn(firstPage);
110        expectNavigate(outerFrameSet);
111        expectLoadingPlaceHolderToBeShown(outerFrameSet);
112        expectAndCaptureLoadRequestFor(secondPageId);
113        expectShutdownCallTo(firstPage);
114        expectPageToBeSetTo(outerFrameSet, secondPage);
115
116        replayAll();
117
118        pageManager.registerPageLoader(secondPageId, pageLoader);
119        requestNavigationTo(secondInnerPlaceWithSameOuterFrame);
120        pageLoadFinishes(secondPageId, secondPage);
121        
122        verify(outerFrameSet, firstPage, pageLoader);
123
124        Assert.assertEquals(1, eventBus.getEventCount(NavigationHandler.NavigationAgreed));
125    }
126
127    @Test
128    public void userCanNavigateToDifferentPageWhilePreviousRequestIsLoading() {
129
130        thereIsNoActivePageIn(rootFrameSet);
131        expectLoadingPlaceHolderToBeShownTwiceIn(rootFrameSet);
132        expectAndCaptureLoadRequestFor(firstPageId);
133        expectAndCaptureLoadRequestFor(secondPageId);
134        expectPageToBeSetTo(rootFrameSet, secondPage);
135
136        replayAll();
137
138        pageManager.registerPageLoader(firstPageId, pageLoader);
139        pageManager.registerPageLoader(secondPageId, pageLoader);
140        requestNavigationTo(firstPlace);
141        requestNavigationTo(secondPlace);
142        pageLoadFinishes(secondPageId, secondPage);
143        pageLoadFinishes(firstPageId, firstPage);
144
145        verify(rootFrameSet, pageLoader);
146    }
147
148
149    private class MockPageState implements PageState {
150        private final PageId pageId;
151        private final List<PageId> viewPath;
152
153        private MockPageState(PageId pageId, List<PageId> viewPath) {
154            this.pageId = pageId;
155            this.viewPath = viewPath;
156        }
157        public PageId getPageId() { return pageId;  }
158        public String serializeAsHistoryToken() { return null; }
159        public List<PageId> getEnclosingFrames() { return viewPath; }
160    }
161
162    @Test
163    public void duplicateNavigationRequestsAreIgnored() {
164        thereIsNoActivePageIn(rootFrameSet);
165        expectLoadingPlaceHolderToBeShown(rootFrameSet);
166        expectAndCaptureLoadRequestFor(firstPageId);
167        expectPageToBeSetTo(rootFrameSet, firstPage);
168
169        replayAll();
170
171        pageManager.registerPageLoader(firstPageId, pageLoader);
172        requestNavigationTo(firstPlace);
173        requestNavigationTo(firstPlace);
174        pageLoadFinishes(firstPageId, firstPage);
175
176        verify(rootFrameSet, pageLoader, firstPage);
177    }
178
179
180    private void theRootPageIs(Page page) {
181        expect(rootFrameSet.getActivePage()).andReturn(page).anyTimes();
182    }
183
184    private void theOuterFrameSetIsShowing(Page page) {
185        expect(outerFrameSet.getActivePage()).andReturn(page).anyTimes();
186    }
187
188    private void requestNavigationTo(PageState place) {
189        eventBus.fireEvent(new NavigationEvent(NavigationHandler.NavigationRequested, place, null));
190    }
191
192    private void thereIsNoActivePageIn(Frame rootFrameSet) {
193        expect(rootFrameSet.getActivePage()).andReturn(null).anyTimes();
194    }
195
196    private void expectShutdownCallTo(Page page) {
197        page.shutdown();
198    }
199
200    private void expectNavigate(Frame frameSet) {
201        expect(frameSet.navigate(isA(PageState.class))).andReturn(true);
202    }
203
204    private Map<PageId, Capture<AsyncCallback<Page>>> loadCallbacks = new HashMap();
205
206    private void expectAndCaptureLoadRequestFor(PageId pageId) {
207        Capture<AsyncCallback<Page>> capture = new Capture<AsyncCallback<Page>>();
208        loadCallbacks.put(pageId, capture);
209
210        pageLoader.load(eq(pageId), isA(PageState.class), capture(capture));
211        expectLastCall().anyTimes();
212    }
213
214    private void pageLoadFinishes(PageId pageId, Page page) {
215        loadCallbacks.get(pageId).getValue().onSuccess(page);
216    }
217
218    private void expectPageToBeSetTo(Frame frameSet, Page page) {
219        frameSet.setActivePage(page);
220    }
221
222    private void expectLoadingPlaceHolderToBeShown(Frame frame) {
223        expect(frame.showLoadingPlaceHolder(isA(PageId.class), isA(PageState.class)))
224                .andReturn(new NullAsyncMonitor());
225    }
226
227    private void expectLoadingPlaceHolderToBeShownTwiceIn(Frame frame) {
228        expect(frame.showLoadingPlaceHolder(isA(PageId.class), isA(PageState.class)))
229                .andReturn(new NullAsyncMonitor())
230                .times(2);
231    }
232
233    private void navigationRequestWillBeRefusedBy(Page page) {
234        navigationRequestWillBeAnsweredBy(page, false);
235    }
236
237    private void expectAndAgreeToNavigationRequestionOn(Page page) {
238        navigationRequestWillBeAnsweredBy(page, true);
239    }
240
241    private void navigationRequestWillBeAnsweredBy(Page page, final boolean allowed) {
242        page.requestToNavigateAway(isA(PageState.class), isA(NavigationCallback.class));
243        expectLastCall().andAnswer(new IAnswer<Void>() {
244            @Override
245            public Void answer() throws Throwable {
246                if(allowed)
247                    ((NavigationCallback)(getCurrentArguments()[1])).onDecided(NavigationError.NONE);
248                else
249                    ((NavigationCallback)(getCurrentArguments()[1])).onDecided(NavigationError.EXECUTION_ERROR);
250                return null;
251            }
252        });
253    }
254
255    private void replayAll() {
256        replay(rootFrameSet);
257        replay(pageLoader);
258        replay(outerFrameSet);
259        replay(firstPage);
260        replay(secondPage);
261    }
262
263}