[web] Don't allow empty initial route (#17936)

This commit is contained in:
Mouad Debbar 2020-04-27 13:54:07 -07:00 committed by GitHub
parent 3b0e4153b7
commit aa00d50396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 5 deletions

View File

@ -73,10 +73,13 @@ class HashLocationStrategy extends LocationStrategy {
// and if it is empty then it will stay empty
String path = _platformLocation.hash ?? '';
assert(path.isEmpty || path.startsWith('#'));
// Dart will complain if a call to substring is
// executed with a position value that exceeds the
// length of string.
return path.isEmpty ? path : path.substring(1);
// We don't want to return an empty string as a path. Instead we default to "/".
if (path.isEmpty || path == '#') {
return '/';
}
// At this point, we know [path] starts with "#" and isn't empty.
return path.substring(1);
}
@override

View File

@ -7,6 +7,7 @@
// TODO(nurhan): https://github.com/flutter/flutter/issues/51169
import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';
import 'package:test/test.dart';
@ -28,7 +29,7 @@ const MethodCodec codec = JSONMethodCodec();
void emptyCallback(ByteData date) {}
void main() {
group('BrowserHistory', () {
group('$BrowserHistory', () {
final PlatformMessagesSpy spy = PlatformMessagesSpy();
setUp(() {
@ -229,6 +230,41 @@ void main() {
// TODO(nurhan): https://github.com/flutter/flutter/issues/50836
skip: browserEngine == BrowserEngine.edge);
});
group('$HashLocationStrategy', () {
TestPlatformLocation location;
setUp(() {
location = TestPlatformLocation();
});
tearDown(() {
location = null;
});
test('leading slash is optional', () {
final HashLocationStrategy strategy = HashLocationStrategy(location);
location.hash = '#/';
expect(strategy.path, '/');
location.hash = '#/foo';
expect(strategy.path, '/foo');
location.hash = '#foo';
expect(strategy.path, 'foo');
});
test('path should not be empty', () {
final HashLocationStrategy strategy = HashLocationStrategy(location);
location.hash = '';
expect(strategy.path, '/');
location.hash = '#';
expect(strategy.path, '/');
});
});
}
void pushRoute(String routeName) {
@ -276,3 +312,38 @@ Future<void> systemNavigatorPop() {
);
return completer.future;
}
/// A mock implementation of [PlatformLocation] that doesn't access the browser.
class TestPlatformLocation extends PlatformLocation {
String pathname;
String search;
String hash;
void onPopState(html.EventListener fn) {
throw UnimplementedError();
}
void offPopState(html.EventListener fn) {
throw UnimplementedError();
}
void onHashChange(html.EventListener fn) {
throw UnimplementedError();
}
void offHashChange(html.EventListener fn) {
throw UnimplementedError();
}
void pushState(dynamic state, String title, String url) {
throw UnimplementedError();
}
void replaceState(dynamic state, String title, String url) {
throw UnimplementedError();
}
void back() {
throw UnimplementedError();
}
}