/sigmah/src/test/java/org/sigmah/client/page/NavigationHandlerTest.java
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}