// 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.

import 'dart:typed_data';

import 'package:flutter/src/foundation/basic_types.dart';
import 'package:flutter/src/gestures/recognizer.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';

import 'webview_flutter_test.mocks.dart';

typedef VoidCallback = void Function();

@GenerateMocks(<Type>[WebViewPlatform, WebViewPlatformController])
void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  late MockWebViewPlatform mockWebViewPlatform;
  late MockWebViewPlatformController mockWebViewPlatformController;
  late MockWebViewCookieManagerPlatform mockWebViewCookieManagerPlatform;

  setUp(() {
    mockWebViewPlatformController = MockWebViewPlatformController();
    mockWebViewPlatform = MockWebViewPlatform();
    mockWebViewCookieManagerPlatform = MockWebViewCookieManagerPlatform();
    when(mockWebViewPlatform.build(
      context: anyNamed('context'),
      creationParams: anyNamed('creationParams'),
      webViewPlatformCallbacksHandler:
          anyNamed('webViewPlatformCallbacksHandler'),
      javascriptChannelRegistry: anyNamed('javascriptChannelRegistry'),
      onWebViewPlatformCreated: anyNamed('onWebViewPlatformCreated'),
      gestureRecognizers: anyNamed('gestureRecognizers'),
    )).thenAnswer((Invocation invocation) {
      final WebViewPlatformCreatedCallback onWebViewPlatformCreated =
          invocation.namedArguments[const Symbol('onWebViewPlatformCreated')]
              as WebViewPlatformCreatedCallback;
      return TestPlatformWebView(
        mockWebViewPlatformController: mockWebViewPlatformController,
        onWebViewPlatformCreated: onWebViewPlatformCreated,
      );
    });

    WebView.platform = mockWebViewPlatform;
    WebViewCookieManagerPlatform.instance = mockWebViewCookieManagerPlatform;
  });

  tearDown(() {
    mockWebViewCookieManagerPlatform.reset();
  });

  testWidgets('Create WebView', (WidgetTester tester) async {
    await tester.pumpWidget(const WebView());
  });

  testWidgets('Initial url', (WidgetTester tester) async {
    await tester.pumpWidget(const WebView(initialUrl: 'https://youtube.com'));

    final CreationParams params = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(params.initialUrl, 'https://youtube.com');
  });

  testWidgets('Javascript mode', (WidgetTester tester) async {
    await tester.pumpWidget(const WebView(
      javascriptMode: JavascriptMode.unrestricted,
    ));

    final CreationParams unrestrictedparams = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(
      unrestrictedparams.webSettings!.javascriptMode,
      JavascriptMode.unrestricted,
    );

    await tester.pumpWidget(const WebView(
      javascriptMode: JavascriptMode.disabled,
    ));

    final CreationParams disabledparams = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(disabledparams.webSettings!.javascriptMode, JavascriptMode.disabled);
  });

  testWidgets('Load file', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    await controller!.loadFile('/test/path/index.html');

    verify(mockWebViewPlatformController.loadFile(
      '/test/path/index.html',
    ));
  });

  testWidgets('Load file with empty path', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    expect(() => controller!.loadFile(''), throwsAssertionError);
  });

  testWidgets('Load HTML string without base URL', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    await controller!.loadHtmlString('<p>This is a test paragraph.</p>');

    verify(mockWebViewPlatformController.loadHtmlString(
      '<p>This is a test paragraph.</p>',
    ));
  });

  testWidgets('Load HTML string with base URL', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    await controller!.loadHtmlString(
      '<p>This is a test paragraph.</p>',
      baseUrl: 'https://flutter.dev',
    );

    verify(mockWebViewPlatformController.loadHtmlString(
      '<p>This is a test paragraph.</p>',
      baseUrl: 'https://flutter.dev',
    ));
  });

  testWidgets('Load HTML string with empty string',
      (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    expect(() => controller!.loadHtmlString(''), throwsAssertionError);
  });

  testWidgets('Load url', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    await controller!.loadUrl('https://flutter.io');

    verify(mockWebViewPlatformController.loadUrl(
      'https://flutter.io',
      argThat(isNull),
    ));
  });

  testWidgets('Invalid urls', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    final CreationParams params = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(params.initialUrl, isNull);

    expect(() => controller!.loadUrl(''), throwsA(anything));
    expect(() => controller!.loadUrl('flutter.io'), throwsA(anything));
  });

  testWidgets('Headers in loadUrl', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    final Map<String, String> headers = <String, String>{
      'CACHE-CONTROL': 'ABC'
    };
    await controller!.loadUrl('https://flutter.io', headers: headers);

    verify(mockWebViewPlatformController.loadUrl(
      'https://flutter.io',
      <String, String>{'CACHE-CONTROL': 'ABC'},
    ));
  });

  testWidgets('loadRequest', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    expect(controller, isNotNull);

    final WebViewRequest req = WebViewRequest(
      uri: Uri.parse('https://flutter.dev'),
      method: WebViewRequestMethod.post,
      headers: <String, String>{'foo': 'bar'},
      body: Uint8List.fromList('Test Body'.codeUnits),
    );

    await controller!.loadRequest(req);

    verify(mockWebViewPlatformController.loadRequest(req));
  });

  testWidgets('Clear Cache', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);

    await controller!.clearCache();

    verify(mockWebViewPlatformController.clearCache());
  });

  testWidgets('Can go back', (WidgetTester tester) async {
    when(mockWebViewPlatformController.canGoBack())
        .thenAnswer((_) => Future<bool>.value(true));

    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);
    expect(controller!.canGoBack(), completion(true));
  });

  testWidgets("Can't go forward", (WidgetTester tester) async {
    when(mockWebViewPlatformController.canGoForward())
        .thenAnswer((_) => Future<bool>.value(false));

    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);
    expect(controller!.canGoForward(), completion(false));
  });

  testWidgets('Go back', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    await controller!.goBack();
    verify(mockWebViewPlatformController.goBack());
  });

  testWidgets('Go forward', (WidgetTester tester) async {
    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);
    await controller!.goForward();
    verify(mockWebViewPlatformController.goForward());
  });

  testWidgets('Current URL', (WidgetTester tester) async {
    when(mockWebViewPlatformController.currentUrl())
        .thenAnswer((_) => Future<String>.value('https://youtube.com'));

    WebViewController? controller;
    await tester.pumpWidget(
      WebView(
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(controller, isNotNull);
    expect(await controller!.currentUrl(), 'https://youtube.com');
  });

  testWidgets('Reload url', (WidgetTester tester) async {
    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    await controller.reload();
    verify(mockWebViewPlatformController.reload());
  });

  testWidgets('evaluate Javascript', (WidgetTester tester) async {
    when(mockWebViewPlatformController.evaluateJavascript('fake js string'))
        .thenAnswer((_) => Future<String>.value('fake js string'));

    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );

    expect(
        // ignore: deprecated_member_use_from_same_package
        await controller.evaluateJavascript('fake js string'),
        'fake js string',
        reason: 'should get the argument');
  });

  testWidgets('evaluate Javascript with JavascriptMode disabled',
      (WidgetTester tester) async {
    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.disabled,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    expect(
      // ignore: deprecated_member_use_from_same_package
      () => controller.evaluateJavascript('fake js string'),
      throwsA(anything),
    );
  });

  testWidgets('runJavaScript', (WidgetTester tester) async {
    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    await controller.runJavascript('fake js string');
    verify(mockWebViewPlatformController.runJavascript('fake js string'));
  });

  testWidgets('runJavaScript with JavascriptMode disabled',
      (WidgetTester tester) async {
    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.disabled,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    expect(
      () => controller.runJavascript('fake js string'),
      throwsA(anything),
    );
  });

  testWidgets('runJavaScriptReturningResult', (WidgetTester tester) async {
    when(mockWebViewPlatformController
            .runJavascriptReturningResult('fake js string'))
        .thenAnswer((_) => Future<String>.value('fake js string'));

    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    expect(await controller.runJavascriptReturningResult('fake js string'),
        'fake js string',
        reason: 'should get the argument');
  });

  testWidgets('runJavaScriptReturningResult with JavascriptMode disabled',
      (WidgetTester tester) async {
    late WebViewController controller;
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://flutter.io',
        javascriptMode: JavascriptMode.disabled,
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
        },
      ),
    );
    expect(
      () => controller.runJavascriptReturningResult('fake js string'),
      throwsA(anything),
    );
  });

  testWidgets('Cookies can be cleared once', (WidgetTester tester) async {
    await tester.pumpWidget(
      const WebView(
        initialUrl: 'https://flutter.io',
      ),
    );
    final CookieManager cookieManager = CookieManager();
    final bool hasCookies = await cookieManager.clearCookies();
    expect(hasCookies, true);
  });

  testWidgets('Cookies can be set', (WidgetTester tester) async {
    const WebViewCookie cookie =
        WebViewCookie(name: 'foo', value: 'bar', domain: 'flutter.dev');

    await tester.pumpWidget(
      const WebView(
        initialUrl: 'https://flutter.io',
      ),
    );
    final CookieManager cookieManager = CookieManager();
    await cookieManager.setCookie(cookie);
    expect(mockWebViewCookieManagerPlatform.setCookieCalls,
        <WebViewCookie>[cookie]);
  });

  testWidgets('Initial JavaScript channels', (WidgetTester tester) async {
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts', onMessageReceived: (JavascriptMessage msg) {}),
          JavascriptChannel(
              name: 'Alarm', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );

    final CreationParams params = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(params.javascriptChannelNames,
        unorderedEquals(<String>['Tts', 'Alarm']));
  });

  test('Only valid JavaScript channel names are allowed', () {
    final JavascriptMessageHandler noOp = (JavascriptMessage msg) {};
    JavascriptChannel(name: 'Tts1', onMessageReceived: noOp);
    JavascriptChannel(name: '_Alarm', onMessageReceived: noOp);
    JavascriptChannel(name: 'foo_bar_', onMessageReceived: noOp);

    VoidCallback createChannel(String name) {
      return () {
        JavascriptChannel(name: name, onMessageReceived: noOp);
      };
    }

    expect(createChannel('1Alarm'), throwsAssertionError);
    expect(createChannel('foo.bar'), throwsAssertionError);
    expect(createChannel(''), throwsAssertionError);
  });

  testWidgets('Unique JavaScript channel names are required',
      (WidgetTester tester) async {
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Alarm', onMessageReceived: (JavascriptMessage msg) {}),
          JavascriptChannel(
              name: 'Alarm', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );
    expect(tester.takeException(), isNot(null));
  });

  testWidgets('JavaScript channels update', (WidgetTester tester) async {
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts', onMessageReceived: (JavascriptMessage msg) {}),
          JavascriptChannel(
              name: 'Alarm', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );

    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts', onMessageReceived: (JavascriptMessage msg) {}),
          JavascriptChannel(
              name: 'Alarm2', onMessageReceived: (JavascriptMessage msg) {}),
          JavascriptChannel(
              name: 'Alarm3', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );

    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
      mockWebViewPlatform,
      javascriptChannelRegistry: true,
    ).first as JavascriptChannelRegistry;

    expect(
      channelRegistry.channels.keys,
      unorderedEquals(<String>['Tts', 'Alarm2', 'Alarm3']),
    );
  });

  testWidgets('Remove all JavaScript channels and then add',
      (WidgetTester tester) async {
    // This covers a specific bug we had where after updating javascriptChannels to null,
    // updating it again with a subset of the previously registered channels fails as the
    // widget's cache of current channel wasn't properly updated when updating javascriptChannels to
    // null.
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );

    await tester.pumpWidget(
      const WebView(
        initialUrl: 'https://youtube.com',
      ),
    );

    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts', onMessageReceived: (JavascriptMessage msg) {}),
        },
      ),
    );

    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
      mockWebViewPlatform,
      javascriptChannelRegistry: true,
    ).last as JavascriptChannelRegistry;

    expect(channelRegistry.channels.keys, unorderedEquals(<String>['Tts']));
  });

  testWidgets('JavaScript channel messages', (WidgetTester tester) async {
    final List<String> ttsMessagesReceived = <String>[];
    final List<String> alarmMessagesReceived = <String>[];
    await tester.pumpWidget(
      WebView(
        initialUrl: 'https://youtube.com',
        javascriptChannels: <JavascriptChannel>{
          JavascriptChannel(
              name: 'Tts',
              onMessageReceived: (JavascriptMessage msg) {
                ttsMessagesReceived.add(msg.message);
              }),
          JavascriptChannel(
              name: 'Alarm',
              onMessageReceived: (JavascriptMessage msg) {
                alarmMessagesReceived.add(msg.message);
              }),
        },
      ),
    );

    final JavascriptChannelRegistry channelRegistry = captureBuildArgs(
      mockWebViewPlatform,
      javascriptChannelRegistry: true,
    ).single as JavascriptChannelRegistry;

    expect(ttsMessagesReceived, isEmpty);
    expect(alarmMessagesReceived, isEmpty);

    channelRegistry.onJavascriptChannelMessage('Tts', 'Hello');
    channelRegistry.onJavascriptChannelMessage('Tts', 'World');

    expect(ttsMessagesReceived, <String>['Hello', 'World']);
  });

  group('$PageStartedCallback', () {
    testWidgets('onPageStarted is not null', (WidgetTester tester) async {
      String? returnedUrl;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageStarted: (String url) {
          returnedUrl = url;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;

      handler.onPageStarted('https://youtube.com');

      expect(returnedUrl, 'https://youtube.com');
    });

    testWidgets('onPageStarted is null', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        initialUrl: 'https://youtube.com',
        onPageStarted: null,
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;

      // The platform side will always invoke a call for onPageStarted. This is
      // to test that it does not crash on a null callback.
      handler.onPageStarted('https://youtube.com');
    });

    testWidgets('onPageStarted changed', (WidgetTester tester) async {
      String? returnedUrl;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageStarted: (String url) {},
      ));

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageStarted: (String url) {
          returnedUrl = url;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).last as WebViewPlatformCallbacksHandler;
      handler.onPageStarted('https://youtube.com');

      expect(returnedUrl, 'https://youtube.com');
    });
  });

  group('$PageFinishedCallback', () {
    testWidgets('onPageFinished is not null', (WidgetTester tester) async {
      String? returnedUrl;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageFinished: (String url) {
          returnedUrl = url;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;
      handler.onPageFinished('https://youtube.com');

      expect(returnedUrl, 'https://youtube.com');
    });

    testWidgets('onPageFinished is null', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        initialUrl: 'https://youtube.com',
        onPageFinished: null,
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;
      // The platform side will always invoke a call for onPageFinished. This is
      // to test that it does not crash on a null callback.
      handler.onPageFinished('https://youtube.com');
    });

    testWidgets('onPageFinished changed', (WidgetTester tester) async {
      String? returnedUrl;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageFinished: (String url) {},
      ));

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onPageFinished: (String url) {
          returnedUrl = url;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).last as WebViewPlatformCallbacksHandler;
      handler.onPageFinished('https://youtube.com');

      expect(returnedUrl, 'https://youtube.com');
    });
  });

  group('$PageLoadingCallback', () {
    testWidgets('onLoadingProgress is not null', (WidgetTester tester) async {
      int? loadingProgress;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onProgress: (int progress) {
          loadingProgress = progress;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;
      handler.onProgress(50);

      expect(loadingProgress, 50);
    });

    testWidgets('onLoadingProgress is null', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        initialUrl: 'https://youtube.com',
        onProgress: null,
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).single as WebViewPlatformCallbacksHandler;

      // This is to test that it does not crash on a null callback.
      handler.onProgress(50);
    });

    testWidgets('onLoadingProgress changed', (WidgetTester tester) async {
      int? loadingProgress;

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onProgress: (int progress) {},
      ));

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        onProgress: (int progress) {
          loadingProgress = progress;
        },
      ));

      final WebViewPlatformCallbacksHandler handler = captureBuildArgs(
        mockWebViewPlatform,
        webViewPlatformCallbacksHandler: true,
      ).last as WebViewPlatformCallbacksHandler;
      handler.onProgress(50);

      expect(loadingProgress, 50);
    });
  });

  group('navigationDelegate', () {
    testWidgets('hasNavigationDelegate', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        initialUrl: 'https://youtube.com',
      ));

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.webSettings!.hasNavigationDelegate, false);

      await tester.pumpWidget(WebView(
        initialUrl: 'https://youtube.com',
        navigationDelegate: (NavigationRequest r) =>
            NavigationDecision.navigate,
      ));

      final WebSettings updateSettings =
          verify(mockWebViewPlatformController.updateSettings(captureAny))
              .captured
              .single as WebSettings;

      expect(updateSettings.hasNavigationDelegate, true);
    });

    testWidgets('Block navigation', (WidgetTester tester) async {
      final List<NavigationRequest> navigationRequests = <NavigationRequest>[];

      await tester.pumpWidget(WebView(
          initialUrl: 'https://youtube.com',
          navigationDelegate: (NavigationRequest request) {
            navigationRequests.add(request);
            // Only allow navigating to https://flutter.dev
            return request.url == 'https://flutter.dev'
                ? NavigationDecision.navigate
                : NavigationDecision.prevent;
          }));

      final List<dynamic> args = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
        webViewPlatformCallbacksHandler: true,
      );

      final CreationParams params = args[0] as CreationParams;
      expect(params.webSettings!.hasNavigationDelegate, true);

      final WebViewPlatformCallbacksHandler handler =
          args[1] as WebViewPlatformCallbacksHandler;

      // The navigation delegate only allows navigation to https://flutter.dev
      // so we should still be in https://youtube.com.
      expect(
        handler.onNavigationRequest(
          url: 'https://www.google.com',
          isForMainFrame: true,
        ),
        completion(false),
      );

      expect(navigationRequests.length, 1);
      expect(navigationRequests[0].url, 'https://www.google.com');
      expect(navigationRequests[0].isForMainFrame, true);

      expect(
        handler.onNavigationRequest(
          url: 'https://flutter.dev',
          isForMainFrame: true,
        ),
        completion(true),
      );
    });
  });

  group('debuggingEnabled', () {
    testWidgets('enable debugging', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        debuggingEnabled: true,
      ));

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.webSettings!.debuggingEnabled, true);
    });

    testWidgets('defaults to false', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView());

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.webSettings!.debuggingEnabled, false);
    });

    testWidgets('can be changed', (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(WebView(key: key));

      await tester.pumpWidget(WebView(
        key: key,
        debuggingEnabled: true,
      ));

      final WebSettings enabledSettings =
          verify(mockWebViewPlatformController.updateSettings(captureAny))
              .captured
              .last as WebSettings;
      expect(enabledSettings.debuggingEnabled, true);

      await tester.pumpWidget(WebView(
        key: key,
        debuggingEnabled: false,
      ));

      final WebSettings disabledSettings =
          verify(mockWebViewPlatformController.updateSettings(captureAny))
              .captured
              .last as WebSettings;
      expect(disabledSettings.debuggingEnabled, false);
    });
  });

  group('zoomEnabled', () {
    testWidgets('Enable zoom', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView(
        zoomEnabled: true,
      ));

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.webSettings!.zoomEnabled, isTrue);
    });

    testWidgets('defaults to true', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView());

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.webSettings!.zoomEnabled, isTrue);
    });

    testWidgets('can be changed', (WidgetTester tester) async {
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(WebView(key: key));

      await tester.pumpWidget(WebView(
        key: key,
        zoomEnabled: true,
      ));

      final WebSettings enabledSettings =
          verify(mockWebViewPlatformController.updateSettings(captureAny))
              .captured
              .last as WebSettings;
      // Zoom defaults to true, so no changes are made to settings.
      expect(enabledSettings.zoomEnabled, isNull);

      await tester.pumpWidget(WebView(
        key: key,
        zoomEnabled: false,
      ));

      final WebSettings disabledSettings =
          verify(mockWebViewPlatformController.updateSettings(captureAny))
              .captured
              .last as WebSettings;
      expect(disabledSettings.zoomEnabled, isFalse);
    });
  });

  group('Background color', () {
    testWidgets('Defaults to null', (WidgetTester tester) async {
      await tester.pumpWidget(const WebView());

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.backgroundColor, null);
    });

    testWidgets('Can be transparent', (WidgetTester tester) async {
      const Color transparentColor = Color(0x00000000);

      await tester.pumpWidget(const WebView(
        backgroundColor: transparentColor,
      ));

      final CreationParams params = captureBuildArgs(
        mockWebViewPlatform,
        creationParams: true,
      ).single as CreationParams;

      expect(params.backgroundColor, transparentColor);
    });
  });

  group('Custom platform implementation', () {
    setUp(() {
      WebView.platform = MyWebViewPlatform();
    });
    tearDownAll(() {
      WebView.platform = null;
    });

    testWidgets('creation', (WidgetTester tester) async {
      await tester.pumpWidget(
        const WebView(
          initialUrl: 'https://youtube.com',
          gestureNavigationEnabled: true,
        ),
      );

      final MyWebViewPlatform builder = WebView.platform as MyWebViewPlatform;
      final MyWebViewPlatformController platform = builder.lastPlatformBuilt!;

      expect(
          platform.creationParams,
          MatchesCreationParams(CreationParams(
            initialUrl: 'https://youtube.com',
            webSettings: WebSettings(
              javascriptMode: JavascriptMode.disabled,
              hasNavigationDelegate: false,
              debuggingEnabled: false,
              userAgent: const WebSetting<String?>.of(null),
              gestureNavigationEnabled: true,
              zoomEnabled: true,
            ),
          )));
    });

    testWidgets('loadUrl', (WidgetTester tester) async {
      late WebViewController controller;
      await tester.pumpWidget(
        WebView(
          initialUrl: 'https://youtube.com',
          onWebViewCreated: (WebViewController webViewController) {
            controller = webViewController;
          },
        ),
      );

      final MyWebViewPlatform builder = WebView.platform as MyWebViewPlatform;
      final MyWebViewPlatformController platform = builder.lastPlatformBuilt!;

      final Map<String, String> headers = <String, String>{
        'header': 'value',
      };

      await controller.loadUrl('https://google.com', headers: headers);

      expect(platform.lastUrlLoaded, 'https://google.com');
      expect(platform.lastRequestHeaders, headers);
    });
  });

  testWidgets('Set UserAgent', (WidgetTester tester) async {
    await tester.pumpWidget(const WebView(
      initialUrl: 'https://youtube.com',
      javascriptMode: JavascriptMode.unrestricted,
    ));

    final CreationParams params = captureBuildArgs(
      mockWebViewPlatform,
      creationParams: true,
    ).single as CreationParams;

    expect(params.webSettings!.userAgent.value, isNull);

    await tester.pumpWidget(const WebView(
      initialUrl: 'https://youtube.com',
      javascriptMode: JavascriptMode.unrestricted,
      userAgent: 'UA',
    ));

    final WebSettings settings =
        verify(mockWebViewPlatformController.updateSettings(captureAny))
            .captured
            .last as WebSettings;
    expect(settings.userAgent.value, 'UA');
  });
}

List<dynamic> captureBuildArgs(
  MockWebViewPlatform mockWebViewPlatform, {
  bool context = false,
  bool creationParams = false,
  bool webViewPlatformCallbacksHandler = false,
  bool javascriptChannelRegistry = false,
  bool onWebViewPlatformCreated = false,
  bool gestureRecognizers = false,
}) {
  return verify(mockWebViewPlatform.build(
    context: context ? captureAnyNamed('context') : anyNamed('context'),
    creationParams: creationParams
        ? captureAnyNamed('creationParams')
        : anyNamed('creationParams'),
    webViewPlatformCallbacksHandler: webViewPlatformCallbacksHandler
        ? captureAnyNamed('webViewPlatformCallbacksHandler')
        : anyNamed('webViewPlatformCallbacksHandler'),
    javascriptChannelRegistry: javascriptChannelRegistry
        ? captureAnyNamed('javascriptChannelRegistry')
        : anyNamed('javascriptChannelRegistry'),
    onWebViewPlatformCreated: onWebViewPlatformCreated
        ? captureAnyNamed('onWebViewPlatformCreated')
        : anyNamed('onWebViewPlatformCreated'),
    gestureRecognizers: gestureRecognizers
        ? captureAnyNamed('gestureRecognizers')
        : anyNamed('gestureRecognizers'),
  )).captured;
}

// This Widget ensures that onWebViewPlatformCreated is only called once when
// making multiple calls to `WidgetTester.pumpWidget` with different parameters
// for the WebView.
class TestPlatformWebView extends StatefulWidget {
  const TestPlatformWebView({
    Key? key,
    required this.mockWebViewPlatformController,
    this.onWebViewPlatformCreated,
  }) : super(key: key);

  final MockWebViewPlatformController mockWebViewPlatformController;
  final WebViewPlatformCreatedCallback? onWebViewPlatformCreated;

  @override
  State<StatefulWidget> createState() => TestPlatformWebViewState();
}

class TestPlatformWebViewState extends State<TestPlatformWebView> {
  @override
  void initState() {
    super.initState();
    final WebViewPlatformCreatedCallback? onWebViewPlatformCreated =
        widget.onWebViewPlatformCreated;
    if (onWebViewPlatformCreated != null) {
      onWebViewPlatformCreated(widget.mockWebViewPlatformController);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

class MyWebViewPlatform implements WebViewPlatform {
  MyWebViewPlatformController? lastPlatformBuilt;

  @override
  Widget build({
    BuildContext? context,
    CreationParams? creationParams,
    required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
    required JavascriptChannelRegistry javascriptChannelRegistry,
    WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
    Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
  }) {
    assert(onWebViewPlatformCreated != null);
    lastPlatformBuilt = MyWebViewPlatformController(
        creationParams, gestureRecognizers, webViewPlatformCallbacksHandler);
    onWebViewPlatformCreated!(lastPlatformBuilt);
    return Container();
  }

  @override
  Future<bool> clearCookies() {
    return Future<bool>.sync(() => true);
  }
}

class MyWebViewPlatformController extends WebViewPlatformController {
  MyWebViewPlatformController(this.creationParams, this.gestureRecognizers,
      WebViewPlatformCallbacksHandler platformHandler)
      : super(platformHandler);

  CreationParams? creationParams;
  Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;

  String? lastUrlLoaded;
  Map<String, String>? lastRequestHeaders;

  @override
  Future<void> loadUrl(String url, Map<String, String>? headers) async {
    equals(1, 1);
    lastUrlLoaded = url;
    lastRequestHeaders = headers;
  }
}

class MatchesWebSettings extends Matcher {
  MatchesWebSettings(this._webSettings);

  final WebSettings? _webSettings;

  @override
  Description describe(Description description) =>
      description.add('$_webSettings');

  @override
  bool matches(
      covariant WebSettings webSettings, Map<dynamic, dynamic> matchState) {
    return _webSettings!.javascriptMode == webSettings.javascriptMode &&
        _webSettings!.hasNavigationDelegate ==
            webSettings.hasNavigationDelegate &&
        _webSettings!.debuggingEnabled == webSettings.debuggingEnabled &&
        _webSettings!.gestureNavigationEnabled ==
            webSettings.gestureNavigationEnabled &&
        _webSettings!.userAgent == webSettings.userAgent &&
        _webSettings!.zoomEnabled == webSettings.zoomEnabled;
  }
}

class MatchesCreationParams extends Matcher {
  MatchesCreationParams(this._creationParams);

  final CreationParams _creationParams;

  @override
  Description describe(Description description) =>
      description.add('$_creationParams');

  @override
  bool matches(covariant CreationParams creationParams,
      Map<dynamic, dynamic> matchState) {
    return _creationParams.initialUrl == creationParams.initialUrl &&
        MatchesWebSettings(_creationParams.webSettings)
            .matches(creationParams.webSettings!, matchState) &&
        orderedEquals(_creationParams.javascriptChannelNames)
            .matches(creationParams.javascriptChannelNames, matchState);
  }
}

class MockWebViewCookieManagerPlatform extends WebViewCookieManagerPlatform {
  List<WebViewCookie> setCookieCalls = <WebViewCookie>[];

  @override
  Future<bool> clearCookies() async => true;

  @override
  Future<void> setCookie(WebViewCookie cookie) async {
    setCookieCalls.add(cookie);
  }

  void reset() {
    setCookieCalls = <WebViewCookie>[];
  }
}
