import 'dart:async'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_test/flutter_test.dart'; import '../env.dart'; void interceptAjaxRequest() { final shouldSkip = kIsWeb ? true : ![ TargetPlatform.android, TargetPlatform.iOS, TargetPlatform.macOS, ].contains(defaultTargetPlatform); group('intercept ajax request', () { testWidgets('send string data', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer shouldInterceptAjaxPostRequestCompleter = Completer(); final Completer> onAjaxReadyStateChangeCompleter = Completer>(); final Completer> onAjaxProgressCompleter = Completer>(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), initialData: InAppWebViewInitialData(data: """ InAppWebViewAjaxTest

InAppWebViewAjaxTest

"""), initialSettings: InAppWebViewSettings( clearCache: true, useShouldInterceptAjaxRequest: true, ), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, shouldInterceptAjaxRequest: (controller, ajaxRequest) async { assert(ajaxRequest.data == "firstname=Foo&lastname=Bar"); ajaxRequest.responseType = 'json'; ajaxRequest.data = "firstname=Foo2&lastname=Bar2"; shouldInterceptAjaxPostRequestCompleter.complete(controller); return ajaxRequest; }, onAjaxReadyStateChange: (controller, ajaxRequest) async { if (ajaxRequest.readyState == AjaxRequestReadyState.DONE && ajaxRequest.status == 200) { Map res = ajaxRequest.response; onAjaxReadyStateChangeCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, onAjaxProgress: (controller, ajaxRequest) async { if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) { Map res = ajaxRequest.response; onAjaxProgressCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, ), ), ); await shouldInterceptAjaxPostRequestCompleter.future; final Map onAjaxReadyStateChangeValue = await onAjaxReadyStateChangeCompleter.future; final Map onAjaxProgressValue = await onAjaxProgressCompleter.future; expect( mapEquals(onAjaxReadyStateChangeValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); expect( mapEquals( onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); }); testWidgets('send json data', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer shouldInterceptAjaxPostRequestCompleter = Completer(); final Completer> onAjaxReadyStateChangeCompleter = Completer>(); final Completer> onAjaxProgressCompleter = Completer>(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), initialData: InAppWebViewInitialData(data: """ InAppWebViewAjaxTest

InAppWebViewAjaxTest

"""), initialSettings: InAppWebViewSettings( clearCache: true, useShouldInterceptAjaxRequest: true, ), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, shouldInterceptAjaxRequest: (controller, ajaxRequest) async { String data = ajaxRequest.data; assert(data.contains('"firstname":"Foo"') && data.contains('"lastname":"Bar"')); ajaxRequest.responseType = 'json'; ajaxRequest.data = '{"firstname": "Foo2", "lastname": "Bar2"}'; shouldInterceptAjaxPostRequestCompleter.complete(controller); return ajaxRequest; }, onAjaxReadyStateChange: (controller, ajaxRequest) async { if (ajaxRequest.readyState == AjaxRequestReadyState.DONE && ajaxRequest.status == 200) { Map res = ajaxRequest.response; onAjaxReadyStateChangeCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, onAjaxProgress: (controller, ajaxRequest) async { if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) { Map res = ajaxRequest.response; onAjaxProgressCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, ), ), ); await shouldInterceptAjaxPostRequestCompleter.future; final Map onAjaxReadyStateChangeValue = await onAjaxReadyStateChangeCompleter.future; final Map onAjaxProgressValue = await onAjaxProgressCompleter.future; expect( mapEquals(onAjaxReadyStateChangeValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); expect( mapEquals( onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); }); testWidgets('send URLSearchParams data', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer shouldInterceptAjaxPostRequestCompleter = Completer(); final Completer> onAjaxReadyStateChangeCompleter = Completer>(); final Completer> onAjaxProgressCompleter = Completer>(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), initialData: InAppWebViewInitialData(data: """ InAppWebViewAjaxTest

InAppWebViewAjaxTest

"""), initialSettings: InAppWebViewSettings( clearCache: true, useShouldInterceptAjaxRequest: true, ), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, shouldInterceptAjaxRequest: (controller, ajaxRequest) async { assert(ajaxRequest.data == "firstname=Foo&lastname=Bar"); ajaxRequest.responseType = 'json'; ajaxRequest.data = "firstname=Foo2&lastname=Bar2"; shouldInterceptAjaxPostRequestCompleter.complete(controller); return ajaxRequest; }, onAjaxReadyStateChange: (controller, ajaxRequest) async { if (ajaxRequest.readyState == AjaxRequestReadyState.DONE && ajaxRequest.status == 200) { Map res = ajaxRequest.response; onAjaxReadyStateChangeCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, onAjaxProgress: (controller, ajaxRequest) async { if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) { Map res = ajaxRequest.response; onAjaxProgressCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, ), ), ); await shouldInterceptAjaxPostRequestCompleter.future; final Map onAjaxReadyStateChangeValue = await onAjaxReadyStateChangeCompleter.future; final Map onAjaxProgressValue = await onAjaxProgressCompleter.future; expect( mapEquals(onAjaxReadyStateChangeValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); expect( mapEquals( onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); }); testWidgets('send FormData', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); final Completer shouldInterceptAjaxPostRequestCompleter = Completer(); final Completer> onAjaxReadyStateChangeCompleter = Completer>(); final Completer> onAjaxProgressCompleter = Completer>(); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, child: InAppWebView( key: GlobalKey(), initialData: InAppWebViewInitialData(data: """ InAppWebViewAjaxTest

InAppWebViewAjaxTest

"""), initialSettings: InAppWebViewSettings( clearCache: true, useShouldInterceptAjaxRequest: true, ), onWebViewCreated: (controller) { controllerCompleter.complete(controller); }, shouldInterceptAjaxRequest: (controller, ajaxRequest) async { assert(ajaxRequest.data != null); var body = ajaxRequest.data.cast(); var bodyString = String.fromCharCodes(body); assert(bodyString.indexOf("WebKitFormBoundary") >= 0); ajaxRequest.data = utf8.encode(bodyString .replaceFirst("Foo", "Foo2") .replaceFirst("Bar", "Bar2")); ajaxRequest.responseType = 'json'; shouldInterceptAjaxPostRequestCompleter.complete(controller); return ajaxRequest; }, onAjaxReadyStateChange: (controller, ajaxRequest) async { if (ajaxRequest.readyState == AjaxRequestReadyState.DONE && ajaxRequest.status == 200) { Map res = ajaxRequest.response; onAjaxReadyStateChangeCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, onAjaxProgress: (controller, ajaxRequest) async { if (ajaxRequest.event!.type == AjaxRequestEventType.LOAD) { Map res = ajaxRequest.response; onAjaxProgressCompleter.complete(res); } return AjaxRequestAction.PROCEED; }, ), ), ); await shouldInterceptAjaxPostRequestCompleter.future; final Map onAjaxReadyStateChangeValue = await onAjaxReadyStateChangeCompleter.future; final Map onAjaxProgressValue = await onAjaxProgressCompleter.future; expect( mapEquals(onAjaxReadyStateChangeValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); expect( mapEquals( onAjaxProgressValue, {'firstname': 'Foo2', 'lastname': 'Bar2'}), true); }); }, skip: shouldSkip); }