Skip to content

Commit

Permalink
fix: Client route autolayout should have parent layouts chain (#20511)
Browse files Browse the repository at this point in the history
When having a client route for
server layout  the layout
parent routes should be collected.

Fixes #20505
  • Loading branch information
caalador authored Nov 19, 2024
1 parent 23093d7 commit bd8c796
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -58,15 +59,16 @@ public NavigationState resolve(ResolveRequest request) {
: "/" + clientPath);
if (viewInfo != null && viewInfo.flowLayout()) {

Class<? extends Component> layout = (Class<? extends Component>) registry
Class<? extends RouterLayout> 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<? extends Component>) layout, RouteUtil
.getParentLayoutsForNonRouteTarget(layout));
navigationResult = new NavigationRouteTarget(
navigationResult.getPath(), target,
Collections.emptyMap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -149,6 +145,34 @@ public void clientRouteRequest_getDefinedLayout() {
}
}

@Test
public void clientRouteRequest_getDefinedLayoutAndParentLayouts() {
String path = "route";

router.getRegistry().setLayout(DefaultWithParentLayout.class);

try (MockedStatic<MenuRegistry> 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);
Expand Down Expand Up @@ -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<? extends Component> resolveNavigationTarget(String path) {
return resolveNavigationState(path).getNavigationTarget();
}
Expand Down

0 comments on commit bd8c796

Please sign in to comment.