Skip to content

Commit

Permalink
[web] Ensure handleNavigationMessage can receive null arguments. (flu…
Browse files Browse the repository at this point in the history
  • Loading branch information
ditman committed May 26, 2021
1 parent 94a40bc commit 052471f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
9 changes: 6 additions & 3 deletions lib/web_ui/lib/src/engine/window.dart
Expand Up @@ -113,21 +113,24 @@ 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();
return true;
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;
Expand Down
27 changes: 26 additions & 1 deletion lib/web_ui/test/window_test.dart
Expand Up @@ -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',
Expand All @@ -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
Expand All @@ -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(
Expand Down

0 comments on commit 052471f

Please sign in to comment.