// 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:math';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
import 'package:webview_flutter_wkwebview/src/foundation/foundation.dart';
import 'package:webview_flutter_wkwebview/src/ui_kit/ui_kit.dart';
import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart';
import 'package:webview_flutter_wkwebview/src/web_kit_webview_widget.dart';

import 'web_kit_webview_widget_test.mocks.dart';

@GenerateMocks(<Type>[
  UIScrollView,
  WKNavigationDelegate,
  WKPreferences,
  WKScriptMessageHandler,
  WKWebView,
  WKWebViewConfiguration,
  WKWebsiteDataStore,
  WKUIDelegate,
  WKUserContentController,
  JavascriptChannelRegistry,
  WebViewPlatformCallbacksHandler,
  WebViewWidgetProxy,
])
void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('WebKitWebViewWidget', () {
    late MockWKWebView mockWebView;
    late MockWebViewWidgetProxy mockWebViewWidgetProxy;
    late MockWKUserContentController mockUserContentController;
    late MockWKPreferences mockPreferences;
    late MockWKWebViewConfiguration mockWebViewConfiguration;
    late MockWKUIDelegate mockUIDelegate;
    late MockUIScrollView mockScrollView;
    late MockWKWebsiteDataStore mockWebsiteDataStore;
    late MockWKNavigationDelegate mockNavigationDelegate;

    late MockWebViewPlatformCallbacksHandler mockCallbacksHandler;
    late MockJavascriptChannelRegistry mockJavascriptChannelRegistry;

    late WebKitWebViewPlatformController testController;

    setUp(() {
      mockWebView = MockWKWebView();
      mockWebViewConfiguration = MockWKWebViewConfiguration();
      mockUserContentController = MockWKUserContentController();
      mockPreferences = MockWKPreferences();
      mockUIDelegate = MockWKUIDelegate();
      mockScrollView = MockUIScrollView();
      mockWebsiteDataStore = MockWKWebsiteDataStore();
      mockNavigationDelegate = MockWKNavigationDelegate();
      mockWebViewWidgetProxy = MockWebViewWidgetProxy();

      when(
        mockWebViewWidgetProxy.createWebView(
          any,
          observeValue: anyNamed('observeValue'),
        ),
      ).thenReturn(mockWebView);
      when(
        mockWebViewWidgetProxy.createUIDelgate(
          onCreateWebView: captureAnyNamed('onCreateWebView'),
        ),
      ).thenReturn(mockUIDelegate);
      when(mockWebViewWidgetProxy.createNavigationDelegate(
        didFinishNavigation: anyNamed('didFinishNavigation'),
        didStartProvisionalNavigation:
            anyNamed('didStartProvisionalNavigation'),
        decidePolicyForNavigationAction:
            anyNamed('decidePolicyForNavigationAction'),
        didFailNavigation: anyNamed('didFailNavigation'),
        didFailProvisionalNavigation: anyNamed('didFailProvisionalNavigation'),
        webViewWebContentProcessDidTerminate:
            anyNamed('webViewWebContentProcessDidTerminate'),
      )).thenReturn(mockNavigationDelegate);
      when(mockWebView.configuration).thenReturn(mockWebViewConfiguration);
      when(mockWebViewConfiguration.userContentController).thenReturn(
        mockUserContentController,
      );
      when(mockWebViewConfiguration.preferences).thenReturn(mockPreferences);

      when(mockWebView.scrollView).thenReturn(mockScrollView);

      when(mockWebViewConfiguration.websiteDataStore).thenReturn(
        mockWebsiteDataStore,
      );

      mockCallbacksHandler = MockWebViewPlatformCallbacksHandler();
      mockJavascriptChannelRegistry = MockJavascriptChannelRegistry();
    });

    // Builds a WebViewCupertinoWidget with default parameters.
    Future<void> buildWidget(
      WidgetTester tester, {
      CreationParams? creationParams,
      bool hasNavigationDelegate = false,
      bool hasProgressTracking = false,
    }) async {
      await tester.pumpWidget(WebKitWebViewWidget(
        creationParams: creationParams ??
            CreationParams(
                webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: hasNavigationDelegate,
              hasProgressTracking: hasProgressTracking,
            )),
        callbacksHandler: mockCallbacksHandler,
        javascriptChannelRegistry: mockJavascriptChannelRegistry,
        webViewProxy: mockWebViewWidgetProxy,
        configuration: mockWebViewConfiguration,
        onBuildWidget: (WebKitWebViewPlatformController controller) {
          testController = controller;
          return Container();
        },
      ));
      await tester.pumpAndSettle();
    }

    testWidgets('build $WebKitWebViewWidget', (WidgetTester tester) async {
      await buildWidget(tester);
    });

    testWidgets('Requests to open a new window loads request in same window',
        (WidgetTester tester) async {
      await buildWidget(tester);

      final dynamic onCreateWebView = verify(
                  mockWebViewWidgetProxy.createUIDelgate(
                      onCreateWebView: captureAnyNamed('onCreateWebView')))
              .captured
              .single
          as void Function(
              WKWebView, WKWebViewConfiguration, WKNavigationAction);

      const NSUrlRequest request = NSUrlRequest(url: 'https://google.com');
      onCreateWebView(
        mockWebView,
        mockWebViewConfiguration,
        const WKNavigationAction(
          request: request,
          targetFrame: WKFrameInfo(isMainFrame: false),
        ),
      );

      verify(mockWebView.loadRequest(request));
    });

    group('CreationParams', () {
      testWidgets('initialUrl', (WidgetTester tester) async {
        await buildWidget(
          tester,
          creationParams: CreationParams(
            initialUrl: 'https://www.google.com',
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );
        final NSUrlRequest request = verify(mockWebView.loadRequest(captureAny))
            .captured
            .single as NSUrlRequest;
        expect(request.url, 'https://www.google.com');
      });

      testWidgets('backgroundColor', (WidgetTester tester) async {
        await buildWidget(
          tester,
          creationParams: CreationParams(
            backgroundColor: Colors.red,
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );

        verify(mockWebView.setOpaque(false));
        verify(mockWebView.setBackgroundColor(Colors.transparent));
        verify(mockScrollView.setBackgroundColor(Colors.red));
      });

      testWidgets('userAgent', (WidgetTester tester) async {
        await buildWidget(
          tester,
          creationParams: CreationParams(
            userAgent: 'MyUserAgent',
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );

        verify(mockWebView.setCustomUserAgent('MyUserAgent'));
      });

      testWidgets('autoMediaPlaybackPolicy true', (WidgetTester tester) async {
        await buildWidget(
          tester,
          creationParams: CreationParams(
            autoMediaPlaybackPolicy:
                AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );

        verify(mockWebViewConfiguration
            .setMediaTypesRequiringUserActionForPlayback(<
                WKAudiovisualMediaType>{
          WKAudiovisualMediaType.all,
        }));
      });

      testWidgets('autoMediaPlaybackPolicy false', (WidgetTester tester) async {
        await buildWidget(
          tester,
          creationParams: CreationParams(
            autoMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );

        verify(mockWebViewConfiguration
            .setMediaTypesRequiringUserActionForPlayback(<
                WKAudiovisualMediaType>{
          WKAudiovisualMediaType.none,
        }));
      });

      testWidgets('javascriptChannelNames', (WidgetTester tester) async {
        when(
          mockWebViewWidgetProxy.createScriptMessageHandler(
            didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
          ),
        ).thenReturn(
          MockWKScriptMessageHandler(),
        );

        await buildWidget(
          tester,
          creationParams: CreationParams(
            javascriptChannelNames: <String>{'a', 'b'},
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              hasNavigationDelegate: false,
            ),
          ),
        );

        final List<dynamic> javaScriptChannels = verify(
          mockUserContentController.addScriptMessageHandler(
            captureAny,
            captureAny,
          ),
        ).captured;
        expect(
          javaScriptChannels[0],
          isA<WKScriptMessageHandler>(),
        );
        expect(javaScriptChannels[1], 'a');
        expect(
          javaScriptChannels[2],
          isA<WKScriptMessageHandler>(),
        );
        expect(javaScriptChannels[3], 'b');
      });

      group('WebSettings', () {
        testWidgets('javascriptMode', (WidgetTester tester) async {
          await buildWidget(
            tester,
            creationParams: CreationParams(
              webSettings: WebSettings(
                userAgent: const WebSetting<String?>.absent(),
                javascriptMode: JavascriptMode.unrestricted,
                hasNavigationDelegate: false,
              ),
            ),
          );

          verify(mockPreferences.setJavaScriptEnabled(true));
        });

        testWidgets('userAgent', (WidgetTester tester) async {
          await buildWidget(
            tester,
            creationParams: CreationParams(
              webSettings: WebSettings(
                userAgent: const WebSetting<String?>.of('myUserAgent'),
                hasNavigationDelegate: false,
              ),
            ),
          );

          verify(mockWebView.setCustomUserAgent('myUserAgent'));
        });

        testWidgets(
          'enabling zoom re-adds JavaScript channels',
          (WidgetTester tester) async {
            when(
              mockWebViewWidgetProxy.createScriptMessageHandler(
                didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
              ),
            ).thenReturn(
              MockWKScriptMessageHandler(),
            );

            await buildWidget(
              tester,
              creationParams: CreationParams(
                webSettings: WebSettings(
                  userAgent: const WebSetting<String?>.absent(),
                  zoomEnabled: false,
                  hasNavigationDelegate: false,
                ),
                javascriptChannelNames: <String>{'myChannel'},
              ),
            );

            clearInteractions(mockUserContentController);

            await testController.updateSettings(WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              zoomEnabled: true,
            ));

            final List<dynamic> javaScriptChannels = verifyInOrder(<Object>[
              mockUserContentController.removeAllUserScripts(),
              mockUserContentController.removeScriptMessageHandler('myChannel'),
              mockUserContentController.addScriptMessageHandler(
                captureAny,
                captureAny,
              ),
            ]).captured[2];

            expect(
              javaScriptChannels[0],
              isA<WKScriptMessageHandler>(),
            );
            expect(javaScriptChannels[1], 'myChannel');
          },
        );

        testWidgets(
          'enabling zoom removes script',
          (WidgetTester tester) async {
            when(mockWebViewWidgetProxy.createScriptMessageHandler())
                .thenReturn(
              MockWKScriptMessageHandler(),
            );

            await buildWidget(
              tester,
              creationParams: CreationParams(
                webSettings: WebSettings(
                  userAgent: const WebSetting<String?>.absent(),
                  zoomEnabled: false,
                  hasNavigationDelegate: false,
                ),
              ),
            );

            clearInteractions(mockUserContentController);

            await testController.updateSettings(WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              zoomEnabled: true,
            ));

            verify(mockUserContentController.removeAllUserScripts());
            verifyNever(mockUserContentController.addScriptMessageHandler(
              any,
              any,
            ));
          },
        );

        testWidgets('zoomEnabled is false', (WidgetTester tester) async {
          await buildWidget(
            tester,
            creationParams: CreationParams(
              webSettings: WebSettings(
                userAgent: const WebSetting<String?>.absent(),
                zoomEnabled: false,
                hasNavigationDelegate: false,
              ),
            ),
          );

          final WKUserScript zoomScript =
              verify(mockUserContentController.addUserScript(captureAny))
                  .captured
                  .first as WKUserScript;
          expect(zoomScript.isMainFrameOnly, isTrue);
          expect(zoomScript.injectionTime,
              WKUserScriptInjectionTime.atDocumentEnd);
          expect(
            zoomScript.source,
            "var meta = document.createElement('meta');\n"
            "meta.name = 'viewport';\n"
            "meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, "
            "user-scalable=no';\n"
            "var head = document.getElementsByTagName('head')[0];head.appendChild(meta);",
          );
        });

        testWidgets('allowsInlineMediaPlayback', (WidgetTester tester) async {
          await buildWidget(
            tester,
            creationParams: CreationParams(
              webSettings: WebSettings(
                userAgent: const WebSetting<String?>.absent(),
                allowsInlineMediaPlayback: true,
              ),
            ),
          );

          verify(mockWebViewConfiguration.setAllowsInlineMediaPlayback(true));
        });
      });
    });

    group('WebKitWebViewPlatformController', () {
      testWidgets('loadFile', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.loadFile('/path/to/file.html');
        verify(mockWebView.loadFileUrl(
          '/path/to/file.html',
          readAccessUrl: '/path/to',
        ));
      });

      testWidgets('loadFlutterAsset', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.loadFlutterAsset('test_assets/index.html');
        verify(mockWebView.loadFlutterAsset('test_assets/index.html'));
      });

      testWidgets('loadHtmlString', (WidgetTester tester) async {
        await buildWidget(tester);

        const String htmlString = '<html><body>Test data.</body></html>';
        await testController.loadHtmlString(htmlString, baseUrl: 'baseUrl');

        verify(mockWebView.loadHtmlString(
          '<html><body>Test data.</body></html>',
          baseUrl: 'baseUrl',
        ));
      });

      testWidgets('loadUrl', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.loadUrl(
          'https://www.google.com',
          <String, String>{'a': 'header'},
        );

        final NSUrlRequest request = verify(mockWebView.loadRequest(captureAny))
            .captured
            .single as NSUrlRequest;
        expect(request.url, 'https://www.google.com');
        expect(request.allHttpHeaderFields, <String, String>{'a': 'header'});
      });

      group('loadRequest', () {
        testWidgets('Throws ArgumentError for empty scheme',
            (WidgetTester tester) async {
          await buildWidget(tester);

          expect(
              () async => await testController.loadRequest(
                    WebViewRequest(
                      uri: Uri.parse('www.google.com'),
                      method: WebViewRequestMethod.get,
                    ),
                  ),
              throwsA(const TypeMatcher<ArgumentError>()));
        });

        testWidgets('GET without headers', (WidgetTester tester) async {
          await buildWidget(tester);

          await testController.loadRequest(WebViewRequest(
            uri: Uri.parse('https://www.google.com'),
            method: WebViewRequestMethod.get,
          ));

          final NSUrlRequest request =
              verify(mockWebView.loadRequest(captureAny)).captured.single
                  as NSUrlRequest;
          expect(request.url, 'https://www.google.com');
          expect(request.allHttpHeaderFields, <String, String>{});
          expect(request.httpMethod, 'get');
        });

        testWidgets('GET with headers', (WidgetTester tester) async {
          await buildWidget(tester);

          await testController.loadRequest(WebViewRequest(
            uri: Uri.parse('https://www.google.com'),
            method: WebViewRequestMethod.get,
            headers: <String, String>{'a': 'header'},
          ));

          final NSUrlRequest request =
              verify(mockWebView.loadRequest(captureAny)).captured.single
                  as NSUrlRequest;
          expect(request.url, 'https://www.google.com');
          expect(request.allHttpHeaderFields, <String, String>{'a': 'header'});
          expect(request.httpMethod, 'get');
        });

        testWidgets('POST without body', (WidgetTester tester) async {
          await buildWidget(tester);

          await testController.loadRequest(WebViewRequest(
            uri: Uri.parse('https://www.google.com'),
            method: WebViewRequestMethod.post,
          ));

          final NSUrlRequest request =
              verify(mockWebView.loadRequest(captureAny)).captured.single
                  as NSUrlRequest;
          expect(request.url, 'https://www.google.com');
          expect(request.httpMethod, 'post');
        });

        testWidgets('POST with body', (WidgetTester tester) async {
          await buildWidget(tester);

          await testController.loadRequest(WebViewRequest(
              uri: Uri.parse('https://www.google.com'),
              method: WebViewRequestMethod.post,
              body: Uint8List.fromList('Test Body'.codeUnits)));

          final NSUrlRequest request =
              verify(mockWebView.loadRequest(captureAny)).captured.single
                  as NSUrlRequest;
          expect(request.url, 'https://www.google.com');
          expect(request.httpMethod, 'post');
          expect(
            request.httpBody,
            Uint8List.fromList('Test Body'.codeUnits),
          );
        });
      });

      testWidgets('canGoBack', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.canGoBack()).thenAnswer(
          (_) => Future<bool>.value(false),
        );
        expect(testController.canGoBack(), completion(false));
      });

      testWidgets('canGoForward', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.canGoForward()).thenAnswer(
          (_) => Future<bool>.value(true),
        );
        expect(testController.canGoForward(), completion(true));
      });

      testWidgets('goBack', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.goBack();
        verify(mockWebView.goBack());
      });

      testWidgets('goForward', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.goForward();
        verify(mockWebView.goForward());
      });

      testWidgets('reload', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.reload();
        verify(mockWebView.reload());
      });

      testWidgets('evaluateJavascript', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<String>.value('returnString'),
        );
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('returnString'),
        );
      });

      testWidgets('evaluateJavascript with null return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<Object?>.value(),
        );
        // The legacy implementation of webview_flutter_wkwebview would convert
        // objects to strings before returning them to Dart. This verifies null
        // is represented the way it is in Objective-C.
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('(null)'),
        );
      });

      testWidgets('evaluateJavascript with bool return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<Object?>.value(true),
        );
        // The legacy implementation of webview_flutter_wkwebview would convert
        // objects to strings before returning them to Dart. This verifies bool
        // is represented the way it is in Objective-C.
        // `NSNumber.description` converts bool values to a 1 or 0.
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('1'),
        );
      });

      testWidgets('evaluateJavascript with double return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<Object?>.value(1.0),
        );
        // The legacy implementation of webview_flutter_wkwebview would convert
        // objects to strings before returning them to Dart. This verifies
        // double is represented the way it is in Objective-C. If a double
        // doesn't contain any decimal values, it gets truncated to an int.
        // This should be happenning because NSNumber convertes float values
        // with no decimals to an int when using `NSNumber.description`.
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('1'),
        );
      });

      testWidgets('evaluateJavascript with list return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<Object?>.value(<Object?>[1, 'string', null]),
        );
        // The legacy implementation of webview_flutter_wkwebview would convert
        // objects to strings before returning them to Dart. This verifies list
        // is represented the way it is in Objective-C.
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('(1,string,"<null>")'),
        );
      });

      testWidgets('evaluateJavascript with map return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<Object?>.value(<Object?, Object?>{
            1: 'string',
            null: null,
          }),
        );
        // The legacy implementation of webview_flutter_wkwebview would convert
        // objects to strings before returning them to Dart. This verifies map
        // is represented the way it is in Objective-C.
        expect(
          testController.evaluateJavascript('runJavaScript'),
          completion('{1 = string;"<null>" = "<null>"}'),
        );
      });

      testWidgets('evaluateJavascript throws exception',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript'))
            .thenThrow(Error());
        expect(
          testController.evaluateJavascript('runJavaScript'),
          throwsA(isA<Error>()),
        );
      });

      testWidgets('runJavascriptReturningResult', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<String>.value('returnString'),
        );
        expect(
          testController.runJavascriptReturningResult('runJavaScript'),
          completion('returnString'),
        );
      });

      testWidgets(
          'runJavascriptReturningResult throws error on null return value',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<String?>.value(null),
        );
        expect(
          () => testController.runJavascriptReturningResult('runJavaScript'),
          throwsArgumentError,
        );
      });

      testWidgets('runJavascript', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript')).thenAnswer(
          (_) => Future<String>.value('returnString'),
        );
        expect(
          testController.runJavascript('runJavaScript'),
          completes,
        );
      });

      testWidgets(
          'runJavascript ignores exception with unsupported javascript type',
          (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.evaluateJavaScript('runJavaScript'))
            .thenThrow(PlatformException(
          code: '',
          details: const NSError(
            code: WKErrorCode.javaScriptResultTypeIsUnsupported,
            domain: '',
            localizedDescription: '',
          ),
        ));
        expect(
          testController.runJavascript('runJavaScript'),
          completes,
        );
      });

      testWidgets('getTitle', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.getTitle())
            .thenAnswer((_) => Future<String>.value('Web Title'));
        expect(testController.getTitle(), completion('Web Title'));
      });

      testWidgets('currentUrl', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockWebView.getUrl())
            .thenAnswer((_) => Future<String>.value('myUrl.com'));
        expect(testController.currentUrl(), completion('myUrl.com'));
      });

      testWidgets('scrollTo', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.scrollTo(2, 4);
        verify(mockScrollView.setContentOffset(const Point<double>(2.0, 4.0)));
      });

      testWidgets('scrollBy', (WidgetTester tester) async {
        await buildWidget(tester);

        await testController.scrollBy(2, 4);
        verify(mockScrollView.scrollBy(const Point<double>(2.0, 4.0)));
      });

      testWidgets('getScrollX', (WidgetTester tester) async {
        await buildWidget(tester);

        when(mockScrollView.getContentOffset()).thenAnswer(
            (_) => Future<Point<double>>.value(const Point<double>(8.0, 16.0)));
        expect(testController.getScrollX(), completion(8.0));
      });

      testWidgets('getScrollY', (WidgetTester tester) async {
        await buildWidget(tester);

        await buildWidget(tester);

        when(mockScrollView.getContentOffset()).thenAnswer(
            (_) => Future<Point<double>>.value(const Point<double>(8.0, 16.0)));
        expect(testController.getScrollY(), completion(16.0));
      });

      testWidgets('clearCache', (WidgetTester tester) async {
        await buildWidget(tester);
        when(
          mockWebsiteDataStore.removeDataOfTypes(
            <WKWebsiteDataType>{
              WKWebsiteDataType.memoryCache,
              WKWebsiteDataType.diskCache,
              WKWebsiteDataType.offlineWebApplicationCache,
              WKWebsiteDataType.localStorage,
            },
            DateTime.fromMillisecondsSinceEpoch(0),
          ),
        ).thenAnswer((_) => Future<bool>.value(false));

        expect(testController.clearCache(), completes);
      });

      testWidgets('addJavascriptChannels', (WidgetTester tester) async {
        when(
          mockWebViewWidgetProxy.createScriptMessageHandler(
            didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
          ),
        ).thenReturn(
          MockWKScriptMessageHandler(),
        );

        await buildWidget(tester);

        await testController.addJavascriptChannels(<String>{'c', 'd'});
        final List<dynamic> javaScriptChannels = verify(
          mockUserContentController.addScriptMessageHandler(
              captureAny, captureAny),
        ).captured;
        expect(
          javaScriptChannels[0],
          isA<WKScriptMessageHandler>(),
        );
        expect(javaScriptChannels[1], 'c');
        expect(
          javaScriptChannels[2],
          isA<WKScriptMessageHandler>(),
        );
        expect(javaScriptChannels[3], 'd');

        final List<WKUserScript> userScripts =
            verify(mockUserContentController.addUserScript(captureAny))
                .captured
                .cast<WKUserScript>();
        expect(userScripts[0].source, 'window.c = webkit.messageHandlers.c;');
        expect(
          userScripts[0].injectionTime,
          WKUserScriptInjectionTime.atDocumentStart,
        );
        expect(userScripts[0].isMainFrameOnly, false);
        expect(userScripts[1].source, 'window.d = webkit.messageHandlers.d;');
        expect(
          userScripts[1].injectionTime,
          WKUserScriptInjectionTime.atDocumentStart,
        );
        expect(userScripts[0].isMainFrameOnly, false);
      });

      testWidgets('removeJavascriptChannels', (WidgetTester tester) async {
        when(
          mockWebViewWidgetProxy.createScriptMessageHandler(
            didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
          ),
        ).thenReturn(
          MockWKScriptMessageHandler(),
        );

        await buildWidget(tester);

        await testController.addJavascriptChannels(<String>{'c', 'd'});
        reset(mockUserContentController);

        await testController.removeJavascriptChannels(<String>{'c'});

        verify(mockUserContentController.removeAllUserScripts());
        verify(mockUserContentController.removeScriptMessageHandler('c'));
        verify(mockUserContentController.removeScriptMessageHandler('d'));

        final List<dynamic> javaScriptChannels = verify(
          mockUserContentController.addScriptMessageHandler(
            captureAny,
            captureAny,
          ),
        ).captured;
        expect(
          javaScriptChannels[0],
          isA<WKScriptMessageHandler>(),
        );
        expect(javaScriptChannels[1], 'd');

        final List<WKUserScript> userScripts =
            verify(mockUserContentController.addUserScript(captureAny))
                .captured
                .cast<WKUserScript>();
        expect(userScripts[0].source, 'window.d = webkit.messageHandlers.d;');
        expect(
          userScripts[0].injectionTime,
          WKUserScriptInjectionTime.atDocumentStart,
        );
        expect(userScripts[0].isMainFrameOnly, false);
      });

      testWidgets('removeJavascriptChannels with zoom disabled',
          (WidgetTester tester) async {
        when(
          mockWebViewWidgetProxy.createScriptMessageHandler(
            didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
          ),
        ).thenReturn(
          MockWKScriptMessageHandler(),
        );

        await buildWidget(
          tester,
          creationParams: CreationParams(
            webSettings: WebSettings(
              userAgent: const WebSetting<String?>.absent(),
              zoomEnabled: false,
              hasNavigationDelegate: false,
            ),
          ),
        );

        await testController.addJavascriptChannels(<String>{'c'});
        clearInteractions(mockUserContentController);
        await testController.removeJavascriptChannels(<String>{'c'});

        final WKUserScript zoomScript =
            verify(mockUserContentController.addUserScript(captureAny))
                .captured
                .first as WKUserScript;
        expect(zoomScript.isMainFrameOnly, isTrue);
        expect(
            zoomScript.injectionTime, WKUserScriptInjectionTime.atDocumentEnd);
        expect(
          zoomScript.source,
          "var meta = document.createElement('meta');\n"
          "meta.name = 'viewport';\n"
          "meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, "
          "user-scalable=no';\n"
          "var head = document.getElementsByTagName('head')[0];head.appendChild(meta);",
        );
      });
    });

    group('WebViewPlatformCallbacksHandler', () {
      testWidgets('onPageStarted', (WidgetTester tester) async {
        await buildWidget(tester);

        final dynamic didStartProvisionalNavigation =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: anyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              captureAnyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              anyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: anyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              anyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              anyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as void Function(WKWebView, String);
        didStartProvisionalNavigation(mockWebView, 'https://google.com');

        verify(mockCallbacksHandler.onPageStarted('https://google.com'));
      });

      testWidgets('onPageFinished', (WidgetTester tester) async {
        await buildWidget(tester);

        final dynamic didFinishNavigation =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: captureAnyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              anyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              anyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: anyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              anyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              anyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as void Function(WKWebView, String);
        didFinishNavigation(mockWebView, 'https://google.com');

        verify(mockCallbacksHandler.onPageFinished('https://google.com'));
      });

      testWidgets('onWebResourceError from didFailNavigation',
          (WidgetTester tester) async {
        await buildWidget(tester);

        final dynamic didFailNavigation =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: anyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              anyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              anyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: captureAnyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              anyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              anyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as void Function(WKWebView, NSError);

        didFailNavigation(
          mockWebView,
          const NSError(
            code: WKErrorCode.webViewInvalidated,
            domain: 'domain',
            localizedDescription: 'my desc',
          ),
        );

        final WebResourceError error =
            verify(mockCallbacksHandler.onWebResourceError(captureAny))
                .captured
                .single as WebResourceError;
        expect(error.description, 'my desc');
        expect(error.errorCode, WKErrorCode.webViewInvalidated);
        expect(error.domain, 'domain');
        expect(error.errorType, WebResourceErrorType.webViewInvalidated);
      });

      testWidgets('onWebResourceError from didFailProvisionalNavigation',
          (WidgetTester tester) async {
        await buildWidget(tester);

        final dynamic didFailProvisionalNavigation =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: anyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              anyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              anyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: anyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              captureAnyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              anyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as void Function(WKWebView, NSError);

        didFailProvisionalNavigation(
          mockWebView,
          const NSError(
            code: WKErrorCode.webContentProcessTerminated,
            domain: 'domain',
            localizedDescription: 'my desc',
          ),
        );

        final WebResourceError error =
            verify(mockCallbacksHandler.onWebResourceError(captureAny))
                .captured
                .single as WebResourceError;
        expect(error.description, 'my desc');
        expect(error.errorCode, WKErrorCode.webContentProcessTerminated);
        expect(error.domain, 'domain');
        expect(
          error.errorType,
          WebResourceErrorType.webContentProcessTerminated,
        );
      });

      testWidgets(
          'onWebResourceError from webViewWebContentProcessDidTerminate',
          (WidgetTester tester) async {
        await buildWidget(tester);

        final dynamic webViewWebContentProcessDidTerminate =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: anyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              anyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              anyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: anyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              anyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              captureAnyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as void Function(WKWebView);
        webViewWebContentProcessDidTerminate(mockWebView);

        final WebResourceError error =
            verify(mockCallbacksHandler.onWebResourceError(captureAny))
                .captured
                .single as WebResourceError;
        expect(error.description, '');
        expect(error.errorCode, WKErrorCode.webContentProcessTerminated);
        expect(error.domain, 'WKErrorDomain');
        expect(
          error.errorType,
          WebResourceErrorType.webContentProcessTerminated,
        );
      });

      testWidgets('onNavigationRequest from decidePolicyForNavigationAction',
          (WidgetTester tester) async {
        await buildWidget(tester, hasNavigationDelegate: true);

        final dynamic decidePolicyForNavigationAction =
            verify(mockWebViewWidgetProxy.createNavigationDelegate(
          didFinishNavigation: anyNamed('didFinishNavigation'),
          didStartProvisionalNavigation:
              anyNamed('didStartProvisionalNavigation'),
          decidePolicyForNavigationAction:
              captureAnyNamed('decidePolicyForNavigationAction'),
          didFailNavigation: anyNamed('didFailNavigation'),
          didFailProvisionalNavigation:
              anyNamed('didFailProvisionalNavigation'),
          webViewWebContentProcessDidTerminate:
              anyNamed('webViewWebContentProcessDidTerminate'),
        )).captured.single as Future<WKNavigationActionPolicy> Function(
                WKWebView, WKNavigationAction);

        when(mockCallbacksHandler.onNavigationRequest(
          isForMainFrame: argThat(isFalse, named: 'isForMainFrame'),
          url: 'https://google.com',
        )).thenReturn(true);

        expect(
          decidePolicyForNavigationAction(
            mockWebView,
            const WKNavigationAction(
              request: NSUrlRequest(url: 'https://google.com'),
              targetFrame: WKFrameInfo(isMainFrame: false),
            ),
          ),
          completion(WKNavigationActionPolicy.allow),
        );

        verify(mockCallbacksHandler.onNavigationRequest(
          url: 'https://google.com',
          isForMainFrame: false,
        ));
      });

      testWidgets('onProgress', (WidgetTester tester) async {
        await buildWidget(tester, hasProgressTracking: true);

        verify(mockWebView.addObserver(
          mockWebView,
          keyPath: 'estimatedProgress',
          options: <NSKeyValueObservingOptions>{
            NSKeyValueObservingOptions.newValue,
          },
        ));

        final dynamic observeValue = verify(
                mockWebViewWidgetProxy.createWebView(any,
                    observeValue: captureAnyNamed('observeValue')))
            .captured
            .single as void Function(
          String keyPath,
          NSObject object,
          Map<NSKeyValueChangeKey, Object?> change,
        );

        observeValue(
          'estimatedProgress',
          mockWebView,
          <NSKeyValueChangeKey, Object?>{NSKeyValueChangeKey.newValue: 0.32},
        );

        verify(mockCallbacksHandler.onProgress(32));
      });

      testWidgets('progress observer is not removed without being set first',
          (WidgetTester tester) async {
        await buildWidget(tester, hasProgressTracking: false);

        verifyNever(mockWebView.removeObserver(
          mockWebView,
          keyPath: 'estimatedProgress',
        ));
      });
    });

    group('JavascriptChannelRegistry', () {
      testWidgets('onJavascriptChannelMessage', (WidgetTester tester) async {
        when(
          mockWebViewWidgetProxy.createScriptMessageHandler(
            didReceiveScriptMessage: anyNamed('didReceiveScriptMessage'),
          ),
        ).thenReturn(
          MockWKScriptMessageHandler(),
        );

        await buildWidget(tester);
        await testController.addJavascriptChannels(<String>{'hello'});

        final dynamic didReceiveScriptMessage = verify(
                mockWebViewWidgetProxy.createScriptMessageHandler(
                    didReceiveScriptMessage:
                        captureAnyNamed('didReceiveScriptMessage')))
            .captured
            .single as void Function(
          WKUserContentController userContentController,
          WKScriptMessage message,
        );

        didReceiveScriptMessage(
          mockUserContentController,
          const WKScriptMessage(name: 'hello', body: 'A message.'),
        );
        verify(mockJavascriptChannelRegistry.onJavascriptChannelMessage(
          'hello',
          'A message.',
        ));
      });
    });
  });
}
