JavaScriptBootstrapUI extends UI { @Override public void navigate(String pathname, QueryParameters queryParameters) { Location location = new Location(pathname, queryParameters); if (Boolean.TRUE.equals(getSession().getAttribute(SERVER_ROUTING))) { renderViewForRoute(location, NavigationTrigger.UI_NAVIGATE); } else { if (navigationInProgress || getInternals().hasLastHandledLocation() && sameLocation(getInternals().getLastHandledLocation(), location)) { return; } navigationInProgress = true; Optional<NavigationState> navigationState = getInternals() .getRouter().resolveNavigationTarget(location); if (navigationState.isPresent()) { handleNavigation(location, navigationState.get(), NavigationTrigger.UI_NAVIGATE); if (getForwardToClientUrl() != null) { navigationInProgress = false; navigateToClient(getForwardToClientUrl()); return; } } else { navigateToClient(location.getPathWithQueryParameters()); } navigationInProgress = false; } } JavaScriptBootstrapUI(); @Override Stream<Component> getChildren(); String getForwardToClientUrl(); @ClientCallable void connectClient(String clientElementTag, String clientElementId,
            String flowRoute); @ClientCallable void leaveNavigation(String route); @Override void navigate(String pathname, QueryParameters queryParameters); static final String SERVER_ROUTING; }
@Test public void should_clearLastHandledNavigation_when_navigateToOtherViews() { Mockito.when(mocks.getSession().getAttribute(SERVER_ROUTING)) .thenReturn(Boolean.TRUE); ui.navigate("clean"); assertFalse("Should clear lastHandledNavigation after finishing", ui.getInternals().hasLastHandledLocation()); ui.navigate("product"); assertFalse("Should clear lastHandledNavigation after finishing", ui.getInternals().hasLastHandledLocation()); }
@Test public void should_invoke_clientRoute_when_navigationHasNotBeenStarted() { ui = Mockito.spy(ui); Page page = mockPage(); ArgumentCaptor<String> execJs = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> execArg = ArgumentCaptor.forClass(String.class); ui.navigate("whatever"); Mockito.verify(page).executeJs(execJs.capture(), execArg.capture()); assertEquals(CLIENT_NAVIGATE_TO, execJs.getValue()); assertEquals("whatever", execArg.getValue()); }
@Test public void should_update_pushState_when_navigationHasBeenAlreadyStarted() { ui = Mockito.spy(ui); Page page = mockPage(); UIInternals internals = mockUIInternals(); Mockito.when(internals.hasLastHandledLocation()).thenReturn(true); Location lastLocation = new Location("clean"); Mockito.when(internals.getLastHandledLocation()).thenReturn(lastLocation); StateTree stateTree = Mockito.mock(StateTree.class); Mockito.when(internals.getStateTree()).thenReturn(stateTree); Mockito.when(internals.getTitle()).thenReturn(""); StateNode stateNode = BasicElementStateProvider.createStateNode("foo-element"); Mockito.when(stateTree.getRootNode()).thenReturn(stateNode); ArgumentCaptor<String> execJs = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> execArg = ArgumentCaptor.forClass(String.class); ui.navigate("clean/1"); Mockito.verify(page).executeJs(execJs.capture(), execArg.capture()); assertEquals(CLIENT_PUSHSTATE_TO, execJs.getValue()); final List<String> execValues = execArg.getAllValues(); assertEquals(2, execValues.size()); assertNull(execValues.get(0)); assertEquals("clean/1", execArg.getValue()); }
@Test public void should_not_notify_clientRoute_when_navigatingToTheSame() { ui = Mockito.spy(ui); Page page = mockPage(); UIInternals internals = mockUIInternals(); Mockito.when(internals.hasLastHandledLocation()).thenReturn(true); Location lastLocation = new Location("clean"); Mockito.when(internals.getLastHandledLocation()).thenReturn(lastLocation); ui.navigate("clean/"); Mockito.verify(page, Mockito.never()).executeJs(Mockito.anyString(), Mockito.anyString()); }
@Test public void should_updatePageTitle_when_serverNavigation() { ui.navigate("empty"); assertNull(ui.getInternals().getTitle()); ui.navigate("product"); assertEquals("my-product", ui.getInternals().getTitle()); }
@Test public void should_removeTitle_when_noAppShellTitle() { ui.navigate("empty"); assertNull(ui.getInternals().getTitle()); ui.navigate("dirty"); assertEquals("", ui.getInternals().getTitle()); }
@Test public void should_restoreAppShellTitle() { AppShellRegistry registry = new AppShellRegistry(); registry.setShell(AppShell.class); mocks.setAppShellRegistry(registry); registry.modifyIndexHtml(Document.createShell(""), mocks.createRequest(mocks, "/foo")); ui.navigate("empty"); assertNull(ui.getInternals().getTitle()); ui.navigate("dirty"); assertEquals("app-shell-title", ui.getInternals().getTitle()); }
@Test public void should_restoreIndexHtmlTitle() { AppShellRegistry registry = new AppShellRegistry(); mocks.setAppShellRegistry(registry); VaadinRequest request = mocks.createRequest(mocks, "/foo"); Document document = Document.createShell(""); org.jsoup.nodes.Element title = document.createElement("title"); title.appendText("index-html-title"); document.head().appendChild(title); registry.modifyIndexHtml(document, request); ui.navigate("empty"); assertNull(ui.getInternals().getTitle()); ui.navigate("dirty"); assertEquals("index-html-title", ui.getInternals().getTitle()); }
@Test public void should_caught_and_show_exception_during_navigation_in_internalServerError() throws InvalidRouteConfigurationException { String location = "exception"; String validationMessage = "Failed on an exception"; Mockito.when(mocks.getSession().getAttribute(SERVER_ROUTING)) .thenReturn(Boolean.TRUE); ui.navigate(location); String errorMessage = String.format( "There was an exception while trying to navigate to '%s' with the exception message '%s'", location, validationMessage); assertExceptionComponent(InternalServerError.class, errorMessage); }