[web] Ensure handleNavigationMessage can receive null arguments. (flutter/engine#26406)

This commit is contained in:
David Iglesias 2021-05-25 18:09:01 -07:00 committed by GitHub
parent 00e9f108c1
commit 4316a6b2ed
2 changed files with 32 additions and 4 deletions

View File

@ -113,7 +113,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
Future<bool> handleNavigationMessage(ByteData? data) async {
final MethodCall decoded = JSONMethodCodec().decodeMethodCall(data);
final Map<String, dynamic> arguments = decoded.arguments;
final Map<String, dynamic>? arguments = decoded.arguments;
switch (decoded.method) {
case 'selectMultiEntryHistory':
await _useMultiEntryBrowserHistory();
@ -121,13 +121,16 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
case 'selectSingleEntryHistory':
await _useSingleEntryBrowserHistory();
return true;
// the following cases assert that arguments are not null
case 'routeUpdated': // deprecated
assert(arguments != null);
await _useSingleEntryBrowserHistory();
browserHistory.setRouteName(arguments['routeName']);
browserHistory.setRouteName(arguments!['routeName']);
return true;
case 'routeInformationUpdated':
assert(arguments != null);
browserHistory.setRouteName(
arguments['location'],
arguments!['location'],
state: arguments['state'],
);
return true;

View File

@ -82,7 +82,7 @@ void testMain() {
), useSingle: false);
expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());
Future<void> check<T>(String method, Map<String, Object?> arguments) async {
Future<void> check<T>(String method, Object? arguments) async {
callback = Completer<void>();
window.sendPlatformMessage(
'flutter/navigation',
@ -93,6 +93,10 @@ void testMain() {
expect(window.browserHistory, isA<T>());
}
// These may be initialized as `null`
// See https://github.com/flutter/flutter/issues/83158#issuecomment-847483010
await check<SingleEntryBrowserHistory>('selectSingleEntryHistory', null); // -> single
await check<MultiEntriesBrowserHistory>('selectMultiEntryHistory', null); // -> multi
await check<SingleEntryBrowserHistory>('selectSingleEntryHistory', <String, dynamic>{}); // -> single
await check<MultiEntriesBrowserHistory>('selectMultiEntryHistory', <String, dynamic>{}); // -> multi
await check<SingleEntryBrowserHistory>('routeUpdated', <String, dynamic>{'routeName': '/bar'}); // -> single
@ -101,6 +105,27 @@ void testMain() {
await check<MultiEntriesBrowserHistory>('routeInformationUpdated', <String, dynamic>{'location': '/bar'}); // does not change mode
});
test('handleNavigationMessage throws for route update methods called with null arguments',
() async {
expect(() async {
await window.handleNavigationMessage(
JSONMethodCodec().encodeMethodCall(MethodCall(
'routeUpdated',
null, // boom
))
);
}, throwsAssertionError);
expect(() async {
await window.handleNavigationMessage(
JSONMethodCodec().encodeMethodCall(MethodCall(
'routeInformationUpdated',
null, // boom
))
);
}, throwsAssertionError);
});
test('should not throw when using nav1 and nav2 together',
() async {
await window.debugInitializeHistory(TestUrlStrategy.fromEntry(