Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/go_router/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,14 @@ class RouteConfiguration {

/// Normalizes a URI by ensuring it has a valid path and removing trailing slashes.
static Uri normalizeUri(Uri uri) {
if (uri.hasEmptyPath) {
return uri.replace(path: '/');
} else if (uri.path.length > 1 && uri.path.endsWith('/')) {
return uri.replace(path: uri.path.substring(0, uri.path.length - 1));
String path = uri.path;
if (!path.startsWith('/')) {
path = '/$path';
}
return uri;
if (path.length > 1 && path.endsWith('/')) {
path = path.substring(0, path.length - 1);
}
return uri.replace(path: path);
Comment thread
chunhtai marked this conversation as resolved.
}

/// The global key for top level navigator.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
changelog: |
- Fixes an assertion failure when navigating to URLs with hash fragments missing a leading slash.
version: patch
37 changes: 37 additions & 0 deletions packages/go_router/test/configuration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,43 @@ void main() {
);
},
);

group('normalizeUri', () {
test('adds leading slash if missing', () {
expect(
RouteConfiguration.normalizeUri(Uri.parse('foo')).path,
'/foo',
);
});

test('handles empty path', () {
expect(
RouteConfiguration.normalizeUri(Uri.parse('')).path,
'/',
);
});

test('removes trailing slash if length > 1', () {
expect(
RouteConfiguration.normalizeUri(Uri.parse('/foo/')).path,
'/foo',
);
});

test('does not remove slash for root root', () {
expect(
RouteConfiguration.normalizeUri(Uri.parse('/')).path,
'/',
);
});

test('preserves query parameters and fragments', () {
final Uri uri = RouteConfiguration.normalizeUri(Uri.parse('foo?a=b#c'));
expect(uri.path, '/foo');
expect(uri.queryParameters['a'], 'b');
expect(uri.fragment, 'c');
});
});
});
}

Expand Down
29 changes: 29 additions & 0 deletions packages/go_router/test/parser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -662,4 +662,33 @@ void main() {
expect(match.matches, hasLength(1));
expect(matchesObj.error, isNull);
});

testWidgets(
'GoRouteInformationParser can handle path without leading slash',
(WidgetTester tester) async {
final routes = <RouteBase>[
GoRoute(
path: '/abc',
builder: (_, __) => const Placeholder(),
),
];
final GoRouteInformationParser parser = await createParser(
tester,
routes: routes,
redirectLimit: 100,
redirect: (_, __) => null,
);

final BuildContext context = tester.element(find.byType(Router<Object>));

final RouteMatchList matchesObj = await parser
.parseRouteInformationWithDependencies(
createRouteInformation('abc'),
context,
);
final List<RouteMatchBase> matches = matchesObj.matches;
expect(matches.length, 1);
expect(matchesObj.uri.toString(), '/abc');
},
);
}
Loading