diff --git a/flow-server/src/main/java/com/vaadin/flow/router/internal/DefaultRouteResolver.java b/flow-server/src/main/java/com/vaadin/flow/router/internal/DefaultRouteResolver.java index cfd7c2e7885..63944c2a540 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/internal/DefaultRouteResolver.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/internal/DefaultRouteResolver.java @@ -25,6 +25,7 @@ import com.vaadin.flow.router.NavigationStateBuilder; import com.vaadin.flow.router.NotFoundException; import com.vaadin.flow.router.RouteResolver; +import com.vaadin.flow.router.RouterLayout; import com.vaadin.flow.server.RouteRegistry; import com.vaadin.flow.internal.menu.MenuRegistry; import com.vaadin.flow.server.menu.AvailableViewInfo; @@ -58,15 +59,16 @@ public NavigationState resolve(ResolveRequest request) { : "/" + clientPath); if (viewInfo != null && viewInfo.flowLayout()) { - Class layout = (Class) registry + Class layout = registry .getLayout(path); if (layout == null) { throw new NotFoundException( "No layout for client path '%s'" .formatted(path)); } - RouteTarget target = new RouteTarget(layout, - Collections.emptyList()); + RouteTarget target = new RouteTarget( + (Class) layout, RouteUtil + .getParentLayoutsForNonRouteTarget(layout)); navigationResult = new NavigationRouteTarget( navigationResult.getPath(), target, Collections.emptyMap()); diff --git a/flow-server/src/test/java/com/vaadin/flow/router/DefaultRouteResolverTest.java b/flow-server/src/test/java/com/vaadin/flow/router/DefaultRouteResolverTest.java index 999a7dc4fe1..8c576e535be 100644 --- a/flow-server/src/test/java/com/vaadin/flow/router/DefaultRouteResolverTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/router/DefaultRouteResolverTest.java @@ -15,16 +15,13 @@ */ package com.vaadin.flow.router; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.fasterxml.jackson.annotation.JsonProperty; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -41,7 +38,6 @@ import com.vaadin.flow.server.RouteRegistry; import com.vaadin.flow.internal.menu.MenuRegistry; import com.vaadin.flow.server.menu.AvailableViewInfo; -import com.vaadin.flow.server.menu.RouteParamType; public class DefaultRouteResolverTest extends RoutingTestBase { @@ -149,6 +145,34 @@ public void clientRouteRequest_getDefinedLayout() { } } + @Test + public void clientRouteRequest_getDefinedLayoutAndParentLayouts() { + String path = "route"; + + router.getRegistry().setLayout(DefaultWithParentLayout.class); + + try (MockedStatic menuRegistry = Mockito + .mockStatic(MenuRegistry.class)) { + menuRegistry.when(() -> MenuRegistry.getClientRoutes(false)) + .thenReturn(Collections.singletonMap("/route", + new AvailableViewInfo("", null, false, "/route", + false, false, null, null, null, true))); + NavigationState greeting = resolveNavigationState(path); + Assert.assertEquals( + "Layout should be returned for a non server route when matching @Layout exists", + DefaultWithParentLayout.class, + greeting.getRouteTarget().getTarget()); + Assert.assertEquals( + "@ParentLayout annotation should be followed. @Layout class should not be in parent layout list.", + 1, greeting.getRouteTarget().getParentLayouts().size()); + Assert.assertEquals( + "@ParentLayout annotation should be followed. @Layout class should not be in parent layout list.", + DefaultParentLayout.class, + greeting.getRouteTarget().getParentLayouts().get(0)); + + } + } + @Test public void clientRouteRequest_withRouteParameters_getDefinedLayout() { router.getRegistry().setLayout(DefaultLayout.class); @@ -308,6 +332,18 @@ private static class DefaultLayout extends Component implements RouterLayout { } + @Tag("div") + @Layout + @ParentLayout(DefaultParentLayout.class) + private static class DefaultWithParentLayout extends Component + implements RouterLayout { + } + + @Tag("div") + private static class DefaultParentLayout extends Component + implements RouterLayout { + } + private Class resolveNavigationTarget(String path) { return resolveNavigationState(path).getNavigationTarget(); }