Skip to content

Commit

Permalink
fix: update document title for client route (#20184) (#20192)
Browse files Browse the repository at this point in the history
* chore: update document title for client route

Updates document title for client view with flow layout based on `ViewConfig.title` and when not overridden by server's `HasDynamicTitle`.

RelatedTo: #20107

* chore: added tests

* chore: renamed test method

---------

Co-authored-by: Tomi Virtanen <[email protected]>
Co-authored-by: Mikhail Shabarov <[email protected]>
  • Loading branch information
3 people authored Oct 9, 2024
1 parent 58172fe commit 7ea97e1
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import com.vaadin.flow.server.RouteRegistry;
import com.vaadin.flow.server.VaadinSession;
import com.vaadin.flow.internal.menu.MenuRegistry;
import com.vaadin.flow.server.menu.AvailableViewInfo;

/**
* Base class for navigation handlers that target a navigation state.
Expand Down Expand Up @@ -274,7 +275,7 @@ public int handle(NavigationEvent event) {
new AfterNavigationEvent(locationChangeEvent, parameters),
afterNavigationHandlers);

updatePageTitle(event, componentInstance);
updatePageTitle(event, componentInstance, route);

return statusCode;
}
Expand Down Expand Up @@ -953,7 +954,7 @@ private static void checkForDuplicates(
}

private static void updatePageTitle(NavigationEvent navigationEvent,
Component routeTarget) {
Component routeTarget, String route) {

Supplier<String> lookForTitleInTarget = () -> lookForTitleInTarget(
routeTarget).map(PageTitle::value).orElse("");
Expand All @@ -964,7 +965,11 @@ private static void updatePageTitle(NavigationEvent navigationEvent,
.filter(HasDynamicTitle.class::isInstance)
.map(tc -> ((HasDynamicTitle) tc).getPageTitle())
.filter(Objects::nonNull).findFirst()
.orElseGet(lookForTitleInTarget);
.orElseGet(() -> Optional
.ofNullable(
MenuRegistry.getClientRoutes(true).get(route))
.map(AvailableViewInfo::title)
.orElseGet(lookForTitleInTarget));

navigationEvent.getUI().getPage().setTitle(title);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import com.vaadin.flow.router.AfterNavigationObserver;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.Layout;
import com.vaadin.flow.router.Location;
import com.vaadin.flow.router.NavigationEvent;
import com.vaadin.flow.router.NavigationState;
Expand Down Expand Up @@ -1029,4 +1030,81 @@ public DeploymentConfiguration getConfiguration() {
Assert.assertTrue(UsageStatistics.getEntries().anyMatch(entry -> entry
.getName().equals(Constants.STATISTICS_FLOW_ROUTER)));
}

@Layout
@Tag("div")
public static class MainLayout extends Component implements RouterLayout {
private final Element element = new Element("div");

@Override
public Element getElement() {
return element;
}
}

@Test
public void handle_clientNavigationToFlowLayout_setTitleFromClientRoute() {
testClientNavigationTitle("Client", true);
}

@Test
public void handle_clientNavigation_doNotSetTitleFromClientRoute() {
testClientNavigationTitle(null, false);
}

private void testClientNavigationTitle(String expectedDocumentTitle,
boolean clientRouteHasFlowLayout) {
UI ui = createTestClientNavigationTitleUIForTitleTests();
try (MockedStatic<MenuRegistry> menuRegistry = Mockito
.mockStatic(MenuRegistry.class, Mockito.CALLS_REAL_METHODS)) {

menuRegistry.when(() -> MenuRegistry.getClientRoutes(true))
.thenReturn(Collections.singletonMap("/client-route",
new AvailableViewInfo("Client", null, false,
"/client-route", false, false, null, null,
null, clientRouteHasFlowLayout)));

NavigationEvent event = new NavigationEvent(
new Router(new TestRouteRegistry()),
new Location("client-route"), ui,
NavigationTrigger.UI_NAVIGATE);
NavigationStateRenderer renderer = new NavigationStateRenderer(
new NavigationStateBuilder(router)
.withTarget(MainLayout.class)
.withPath("client-route").build());

renderer.handle(event);

Assert.assertNotNull(ui.getPage());
if (expectedDocumentTitle == null) {
Mockito.verify(ui.getPage(), Mockito.never())
.setTitle("Client");
} else {
Mockito.verify(ui.getPage()).setTitle(expectedDocumentTitle);
}
}
}

private UI createTestClientNavigationTitleUIForTitleTests() {
DeploymentConfiguration configuration = Mockito
.mock(DeploymentConfiguration.class);
MockVaadinServletService service = new MockVaadinServletService(
configuration);
AlwaysLockedVaadinSession session = new AlwaysLockedVaadinSession(
service) {
@Override
public DeploymentConfiguration getConfiguration() {
return configuration;
}
};
Mockito.when(configuration.isReactEnabled()).thenReturn(false);
Page page = Mockito.mock(Page.class);
Mockito.when(page.getHistory()).thenReturn(Mockito.mock(History.class));
return new MockUI(session) {
@Override
public Page getPage() {
return page;
}
};
}
}

0 comments on commit 7ea97e1

Please sign in to comment.