diff --git a/flow-server/src/main/java/com/vaadin/flow/router/internal/RouteUtil.java b/flow-server/src/main/java/com/vaadin/flow/router/internal/RouteUtil.java index 1cb07786235..436a98a4988 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/internal/RouteUtil.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/internal/RouteUtil.java @@ -623,10 +623,25 @@ public static boolean hasClientRouteWithAutoLayout( public static boolean hasServerRouteWithAutoLayout( AbstractRouteRegistry registry) { Collection layouts = registry.getLayouts(); - return registry.getRegisteredRoutes().stream() - .anyMatch(routeData -> !routeData.getParentLayouts().isEmpty() - && routeData.getParentLayouts().stream() - .anyMatch(layouts::contains)); + return registry.getRegisteredRoutes().stream().anyMatch(routeData -> { + String path; + if (routeData.getNavigationTarget() + .getAnnotation(Route.class) != null) { + path = getRoutePath(registry.getContext(), + routeData.getNavigationTarget()); + } else { + path = resolve(registry.getContext(), + routeData.getNavigationTarget()); + List parentRoutePrefixes = getRoutePrefixes( + routeData.getNavigationTarget(), null, path); + path = String.join("/", parentRoutePrefixes); + } + return RouteUtil + .isAutolayoutEnabled(routeData.getNavigationTarget(), path) + && registry.hasLayout(path) + && collectRouteParentLayouts(registry.getLayout(path)) + .stream().anyMatch(layouts::contains); + }); } /** diff --git a/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java b/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java index 29e1860d027..f70ccef1047 100644 --- a/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java +++ b/flow-server/src/test/java/com/vaadin/flow/server/VaadinServiceTest.java @@ -48,6 +48,7 @@ import com.vaadin.flow.internal.UsageStatistics; import com.vaadin.flow.internal.menu.MenuRegistry; import com.vaadin.flow.router.Layout; +import com.vaadin.flow.router.Route; import com.vaadin.flow.router.RouteConfiguration; import com.vaadin.flow.router.RouteData; import com.vaadin.flow.router.Router; @@ -76,6 +77,18 @@ public static class TestView extends Component { } + @Route("test") + @Tag("div") + public static class AnnotatedTestView extends Component { + + } + + @Route(value = "flow", autoLayout = false) + @Tag("div") + public static class OptOutAutoLayoutTestView extends Component { + + } + private class TestSessionDestroyListener implements SessionDestroyListener { int callCount = 0; @@ -160,8 +173,8 @@ class AutoLayout extends Component implements RouterLayout { VaadinServiceInitListener initListener = event -> { ApplicationRouteRegistry.getInstance(event.getSource().getContext()) .setLayout(AutoLayout.class); - RouteConfiguration.forApplicationScope().setRoute("test", - TestView.class, AutoLayout.class); + RouteConfiguration.forApplicationScope() + .setAnnotatedRoute(AnnotatedTestView.class); }; MockVaadinServletService service = new MockVaadinServletService(); runWithClientRoute("test", false, service, () -> { @@ -188,8 +201,6 @@ class AutoLayout extends Component implements RouterLayout { VaadinServiceInitListener initListener = event -> { ApplicationRouteRegistry.getInstance(event.getSource().getContext()) .setLayout(AutoLayout.class); - RouteConfiguration.forApplicationScope().setRoute("flow", - TestView.class); }; MockVaadinServletService service = new MockVaadinServletService(); runWithClientRoute("test", true, service, () -> { @@ -207,6 +218,40 @@ class AutoLayout extends Component implements RouterLayout { }); } + @Test + public void should_reported_auto_layout_routes_not_used() { + UsageStatistics.resetEntries(); + @Route(value = "not-in-auto-layout") + @Tag("div") + class LayoutTestView extends Component { + } + @Layout("layout") + class AutoLayout extends Component implements RouterLayout { + } + VaadinServiceInitListener initListener = event -> { + ApplicationRouteRegistry.getInstance(event.getSource().getContext()) + .setLayout(AutoLayout.class); + RouteConfiguration.forApplicationScope() + .setAnnotatedRoute(OptOutAutoLayoutTestView.class); + RouteConfiguration.forApplicationScope() + .setAnnotatedRoute(LayoutTestView.class); + }; + MockVaadinServletService service = new MockVaadinServletService(); + runWithClientRoute("test", false, service, () -> { + service.init(new MockInstantiator(initListener)); + + Assert.assertTrue(UsageStatistics.getEntries() + .anyMatch(e -> Constants.STATISTIC_HAS_AUTO_LAYOUT + .equals(e.getName()))); + Assert.assertFalse(UsageStatistics.getEntries().anyMatch( + e -> Constants.STATISTIC_HAS_SERVER_ROUTE_WITH_AUTO_LAYOUT + .equals(e.getName()))); + Assert.assertFalse(UsageStatistics.getEntries().anyMatch( + e -> Constants.STATISTIC_HAS_CLIENT_ROUTE_WITH_AUTO_LAYOUT + .equals(e.getName()))); + }); + } + private void runWithClientRoute(String route, boolean flowLayout, MockVaadinServletService service, Runnable runnable) { try (MockedStatic menuRegistry = Mockito