/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. package org.sigmah.client.page;
  6. import com.google.gwt.user.client.rpc.AsyncCallback;
  7. import org.easymock.Capture;
  8. import org.easymock.IAnswer;
  9. import org.junit.Assert;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12. import org.sigmah.client.dispatch.monitor.NullAsyncMonitor;
  13. import org.sigmah.client.event.NavigationEvent;
  14. import org.sigmah.client.event.NavigationEvent.NavigationError;
  15. import org.sigmah.client.mock.MockEventBus;
  16. import java.util.Arrays;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import static org.easymock.EasyMock.*;
  21. public class NavigationHandlerTest {
  22. private MockEventBus eventBus = new MockEventBus();
  23. private Frame rootFrameSet = createMock("rootFrameSet", Frame.class);
  24. private FrameId outerFrameSetId = new FrameId("outerFrameSet");
  25. private Frame outerFrameSet = createMock("outerFrameSet", Frame.class);
  26. private PageId firstPageId = new PageId("page1");
  27. private Page firstPage = createMock("firstPage", Frame.class);
  28. private PageId secondPageId = new PageId("page2");
  29. private Page secondPage = createMock("secondPage", Page.class);
  30. private PageLoader pageLoader = createMock("pageLoader", PageLoader.class);
  31. private PageState innerPlaceWithOuterFrame = new MockPageState(firstPageId, Arrays.asList(outerFrameSetId, firstPageId));
  32. private PageState secondInnerPlaceWithSameOuterFrame = new MockPageState(secondPageId, Arrays.asList(outerFrameSetId, secondPageId));
  33. private PageState firstPlace = new MockPageState(firstPageId, Arrays.asList(firstPageId));
  34. private PageState secondPlace = new MockPageState(secondPageId, Arrays.asList(secondPageId));
  35. private NavigationHandler pageManager;
  36. @Before
  37. public void setUp() {
  38. expect(outerFrameSet.getPageId()).andReturn(outerFrameSetId).anyTimes();
  39. expect(firstPage.getPageId()).andReturn(firstPageId).anyTimes();
  40. pageManager = new NavigationHandler(eventBus, rootFrameSet );
  41. }
  42. @Test
  43. public void verifyThatAPageWithOneOuterContainerIsCorrectlyLoaded() {
  44. thereIsNoActivePageIn(rootFrameSet);
  45. expectLoadingPlaceHolderToBeShown(rootFrameSet);
  46. expectAndCaptureLoadRequestFor(outerFrameSetId);
  47. expectPageToBeSetTo(rootFrameSet, outerFrameSet);
  48. thereIsNoActivePageIn(outerFrameSet);
  49. expectLoadingPlaceHolderToBeShown(outerFrameSet);
  50. expectAndCaptureLoadRequestFor(firstPageId);
  51. expectPageToBeSetTo(outerFrameSet, firstPage);
  52. replayAll();
  53. pageManager.registerPageLoader(outerFrameSetId, pageLoader);
  54. pageManager.registerPageLoader(firstPageId, pageLoader);
  55. requestNavigationTo(innerPlaceWithOuterFrame);
  56. pageLoadFinishes(outerFrameSetId, outerFrameSet);
  57. pageLoadFinishes(firstPageId, firstPage);
  58. verify(rootFrameSet, outerFrameSet, firstPage, pageLoader);
  59. }
  60. @Test
  61. public void innerPageCanCancelNavigation() {
  62. theRootPageIs(outerFrameSet);
  63. theOuterFrameSetIsShowing(firstPage);
  64. navigationRequestWillBeRefusedBy(firstPage);
  65. replayAll();
  66. requestNavigationTo(secondInnerPlaceWithSameOuterFrame);
  67. verify(outerFrameSet, firstPage);
  68. eventBus.assertNotFired(NavigationHandler.NavigationAgreed);
  69. }
  70. @Test
  71. public void navigationProceedsUponApprovalOfInnerPage() {
  72. theRootPageIs(outerFrameSet);
  73. theOuterFrameSetIsShowing(firstPage);
  74. expectAndAgreeToNavigationRequestionOn(firstPage);
  75. expectNavigate(outerFrameSet);
  76. expectLoadingPlaceHolderToBeShown(outerFrameSet);
  77. expectAndCaptureLoadRequestFor(secondPageId);
  78. expectShutdownCallTo(firstPage);
  79. expectPageToBeSetTo(outerFrameSet, secondPage);
  80. replayAll();
  81. pageManager.registerPageLoader(secondPageId, pageLoader);
  82. requestNavigationTo(secondInnerPlaceWithSameOuterFrame);
  83. pageLoadFinishes(secondPageId, secondPage);
  84. verify(outerFrameSet, firstPage, pageLoader);
  85. Assert.assertEquals(1, eventBus.getEventCount(NavigationHandler.NavigationAgreed));
  86. }
  87. @Test
  88. public void userCanNavigateToDifferentPageWhilePreviousRequestIsLoading() {
  89. thereIsNoActivePageIn(rootFrameSet);
  90. expectLoadingPlaceHolderToBeShownTwiceIn(rootFrameSet);
  91. expectAndCaptureLoadRequestFor(firstPageId);
  92. expectAndCaptureLoadRequestFor(secondPageId);
  93. expectPageToBeSetTo(rootFrameSet, secondPage);
  94. replayAll();
  95. pageManager.registerPageLoader(firstPageId, pageLoader);
  96. pageManager.registerPageLoader(secondPageId, pageLoader);
  97. requestNavigationTo(firstPlace);
  98. requestNavigationTo(secondPlace);
  99. pageLoadFinishes(secondPageId, secondPage);
  100. pageLoadFinishes(firstPageId, firstPage);
  101. verify(rootFrameSet, pageLoader);
  102. }
  103. private class MockPageState implements PageState {
  104. private final PageId pageId;
  105. private final List<PageId> viewPath;
  106. private MockPageState(PageId pageId, List<PageId> viewPath) {
  107. this.pageId = pageId;
  108. this.viewPath = viewPath;
  109. }
  110. public PageId getPageId() { return pageId; }
  111. public String serializeAsHistoryToken() { return null; }
  112. public List<PageId> getEnclosingFrames() { return viewPath; }
  113. }
  114. @Test
  115. public void duplicateNavigationRequestsAreIgnored() {
  116. thereIsNoActivePageIn(rootFrameSet);
  117. expectLoadingPlaceHolderToBeShown(rootFrameSet);
  118. expectAndCaptureLoadRequestFor(firstPageId);
  119. expectPageToBeSetTo(rootFrameSet, firstPage);
  120. replayAll();
  121. pageManager.registerPageLoader(firstPageId, pageLoader);
  122. requestNavigationTo(firstPlace);
  123. requestNavigationTo(firstPlace);
  124. pageLoadFinishes(firstPageId, firstPage);
  125. verify(rootFrameSet, pageLoader, firstPage);
  126. }
  127. private void theRootPageIs(Page page) {
  128. expect(rootFrameSet.getActivePage()).andReturn(page).anyTimes();
  129. }
  130. private void theOuterFrameSetIsShowing(Page page) {
  131. expect(outerFrameSet.getActivePage()).andReturn(page).anyTimes();
  132. }
  133. private void requestNavigationTo(PageState place) {
  134. eventBus.fireEvent(new NavigationEvent(NavigationHandler.NavigationRequested, place, null));
  135. }
  136. private void thereIsNoActivePageIn(Frame rootFrameSet) {
  137. expect(rootFrameSet.getActivePage()).andReturn(null).anyTimes();
  138. }
  139. private void expectShutdownCallTo(Page page) {
  140. page.shutdown();
  141. }
  142. private void expectNavigate(Frame frameSet) {
  143. expect(frameSet.navigate(isA(PageState.class))).andReturn(true);
  144. }
  145. private Map<PageId, Capture<AsyncCallback<Page>>> loadCallbacks = new HashMap();
  146. private void expectAndCaptureLoadRequestFor(PageId pageId) {
  147. Capture<AsyncCallback<Page>> capture = new Capture<AsyncCallback<Page>>();
  148. loadCallbacks.put(pageId, capture);
  149. pageLoader.load(eq(pageId), isA(PageState.class), capture(capture));
  150. expectLastCall().anyTimes();
  151. }
  152. private void pageLoadFinishes(PageId pageId, Page page) {
  153. loadCallbacks.get(pageId).getValue().onSuccess(page);
  154. }
  155. private void expectPageToBeSetTo(Frame frameSet, Page page) {
  156. frameSet.setActivePage(page);
  157. }
  158. private void expectLoadingPlaceHolderToBeShown(Frame frame) {
  159. expect(frame.showLoadingPlaceHolder(isA(PageId.class), isA(PageState.class)))
  160. .andReturn(new NullAsyncMonitor());
  161. }
  162. private void expectLoadingPlaceHolderToBeShownTwiceIn(Frame frame) {
  163. expect(frame.showLoadingPlaceHolder(isA(PageId.class), isA(PageState.class)))
  164. .andReturn(new NullAsyncMonitor())
  165. .times(2);
  166. }
  167. private void navigationRequestWillBeRefusedBy(Page page) {
  168. navigationRequestWillBeAnsweredBy(page, false);
  169. }
  170. private void expectAndAgreeToNavigationRequestionOn(Page page) {
  171. navigationRequestWillBeAnsweredBy(page, true);
  172. }
  173. private void navigationRequestWillBeAnsweredBy(Page page, final boolean allowed) {
  174. page.requestToNavigateAway(isA(PageState.class), isA(NavigationCallback.class));
  175. expectLastCall().andAnswer(new IAnswer<Void>() {
  176. @Override
  177. public Void answer() throws Throwable {
  178. if(allowed)
  179. ((NavigationCallback)(getCurrentArguments()[1])).onDecided(NavigationError.NONE);
  180. else
  181. ((NavigationCallback)(getCurrentArguments()[1])).onDecided(NavigationError.EXECUTION_ERROR);
  182. return null;
  183. }
  184. });
  185. }
  186. private void replayAll() {
  187. replay(rootFrameSet);
  188. replay(pageLoader);
  189. replay(outerFrameSet);
  190. replay(firstPage);
  191. replay(secondPage);
  192. }
  193. }