// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@TestOn('!safari')
// TODO(mdebbar): https://github.com/flutter/flutter/issues/51169

import 'dart:async';

import 'package:quiver/testing/async.dart';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart' show DomEventListener, window;
import 'package:ui/src/engine/browser_detection.dart';
import 'package:ui/src/engine/navigation.dart';
import 'package:ui/src/engine/services.dart';
import 'package:ui/src/engine/test_embedding.dart';

import '../spy.dart';

Map<String, dynamic> _wrapOriginState(dynamic state) {
  return <String, dynamic>{'origin': true, 'state': state};
}

Map<String, dynamic> _tagStateWithSerialCount(dynamic state, int serialCount) {
  return <String, dynamic> {
    'serialCount': serialCount,
    'state': state,
  };
}

const Map<String, bool> originState = <String, bool>{'origin': true};
const Map<String, bool> flutterState = <String, bool>{'flutter': true};

const MethodCodec codec = JSONMethodCodec();

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  test('createHistoryForExistingState', () {
    TestUrlStrategy strategy;
    BrowserHistory history;

    // No url strategy.
    history = createHistoryForExistingState(null);
    expect(history, isA<MultiEntriesBrowserHistory>());
    expect(history.urlStrategy, isNull);

    // Random history state.
    strategy = TestUrlStrategy.fromEntry(
      const TestHistoryEntry(<dynamic, dynamic>{'foo': 123}, null, '/'),
    );
    history = createHistoryForExistingState(strategy);
    expect(history, isA<MultiEntriesBrowserHistory>());
    expect(history.urlStrategy, strategy);

    // Multi-entry history state.
    final Map<dynamic, dynamic> state = <dynamic, dynamic>{
      'serialCount': 1,
      'state': <dynamic, dynamic>{'foo': 123},
    };
    strategy = TestUrlStrategy.fromEntry(TestHistoryEntry(state, null, '/'));
    history = createHistoryForExistingState(strategy);
    expect(history, isA<MultiEntriesBrowserHistory>());
    expect(history.urlStrategy, strategy);

    // Single-entry history "origin" state.
    strategy = TestUrlStrategy.fromEntry(
      const TestHistoryEntry(<dynamic, dynamic>{'origin': true}, null, '/'),
    );
    history = createHistoryForExistingState(strategy);
    expect(history, isA<SingleEntryBrowserHistory>());
    expect(history.urlStrategy, strategy);

    // Single-entry history "flutter" state.
    strategy = TestUrlStrategy.fromEntry(
      const TestHistoryEntry(<dynamic, dynamic>{'flutter': true}, null, '/'),
    );
    history = createHistoryForExistingState(strategy);
    expect(history, isA<SingleEntryBrowserHistory>());
    expect(history.urlStrategy, strategy);
  });

  group('$SingleEntryBrowserHistory', () {
    final PlatformMessagesSpy spy = PlatformMessagesSpy();

    setUp(() async {
      spy.setUp();
    });

    tearDown(() async {
      spy.tearDown();
      await window.resetHistory();
    });

    test('basic setup works', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/initial'),
      );
      await window.debugInitializeHistory(strategy, useSingle: true);

      // There should be two entries: origin and flutter.
      expect(strategy.history, hasLength(2));

      // The origin entry is set up but its path should remain unchanged.
      final TestHistoryEntry originEntry = strategy.history[0];
      expect(originEntry.state, _wrapOriginState('initial state'));
      expect(originEntry.url, '/initial');

      // The flutter entry is pushed and its path should be derived from the
      // origin entry.
      final TestHistoryEntry flutterEntry = strategy.history[1];
      expect(flutterEntry.state, flutterState);
      expect(flutterEntry.url, '/initial');

      // The flutter entry is the current entry.
      expect(strategy.currentEntry, flutterEntry);
    });

    test('disposes of its listener without touching history', () async {
      const String unwrappedOriginState = 'initial state';
      final Map<String, dynamic> wrappedOriginState = _wrapOriginState(unwrappedOriginState);

      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(unwrappedOriginState, null, '/initial'),
      );
      expect(strategy.listeners, isEmpty);

      await window.debugInitializeHistory(strategy, useSingle: true);


      // There should be one `popstate` listener and two history entries.
      expect(strategy.listeners, hasLength(1));
      expect(strategy.history, hasLength(2));
      expect(strategy.history[0].state, wrappedOriginState);
      expect(strategy.history[0].url, '/initial');
      expect(strategy.history[1].state, flutterState);
      expect(strategy.history[1].url, '/initial');

      FakeAsync().run((FakeAsync fakeAsync) {
        window.browserHistory.dispose();
        // The `TestUrlStrategy` implementation uses microtasks to schedule the
        // removal of event listeners.
        fakeAsync.flushMicrotasks();
      });

      // After disposing, there should no listeners, and the history entries
      // remain unaffected.
      expect(strategy.listeners, isEmpty);
      expect(strategy.history, hasLength(2));
      expect(strategy.history[0].state, wrappedOriginState);
      expect(strategy.history[0].url, '/initial');
      expect(strategy.history[1].state, flutterState);
      expect(strategy.history[1].url, '/initial');

      // An extra call to dispose should be safe.
      FakeAsync().run((FakeAsync fakeAsync) {
        expect(() => window.browserHistory.dispose(), returnsNormally);
        fakeAsync.flushMicrotasks();
      });

      // Same expectations should remain true after the second dispose.
      expect(strategy.listeners, isEmpty);
      expect(strategy.history, hasLength(2));
      expect(strategy.history[0].state, wrappedOriginState);
      expect(strategy.history[0].url, '/initial');
      expect(strategy.history[1].state, flutterState);
      expect(strategy.history[1].url, '/initial');

      // Can still teardown after being disposed.
      await window.browserHistory.tearDown();
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntry.state, unwrappedOriginState);
      expect(strategy.currentEntry.url, '/initial');
    });

    test('disposes gracefully when url strategy is null', () async {
      await window.debugInitializeHistory(null, useSingle: true);
      expect(() => window.browserHistory.dispose(), returnsNormally);
    });

    test('browser back button pops routes correctly', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(null, null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: true);

      // Initially, we should be on the flutter entry.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
      await routeUpdated('/page1');
      // The number of entries shouldn't change.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      // But the url of the current entry (flutter entry) should be updated.
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page1');

      // No platform messages have been sent so far.
      expect(spy.messages, isEmpty);
      // Clicking back should take us to page1.
      await strategy.go(-1);
      // First, the framework should've received a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      // We still have 2 entries.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      // The url of the current entry (flutter entry) should go back to /home.
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    });

    test('multiple browser back clicks', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(null, null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: true);

      await routeUpdated('/page1');
      await routeUpdated('/page2');

      // Make sure we are on page2.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page2');

      // Back to page1.
      await strategy.go(-1);
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      await routeUpdated('/page1');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page1');

      // Back to home.
      await strategy.go(-1);
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      await routeUpdated('/home');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');

      // The next browser back will exit the app. We store the strategy locally
      // because it will be remove from the browser history class once it exits
      // the app.
      final TestUrlStrategy originalStrategy = strategy;
      await originalStrategy.go(-1);
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `SystemNavigator.pop` platform message
      // because there are no more routes to pop.
      await systemNavigatorPop();
      // 3. The active entry doesn't belong to our history anymore because we
      // navigated past it.
      expect(originalStrategy.currentEntryIndex, -1);
    }, skip: browserEngine == BrowserEngine.webkit);

    test('handle user-provided url', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(null, null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: true);

      await strategy.simulateUserTypingUrl('/page3');
      // This delay is necessary to wait for [BrowserHistory] because it
      // performs a `back` operation which results in a new event loop.
      await Future<void>.delayed(Duration.zero);
      // 1. The engine sends a `pushRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRoute');
      expect(spy.messages[0].methodArguments, '/page3');
      spy.messages.clear();
      // 2. The framework sends a `routePushed` platform message.
      await routeUpdated('/page3');
      // 3. The history state should reflect that /page3 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/page3');

      // Back to home.
      await strategy.go(-1);
      // 1. The engine sends a `popRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'popRoute');
      expect(spy.messages[0].methodArguments, isNull);
      spy.messages.clear();
      // 2. The framework sends a `routePopped` platform message.
      await routeUpdated('/home');
      // 3. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    });

    test('user types unknown url', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(null, null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: true);

      await strategy.simulateUserTypingUrl('/unknown');
      // This delay is necessary to wait for [BrowserHistory] because it
      // performs a `back` operation which results in a new event loop.
      await Future<void>.delayed(Duration.zero);
      // 1. The engine sends a `pushRoute` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRoute');
      expect(spy.messages[0].methodArguments, '/unknown');
      spy.messages.clear();
      // 2. The framework doesn't recognize the route name and ignores it.
      // 3. The history state should reflect that /home is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, flutterState);
      expect(strategy.currentEntry.url, '/home');
    });
  });

  group('$MultiEntriesBrowserHistory', () {
    final PlatformMessagesSpy spy = PlatformMessagesSpy();

    setUp(() async {
      spy.setUp();
    });

    tearDown(() async {
      spy.tearDown();
      await window.resetHistory();
    });

    test('basic setup works', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/initial'),
      );
      await window.debugInitializeHistory(strategy, useSingle: false);

      // There should be only one entry.
      expect(strategy.history, hasLength(1));

      // The origin entry is tagged and its path should remain unchanged.
      final TestHistoryEntry taggedOriginEntry = strategy.history[0];
      expect(taggedOriginEntry.state, _tagStateWithSerialCount('initial state', 0));
      expect(taggedOriginEntry.url, '/initial');
    });

    test('disposes of its listener without touching history', () async {
      const String untaggedState = 'initial state';
      final Map<String, dynamic> taggedState = _tagStateWithSerialCount(untaggedState, 0);

      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry(untaggedState, null, '/initial'),
      );
      expect(strategy.listeners, isEmpty);

      await window.debugInitializeHistory(strategy, useSingle: false);


      // There should be one `popstate` listener and one history entry.
      expect(strategy.listeners, hasLength(1));
      expect(strategy.history, hasLength(1));
      expect(strategy.history.single.state, taggedState);
      expect(strategy.history.single.url, '/initial');

      FakeAsync().run((FakeAsync fakeAsync) {
        window.browserHistory.dispose();
        // The `TestUrlStrategy` implementation uses microtasks to schedule the
        // removal of event listeners.
        fakeAsync.flushMicrotasks();
      });

      // After disposing, there should no listeners, and the history entries
      // remain unaffected.
      expect(strategy.listeners, isEmpty);
      expect(strategy.history, hasLength(1));
      expect(strategy.history.single.state, taggedState);
      expect(strategy.history.single.url, '/initial');

      // An extra call to dispose should be safe.
      FakeAsync().run((FakeAsync fakeAsync) {
        expect(() => window.browserHistory.dispose(), returnsNormally);
        fakeAsync.flushMicrotasks();
      });

      // Same expectations should remain true after the second dispose.
      expect(strategy.listeners, isEmpty);
      expect(strategy.history, hasLength(1));
      expect(strategy.history.single.state, taggedState);
      expect(strategy.history.single.url, '/initial');

      // Can still teardown after being disposed.
      await window.browserHistory.tearDown();
      expect(strategy.history, hasLength(1));
      expect(strategy.history.single.state, untaggedState);
      expect(strategy.history.single.url, '/initial');
    });

    test('disposes gracefully when url strategy is null', () async {
      await window.debugInitializeHistory(null, useSingle: false);
      expect(() => window.browserHistory.dispose(), returnsNormally);
    });

    test('browser back button push route information correctly', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: false);

      // Initially, we should be on the flutter entry.
      expect(strategy.history, hasLength(1));
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('initial state', 0));
      expect(strategy.currentEntry.url, '/home');
      await routeInformationUpdated('/page1', 'page1 state');
      // Should have two history entries now.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      // But the url of the current entry (flutter entry) should be updated.
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page1 state', 1));
      expect(strategy.currentEntry.url, '/page1');

      // No platform messages have been sent so far.
      expect(spy.messages, isEmpty);
      // Clicking back should take us to page1.
      await strategy.go(-1);
      // First, the framework should've received a `pushRouteInformation`
      // platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/home',
        'state': 'initial state',
      });
      // There are still two browser history entries, but we are back to the
      // original state.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 0);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('initial state', 0));
      expect(strategy.currentEntry.url, '/home');
    });

    test('multiple browser back clicks', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: false);

      await routeInformationUpdated('/page1', 'page1 state');
      await routeInformationUpdated('/page2', 'page2 state');

      // Make sure we are on page2.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 2);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page2 state', 2));
      expect(strategy.currentEntry.url, '/page2');

      // Back to page1.
      await strategy.go(-1);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/page1',
        'state': 'page1 state',
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page1 state', 1));
      expect(strategy.currentEntry.url, '/page1');
      // Back to home.
      await strategy.go(-1);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/home',
        'state': 'initial state',
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 0);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('initial state', 0));
      expect(strategy.currentEntry.url, '/home');
    }, skip: browserEngine == BrowserEngine.webkit);

    test('handle user-provided url', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: false);

      await strategy.simulateUserTypingUrl('/page3');
      // This delay is necessary to wait for [BrowserHistory] because it
      // performs a `back` operation which results in a new event loop.
      await Future<void>.delayed(Duration.zero);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/page3',
        'state': null,
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page3 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount(null, 1));
      expect(strategy.currentEntry.url, '/page3');

      // Back to home.
      await strategy.go(-1);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/home',
        'state': 'initial state',
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(2));
      expect(strategy.currentEntryIndex, 0);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('initial state', 0));
      expect(strategy.currentEntry.url, '/home');
    });

    test('forward button works', () async {
      final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
        const TestHistoryEntry('initial state', null, '/home'),
      );
      await window.debugInitializeHistory(strategy, useSingle: false);

      await routeInformationUpdated('/page1', 'page1 state');
      await routeInformationUpdated('/page2', 'page2 state');

      // Make sure we are on page2.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 2);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page2 state', 2));
      expect(strategy.currentEntry.url, '/page2');

      // Back to page1.
      await strategy.go(-1);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/page1',
        'state': 'page1 state',
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page1 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 1);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page1 state', 1));
      expect(strategy.currentEntry.url, '/page1');

      // Forward to page2
      await strategy.go(1);
      // 1. The engine sends a `pushRouteInformation` platform message.
      expect(spy.messages, hasLength(1));
      expect(spy.messages[0].channel, 'flutter/navigation');
      expect(spy.messages[0].methodName, 'pushRouteInformation');
      expect(spy.messages[0].methodArguments, <dynamic, dynamic>{
        'location': '/page2',
        'state': 'page2 state',
      });
      spy.messages.clear();
      // 2. The history state should reflect that /page2 is currently active.
      expect(strategy.history, hasLength(3));
      expect(strategy.currentEntryIndex, 2);
      expect(strategy.currentEntry.state, _tagStateWithSerialCount('page2 state', 2));
      expect(strategy.currentEntry.url, '/page2');
    });
  });

  group('$HashUrlStrategy', () {
    late TestPlatformLocation location;

    setUp(() {
      location = TestPlatformLocation();
    });

    tearDown(() {
      location = TestPlatformLocation();
    });

    test('leading slash is optional', () {
      final HashUrlStrategy strategy = HashUrlStrategy(location);

      location.hash = '#/';
      expect(strategy.getPath(), '/');

      location.hash = '#/foo';
      expect(strategy.getPath(), '/foo');

      location.hash = '#foo';
      expect(strategy.getPath(), 'foo');
    });

    test('path should not be empty', () {
      final HashUrlStrategy strategy = HashUrlStrategy(location);

      location.hash = '';
      expect(strategy.getPath(), '/');

      location.hash = '#';
      expect(strategy.getPath(), '/');
    });
  });
}

Future<void> routeUpdated(String routeName) {
  final Completer<void> completer = Completer<void>();
  window.sendPlatformMessage(
    'flutter/navigation',
    codec.encodeMethodCall(MethodCall(
      'routeUpdated',
      <String, dynamic>{'routeName': routeName},
    )),
    (_) => completer.complete(),
  );
  return completer.future;
}

Future<void> routeInformationUpdated(String location, dynamic state) {
  final Completer<void> completer = Completer<void>();
  window.sendPlatformMessage(
    'flutter/navigation',
    codec.encodeMethodCall(MethodCall(
      'routeInformationUpdated',
      <String, dynamic>{'location': location, 'state': state},
    )),
    (_) => completer.complete(),
  );
  return completer.future;
}

Future<void> systemNavigatorPop() {
  final Completer<void> completer = Completer<void>();
  window.sendPlatformMessage(
    'flutter/platform',
    codec.encodeMethodCall(const MethodCall('SystemNavigator.pop')),
    (_) => completer.complete(),
  );
  return completer.future;
}

/// A mock implementation of [PlatformLocation] that doesn't access the browser.
class TestPlatformLocation extends PlatformLocation {
  @override
  String? hash;

  @override
  dynamic state;

  @override
  String get pathname => throw UnimplementedError();

  @override
  String get search => throw UnimplementedError();

  @override
  void addPopStateListener(DomEventListener fn) {
    throw UnimplementedError();
  }

  @override
  void removePopStateListener(DomEventListener fn) {
    throw UnimplementedError();
  }

  @override
  void pushState(dynamic state, String title, String url) {
    throw UnimplementedError();
  }

  @override
  void replaceState(dynamic state, String title, String url) {
    throw UnimplementedError();
  }

  @override
  void go(int count) {
    throw UnimplementedError();
  }

  @override
  String getBaseHref() => '/';
}
