Skip to content

Commit

Permalink
fix: consider layout prefixes when checking for route and alias paths (
Browse files Browse the repository at this point in the history
  • Loading branch information
vaadin-bot authored Oct 3, 2024
1 parent 1c8243b commit 46043b5
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,27 @@ private void checkForConflictingAnnotations(VaadinContext context,

RouteAlias[] aliases = route.getAnnotationsByType(RouteAlias.class);
if (aliases.length > 0) {
Route routeAnnotation = route.getAnnotation(Route.class);
String routePath = RouteUtil.getRoutePath(context, route);
Map<String, Long> stats = Arrays.stream(aliases)
.map(RouteAlias::value).collect(Collectors.groupingBy(
Function.identity(), Collectors.counting()));
if (stats.containsKey(routeAnnotation.value())) {
.map(ann -> RouteUtil.getRouteAliasPath(route, ann))
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
if (stats.containsKey(routePath)) {
throw new InvalidRouteConfigurationException(String.format(
"'%s' declares '@%s' and '@%s' with the same path '%s'",
"'%s' declares '@%s' and '@%s' with the same path '%s'. "
+ "Make sure paths are different by checking annotation values "
+ "and prefixes defined by layouts",
route.getCanonicalName(), Route.class.getSimpleName(),
RouteAlias.class.getSimpleName(),
routeAnnotation.value()));
RouteAlias.class.getSimpleName(), routePath));
}
String repeatedAliases = stats.entrySet().stream()
.filter(e -> e.getValue() > 1).map(Map.Entry::getKey)
.collect(Collectors.joining(", "));
if (!repeatedAliases.isEmpty()) {
throw new InvalidRouteConfigurationException(String.format(
"'%s' declares multiple '@%s' with same paths: %s.",
"'%s' declares multiple '@%s' with same paths: %s."
+ "Make sure paths are different by checking annotation values "
+ "and prefixes defined by layouts.",
route.getCanonicalName(),
RouteAlias.class.getSimpleName(), repeatedAliases));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,27 @@

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.router.ParentLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;
import com.vaadin.flow.router.RoutePrefix;
import com.vaadin.flow.router.RouterLayout;
import com.vaadin.flow.server.InvalidRouteConfigurationException;
import com.vaadin.flow.server.InvalidRouteLayoutConfigurationException;
import com.vaadin.flow.server.VaadinContext;

public class AbstractRouteRegistryInitializerTest {

private AbstractRouteRegistryInitializer initializer = new AbstractRouteRegistryInitializer() {

};

VaadinContext context = Mockito.mock(VaadinContext.class);

@Tag(Tag.DIV)
public static class TestParentLayout extends Component
implements RouterLayout {
Expand Down Expand Up @@ -64,6 +69,43 @@ public static class RouteAndAliasWithSamePath extends Component {

}

@Tag(Tag.DIV)
@RoutePrefix("parent")
public static class PrefixedParentLayout extends Component
implements RouterLayout {
}

@Tag(Tag.DIV)
@RoutePrefix("nested")
@ParentLayout(PrefixedParentLayout.class)
public static class NestedPrefixedParentLayout extends Component
implements RouterLayout {
}

@Tag(Tag.DIV)
@Route("foo")
@RouteAlias(value = "foo", layout = PrefixedParentLayout.class)
public static class RouteAndAliasWithSamePathDifferentLayoutPrefix
extends Component {

}

@Tag(Tag.DIV)
@Route(value = "foo", layout = PrefixedParentLayout.class)
@RouteAlias(value = "foo", layout = PrefixedParentLayout.class)
public static class RouteAndAliasWithSamePathSameLayoutPrefix
extends Component {

}

@Tag(Tag.DIV)
@Route(value = "foo", layout = NestedPrefixedParentLayout.class)
@RouteAlias(value = "foo", layout = NestedPrefixedParentLayout.class)
public static class RouteAndAliasWithSamePathSameNestedLayoutPrefix
extends Component {

}

@Tag(Tag.DIV)
@Route("foo")
@RouteAlias("bar")
Expand All @@ -77,15 +119,15 @@ public static class AliasesWithSamePath extends Component {

@Test(expected = InvalidRouteLayoutConfigurationException.class)
public void routeAndParentLayout_notRouterLayout_throws() {
initializer.validateRouteClasses(null,
initializer.validateRouteClasses(context,
Stream.of(RouteAndParentLayout.class));
}

@Test
public void validateRouteClasses_samePathForRouteAndAlias_throws() {
InvalidRouteConfigurationException exception = Assert.assertThrows(
InvalidRouteConfigurationException.class,
() -> initializer.validateRouteClasses(null,
() -> initializer.validateRouteClasses(context,
Stream.of(RouteAndAliasWithSamePath.class)));
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
Route.class));
Expand All @@ -99,7 +141,7 @@ public void validateRouteClasses_samePathForRouteAndAlias_throws() {
public void validateRouteClasses_samePathForRepeatableAlias_throws() {
InvalidRouteConfigurationException exception = Assert.assertThrows(
InvalidRouteConfigurationException.class,
() -> initializer.validateRouteClasses(null,
() -> initializer.validateRouteClasses(context,
Stream.of(AliasesWithSamePath.class)));
Assert.assertFalse(containsQuotedAnnotationName(exception.getMessage(),
Route.class));
Expand All @@ -112,10 +154,49 @@ public void validateRouteClasses_samePathForRepeatableAlias_throws() {
Assert.assertFalse(exception.getMessage().contains("hey"));
}

@Test
public void validateRouteClasses_samePathForRouteAndAlias_sameLayoutPrefix_throws() {
InvalidRouteConfigurationException exception = Assert.assertThrows(
InvalidRouteConfigurationException.class,
() -> initializer.validateRouteClasses(context, Stream
.of(RouteAndAliasWithSamePathSameLayoutPrefix.class)));
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
Route.class));
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
RouteAlias.class));
Assert.assertTrue(exception.getMessage().contains("same path"));
Assert.assertTrue(exception.getMessage().contains("foo"));
}

@Test
public void validateRouteClasses_samePathForRouteAndAlias_sameNestedLayoutPrefix_throws() {
InvalidRouteConfigurationException exception = Assert.assertThrows(
InvalidRouteConfigurationException.class,
() -> initializer.validateRouteClasses(context, Stream.of(
RouteAndAliasWithSamePathSameNestedLayoutPrefix.class)));
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
Route.class));
Assert.assertTrue(containsQuotedAnnotationName(exception.getMessage(),
RouteAlias.class));
Assert.assertTrue(exception.getMessage().contains("same path"));
Assert.assertTrue(exception.getMessage().contains("foo"));
}

@Test
public void validateRouteClasses_samePathForRouteAndAlias_differentLayoutPrefix_doNotThrow() {
Set<Class<? extends Component>> classes = initializer
.validateRouteClasses(context, Stream.of(
RouteAndAliasWithSamePathDifferentLayoutPrefix.class));
Assert.assertEquals(1, classes.size());
Assert.assertEquals(
RouteAndAliasWithSamePathDifferentLayoutPrefix.class,
classes.iterator().next());
}

@Test
public void routeAndParentLayout_routerLayout_returnsValidatedClass() {
Set<Class<? extends Component>> classes = initializer
.validateRouteClasses(null,
.validateRouteClasses(context,
Stream.of(RouteAndParentRouterLayout.class));
Assert.assertEquals(1, classes.size());
Assert.assertEquals(RouteAndParentRouterLayout.class,
Expand Down

0 comments on commit 46043b5

Please sign in to comment.