// 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:async';

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart' as widgets;
import 'package:flutter_test/flutter_test.dart';
import 'package:in_app_purchase_android/billing_client_wrappers.dart';
import 'package:in_app_purchase_android/in_app_purchase_android.dart';
import 'package:in_app_purchase_android/src/channel.dart';
import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart';

import 'billing_client_wrappers/purchase_wrapper_test.dart';
import 'billing_client_wrappers/sku_details_wrapper_test.dart';
import 'stub_in_app_purchase_platform.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  final StubInAppPurchasePlatform stubPlatform = StubInAppPurchasePlatform();
  late InAppPurchaseAndroidPlatform iapAndroidPlatform;
  const String startConnectionCall =
      'BillingClient#startConnection(BillingClientStateListener)';
  const String endConnectionCall = 'BillingClient#endConnection()';

  setUpAll(() {
    channel.setMockMethodCallHandler(stubPlatform.fakeMethodCallHandler);
  });

  setUp(() {
    widgets.WidgetsFlutterBinding.ensureInitialized();

    const String debugMessage = 'dummy message';
    const BillingResponse responseCode = BillingResponse.ok;
    const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
        responseCode: responseCode, debugMessage: debugMessage);
    stubPlatform.addResponse(
        name: startConnectionCall,
        value: buildBillingResultMap(expectedBillingResult));
    stubPlatform.addResponse(name: endConnectionCall, value: null);

    InAppPurchaseAndroidPlatform.registerPlatform();
    iapAndroidPlatform =
        InAppPurchasePlatform.instance as InAppPurchaseAndroidPlatform;
  });

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

  group('connection management', () {
    test('connects on initialization', () {
      //await iapAndroidPlatform.isAvailable();
      expect(stubPlatform.countPreviousCalls(startConnectionCall), equals(1));
    });
  });

  group('isAvailable', () {
    test('true', () async {
      stubPlatform.addResponse(name: 'BillingClient#isReady()', value: true);
      expect(await iapAndroidPlatform.isAvailable(), isTrue);
    });

    test('false', () async {
      stubPlatform.addResponse(name: 'BillingClient#isReady()', value: false);
      expect(await iapAndroidPlatform.isAvailable(), isFalse);
    });
  });

  group('querySkuDetails', () {
    const String queryMethodName =
        'BillingClient#querySkuDetailsAsync(SkuDetailsParams, SkuDetailsResponseListener)';

    test('handles empty skuDetails', () async {
      const String debugMessage = 'dummy message';
      const BillingResponse responseCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      stubPlatform.addResponse(name: queryMethodName, value: <String, dynamic>{
        'billingResult': buildBillingResultMap(expectedBillingResult),
        'skuDetailsList': <Map<String, dynamic>>[],
      });

      final ProductDetailsResponse response =
          await iapAndroidPlatform.queryProductDetails(<String>{''});
      expect(response.productDetails, isEmpty);
    });

    test('should get correct product details', () async {
      const String debugMessage = 'dummy message';
      const BillingResponse responseCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      stubPlatform.addResponse(name: queryMethodName, value: <String, dynamic>{
        'billingResult': buildBillingResultMap(expectedBillingResult),
        'skuDetailsList': <Map<String, dynamic>>[buildSkuMap(dummySkuDetails)]
      });
      // Since queryProductDetails makes 2 platform method calls (one for each SkuType), the result will contain 2 dummyWrapper instead
      // of 1.
      final ProductDetailsResponse response =
          await iapAndroidPlatform.queryProductDetails(<String>{'valid'});
      expect(response.productDetails.first.title, dummySkuDetails.title);
      expect(response.productDetails.first.description,
          dummySkuDetails.description);
      expect(response.productDetails.first.price, dummySkuDetails.price);
      expect(response.productDetails.first.currencySymbol, r'$');
    });

    test('should get the correct notFoundIDs', () async {
      const String debugMessage = 'dummy message';
      const BillingResponse responseCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      stubPlatform.addResponse(name: queryMethodName, value: <String, dynamic>{
        'billingResult': buildBillingResultMap(expectedBillingResult),
        'skuDetailsList': <Map<String, dynamic>>[buildSkuMap(dummySkuDetails)]
      });
      // Since queryProductDetails makes 2 platform method calls (one for each SkuType), the result will contain 2 dummyWrapper instead
      // of 1.
      final ProductDetailsResponse response =
          await iapAndroidPlatform.queryProductDetails(<String>{'invalid'});
      expect(response.notFoundIDs.first, 'invalid');
    });

    test(
        'should have error stored in the response when platform exception is thrown',
        () async {
      const BillingResponse responseCode = BillingResponse.ok;
      stubPlatform.addResponse(
          name: queryMethodName,
          value: <String, dynamic>{
            'responseCode':
                const BillingResponseConverter().toJson(responseCode),
            'skuDetailsList': <Map<String, dynamic>>[
              buildSkuMap(dummySkuDetails)
            ]
          },
          additionalStepBeforeReturn: (dynamic _) {
            throw PlatformException(
              code: 'error_code',
              message: 'error_message',
              details: <dynamic, dynamic>{'info': 'error_info'},
            );
          });
      // Since queryProductDetails makes 2 platform method calls (one for each SkuType), the result will contain 2 dummyWrapper instead
      // of 1.
      final ProductDetailsResponse response =
          await iapAndroidPlatform.queryProductDetails(<String>{'invalid'});
      expect(response.notFoundIDs, <String>['invalid']);
      expect(response.productDetails, isEmpty);
      expect(response.error, isNotNull);
      expect(response.error!.source, kIAPSource);
      expect(response.error!.code, 'error_code');
      expect(response.error!.message, 'error_message');
      expect(response.error!.details, <String, dynamic>{'info': 'error_info'});
    });
  });

  group('restorePurchases', () {
    const String queryMethodName = 'BillingClient#queryPurchases(String)';
    test('handles error', () async {
      const String debugMessage = 'dummy message';
      const BillingResponse responseCode = BillingResponse.developerError;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);

      stubPlatform.addResponse(name: queryMethodName, value: <dynamic, dynamic>{
        'billingResult': buildBillingResultMap(expectedBillingResult),
        'responseCode': const BillingResponseConverter().toJson(responseCode),
        'purchasesList': <Map<String, dynamic>>[]
      });

      expect(
        iapAndroidPlatform.restorePurchases(),
        throwsA(
          isA<InAppPurchaseException>()
              .having(
                  (InAppPurchaseException e) => e.source, 'source', kIAPSource)
              .having((InAppPurchaseException e) => e.code, 'code',
                  kRestoredPurchaseErrorCode)
              .having((InAppPurchaseException e) => e.message, 'message',
                  responseCode.toString()),
        ),
      );
    });

    test('should store platform exception in the response', () async {
      const String debugMessage = 'dummy message';

      const BillingResponse responseCode = BillingResponse.developerError;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: queryMethodName,
          value: <dynamic, dynamic>{
            'responseCode':
                const BillingResponseConverter().toJson(responseCode),
            'billingResult': buildBillingResultMap(expectedBillingResult),
            'purchasesList': <Map<String, dynamic>>[]
          },
          additionalStepBeforeReturn: (dynamic _) {
            throw PlatformException(
              code: 'error_code',
              message: 'error_message',
              details: <dynamic, dynamic>{'info': 'error_info'},
            );
          });

      expect(
        iapAndroidPlatform.restorePurchases(),
        throwsA(
          isA<PlatformException>()
              .having((PlatformException e) => e.code, 'code', 'error_code')
              .having((PlatformException e) => e.message, 'message',
                  'error_message')
              .having((PlatformException e) => e.details, 'details',
                  <String, dynamic>{'info': 'error_info'}),
        ),
      );
    });

    test('returns SkuDetailsResponseWrapper', () async {
      final Completer<List<PurchaseDetails>> completer =
          Completer<List<PurchaseDetails>>();
      final Stream<List<PurchaseDetails>> stream =
          iapAndroidPlatform.purchaseStream;

      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = stream.listen((List<PurchaseDetails> purchaseDetailsList) {
        if (purchaseDetailsList.first.status == PurchaseStatus.restored) {
          completer.complete(purchaseDetailsList);
          subscription.cancel();
        }
      });

      const String debugMessage = 'dummy message';
      const BillingResponse responseCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: responseCode, debugMessage: debugMessage);

      stubPlatform.addResponse(name: queryMethodName, value: <String, dynamic>{
        'billingResult': buildBillingResultMap(expectedBillingResult),
        'responseCode': const BillingResponseConverter().toJson(responseCode),
        'purchasesList': <Map<String, dynamic>>[
          buildPurchaseMap(dummyPurchase),
        ]
      });

      // Since queryPastPurchases makes 2 platform method calls (one for each
      // SkuType), the result will contain 2 dummyPurchase instances instead
      // of 1.
      await iapAndroidPlatform.restorePurchases();
      final List<PurchaseDetails> restoredPurchases = await completer.future;

      expect(restoredPurchases.length, 2);
      for (final PurchaseDetails element in restoredPurchases) {
        final GooglePlayPurchaseDetails purchase =
            element as GooglePlayPurchaseDetails;

        expect(purchase.productID, dummyPurchase.sku);
        expect(purchase.purchaseID, dummyPurchase.orderId);
        expect(purchase.verificationData.localVerificationData,
            dummyPurchase.originalJson);
        expect(purchase.verificationData.serverVerificationData,
            dummyPurchase.purchaseToken);
        expect(purchase.verificationData.source, kIAPSource);
        expect(purchase.transactionDate, dummyPurchase.purchaseTime.toString());
        expect(purchase.billingClientPurchase, dummyPurchase);
        expect(purchase.status, PurchaseStatus.restored);
      }
    });
  });

  group('make payment', () {
    const String launchMethodName =
        'BillingClient#launchBillingFlow(Activity, BillingFlowParams)';
    const String consumeMethodName =
        'BillingClient#consumeAsync(String, ConsumeResponseListener)';

    test('buy non consumable, serializes and deserializes data', () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);

      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': <dynamic>[
                <dynamic, dynamic>{
                  'orderId': 'orderID1',
                  'sku': skuDetails.sku,
                  'isAutoRenewing': false,
                  'packageName': 'package',
                  'purchaseTime': 1231231231,
                  'purchaseToken': 'token',
                  'signature': 'sign',
                  'originalJson': 'json',
                  'developerPayload': 'dummy payload',
                  'isAcknowledged': true,
                  'purchaseState': 1,
                }
              ]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      final bool launchResult = await iapAndroidPlatform.buyNonConsumable(
          purchaseParam: purchaseParam);

      final PurchaseDetails result = await completer.future;
      expect(launchResult, isTrue);
      expect(result.purchaseID, 'orderID1');
      expect(result.status, PurchaseStatus.purchased);
      expect(result.productID, dummySkuDetails.sku);
    });

    test('handles an error with an empty purchases list', () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.error;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);

      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': const <dynamic>[]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      await iapAndroidPlatform.buyNonConsumable(purchaseParam: purchaseParam);
      final PurchaseDetails result = await completer.future;

      expect(result.error, isNotNull);
      expect(result.error!.source, kIAPSource);
      expect(result.status, PurchaseStatus.error);
      expect(result.purchaseID, isEmpty);
    });

    test('buy consumable with auto consume, serializes and deserializes data',
        () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);

      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': <dynamic>[
                <dynamic, dynamic>{
                  'orderId': 'orderID1',
                  'sku': skuDetails.sku,
                  'isAutoRenewing': false,
                  'packageName': 'package',
                  'purchaseTime': 1231231231,
                  'purchaseToken': 'token',
                  'signature': 'sign',
                  'originalJson': 'json',
                  'developerPayload': 'dummy payload',
                  'isAcknowledged': true,
                  'purchaseState': 1,
                }
              ]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<String> consumeCompleter = Completer<String>();
      // adding call back for consume purchase
      const BillingResponse expectedCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResultForConsume =
          BillingResultWrapper(
              responseCode: expectedCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: consumeMethodName,
          value: buildBillingResultMap(expectedBillingResultForConsume),
          additionalStepBeforeReturn: (dynamic args) {
            final String purchaseToken = args['purchaseToken'] as String;
            consumeCompleter.complete(purchaseToken);
          });

      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      final bool launchResult =
          await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam);

      // Verify that the result has succeeded
      final GooglePlayPurchaseDetails result =
          await completer.future as GooglePlayPurchaseDetails;
      expect(launchResult, isTrue);
      expect(result.billingClientPurchase, isNotNull);
      expect(result.billingClientPurchase.purchaseToken,
          await consumeCompleter.future);
      expect(result.status, PurchaseStatus.purchased);
      expect(result.error, isNull);
    });

    test('buyNonConsumable propagates failures to launch the billing flow',
        () async {
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.error;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult));

      final bool result = await iapAndroidPlatform.buyNonConsumable(
          purchaseParam: GooglePlayPurchaseParam(
              productDetails:
                  GooglePlayProductDetails.fromSkuDetails(dummySkuDetails)));

      // Verify that the failure has been converted and returned
      expect(result, isFalse);
    });

    test('buyConsumable propagates failures to launch the billing flow',
        () async {
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.developerError;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
        name: launchMethodName,
        value: buildBillingResultMap(expectedBillingResult),
      );

      final bool result = await iapAndroidPlatform.buyConsumable(
          purchaseParam: GooglePlayPurchaseParam(
              productDetails:
                  GooglePlayProductDetails.fromSkuDetails(dummySkuDetails)));

      // Verify that the failure has been converted and returned
      expect(result, isFalse);
    });

    test('adds consumption failures to PurchaseDetails objects', () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': <dynamic>[
                <dynamic, dynamic>{
                  'orderId': 'orderID1',
                  'sku': skuDetails.sku,
                  'isAutoRenewing': false,
                  'packageName': 'package',
                  'purchaseTime': 1231231231,
                  'purchaseToken': 'token',
                  'signature': 'sign',
                  'originalJson': 'json',
                  'developerPayload': 'dummy payload',
                  'isAcknowledged': true,
                  'purchaseState': 1,
                }
              ]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<String> consumeCompleter = Completer<String>();
      // adding call back for consume purchase
      const BillingResponse expectedCode = BillingResponse.error;
      const BillingResultWrapper expectedBillingResultForConsume =
          BillingResultWrapper(
              responseCode: expectedCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: consumeMethodName,
          value: buildBillingResultMap(expectedBillingResultForConsume),
          additionalStepBeforeReturn: (dynamic args) {
            final String purchaseToken = args['purchaseToken'] as String;
            consumeCompleter.complete(purchaseToken);
          });

      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam);

      // Verify that the result has an error for the failed consumption
      final GooglePlayPurchaseDetails result =
          await completer.future as GooglePlayPurchaseDetails;
      expect(result.billingClientPurchase, isNotNull);
      expect(result.billingClientPurchase.purchaseToken,
          await consumeCompleter.future);
      expect(result.status, PurchaseStatus.error);
      expect(result.error, isNotNull);
      expect(result.error!.code, kConsumptionFailedErrorCode);
    });

    test(
        'buy consumable without auto consume, consume api should not receive calls',
        () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.developerError;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);

      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': <dynamic>[
                <dynamic, dynamic>{
                  'orderId': 'orderID1',
                  'sku': skuDetails.sku,
                  'isAutoRenewing': false,
                  'packageName': 'package',
                  'purchaseTime': 1231231231,
                  'purchaseToken': 'token',
                  'signature': 'sign',
                  'originalJson': 'json',
                  'developerPayload': 'dummy payload',
                  'isAcknowledged': true,
                  'purchaseState': 1,
                }
              ]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<String?> consumeCompleter = Completer<String?>();
      // adding call back for consume purchase
      const BillingResponse expectedCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResultForConsume =
          BillingResultWrapper(
              responseCode: expectedCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: consumeMethodName,
          value: buildBillingResultMap(expectedBillingResultForConsume),
          additionalStepBeforeReturn: (dynamic args) {
            final String purchaseToken = args['purchaseToken'] as String;
            consumeCompleter.complete(purchaseToken);
          });

      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        consumeCompleter.complete(null);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      await iapAndroidPlatform.buyConsumable(
          purchaseParam: purchaseParam, autoConsume: false);
      expect(null, await consumeCompleter.future);
    });

    test(
        'should get canceled purchase status when response code is BillingResponse.userCanceled',
        () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.userCanceled;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': <dynamic>[
                <dynamic, dynamic>{
                  'orderId': 'orderID1',
                  'sku': skuDetails.sku,
                  'isAutoRenewing': false,
                  'packageName': 'package',
                  'purchaseTime': 1231231231,
                  'purchaseToken': 'token',
                  'signature': 'sign',
                  'originalJson': 'json',
                  'developerPayload': 'dummy payload',
                  'isAcknowledged': true,
                  'purchaseState': 1,
                }
              ]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });
      final Completer<String> consumeCompleter = Completer<String>();
      // adding call back for consume purchase
      const BillingResponse expectedCode = BillingResponse.userCanceled;
      const BillingResultWrapper expectedBillingResultForConsume =
          BillingResultWrapper(
              responseCode: expectedCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: consumeMethodName,
          value: buildBillingResultMap(expectedBillingResultForConsume),
          additionalStepBeforeReturn: (dynamic args) {
            final String purchaseToken = args['purchaseToken'] as String;
            consumeCompleter.complete(purchaseToken);
          });

      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId);
      await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam);

      // Verify that the result has an error for the failed consumption
      final GooglePlayPurchaseDetails result =
          await completer.future as GooglePlayPurchaseDetails;
      expect(result.status, PurchaseStatus.canceled);
    });

    test(
        'should get purchased purchase status when upgrading subscription by deferred proration mode',
        () async {
      const SkuDetailsWrapper skuDetails = dummySkuDetails;
      const String accountId = 'hashedAccountId';
      const String debugMessage = 'dummy message';
      const BillingResponse sentCode = BillingResponse.ok;
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: sentCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
          name: launchMethodName,
          value: buildBillingResultMap(expectedBillingResult),
          additionalStepBeforeReturn: (dynamic _) {
            // Mock java update purchase callback.
            final MethodCall call =
                MethodCall(kOnPurchasesUpdated, <dynamic, dynamic>{
              'billingResult': buildBillingResultMap(expectedBillingResult),
              'responseCode': const BillingResponseConverter().toJson(sentCode),
              'purchasesList': const <dynamic>[]
            });
            iapAndroidPlatform.billingClient.callHandler(call);
          });

      final Completer<PurchaseDetails> completer = Completer<PurchaseDetails>();
      PurchaseDetails purchaseDetails;
      final Stream<List<PurchaseDetails>> purchaseStream =
          iapAndroidPlatform.purchaseStream;
      late StreamSubscription<List<PurchaseDetails>> subscription;
      subscription = purchaseStream.listen((_) {
        purchaseDetails = _.first;
        completer.complete(purchaseDetails);
        subscription.cancel();
      }, onDone: () {});
      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
          applicationUserName: accountId,
          changeSubscriptionParam: ChangeSubscriptionParam(
            oldPurchaseDetails: GooglePlayPurchaseDetails.fromPurchase(
                dummyUnacknowledgedPurchase),
            prorationMode: ProrationMode.deferred,
          ));
      await iapAndroidPlatform.buyNonConsumable(purchaseParam: purchaseParam);

      final PurchaseDetails result = await completer.future;
      expect(result.status, PurchaseStatus.purchased);
    });
  });

  group('complete purchase', () {
    const String completeMethodName =
        'BillingClient#(AcknowledgePurchaseParams params, (AcknowledgePurchaseParams, AcknowledgePurchaseResponseListener)';
    test('complete purchase success', () async {
      const BillingResponse expectedCode = BillingResponse.ok;
      const String debugMessage = 'dummy message';
      const BillingResultWrapper expectedBillingResult = BillingResultWrapper(
          responseCode: expectedCode, debugMessage: debugMessage);
      stubPlatform.addResponse(
        name: completeMethodName,
        value: buildBillingResultMap(expectedBillingResult),
      );
      final PurchaseDetails purchaseDetails =
          GooglePlayPurchaseDetails.fromPurchase(dummyUnacknowledgedPurchase);
      final Completer<BillingResultWrapper> completer =
          Completer<BillingResultWrapper>();
      purchaseDetails.status = PurchaseStatus.purchased;
      if (purchaseDetails.pendingCompletePurchase) {
        final BillingResultWrapper billingResultWrapper =
            await iapAndroidPlatform.completePurchase(purchaseDetails);
        expect(billingResultWrapper, equals(expectedBillingResult));
        completer.complete(billingResultWrapper);
      }
      expect(await completer.future, equals(expectedBillingResult));
    });
  });
}
