@@ -20,6 +20,33 @@ import 'billing_client_wrappers/product_details_wrapper_test.dart';
20
20
import 'billing_client_wrappers/purchase_wrapper_test.dart' ;
21
21
import 'test_conversion_utils.dart' ;
22
22
23
+ const ProductDetailsWrapper dummySubscriptionProductDetails =
24
+ ProductDetailsWrapper (
25
+ description: 'description' ,
26
+ name: 'name' ,
27
+ productId: 'productId' ,
28
+ productType: ProductType .subs,
29
+ title: 'title' ,
30
+ subscriptionOfferDetails: < SubscriptionOfferDetailsWrapper > [
31
+ SubscriptionOfferDetailsWrapper (
32
+ basePlanId: 'basePlanId' ,
33
+ offerTags: < String > ['offerTags' ],
34
+ offerId: 'offerId' ,
35
+ offerIdToken: 'offerToken' ,
36
+ pricingPhases: < PricingPhaseWrapper > [
37
+ PricingPhaseWrapper (
38
+ billingCycleCount: 4 ,
39
+ billingPeriod: 'billingPeriod' ,
40
+ formattedPrice: r'$100' ,
41
+ priceAmountMicros: 100000000 ,
42
+ priceCurrencyCode: 'USD' ,
43
+ recurrenceMode: RecurrenceMode .finiteRecurring,
44
+ ),
45
+ ],
46
+ ),
47
+ ],
48
+ );
49
+
23
50
void main () {
24
51
TestWidgetsFlutterBinding .ensureInitialized ();
25
52
@@ -255,6 +282,67 @@ void main() {
255
282
});
256
283
257
284
group ('make payment' , () {
285
+ test ('buy non consumable subscribe offer, serializes and deserializes data' ,
286
+ () async {
287
+ const ProductDetailsWrapper productDetails =
288
+ dummySubscriptionProductDetails;
289
+ const String accountId = 'hashedAccountId' ;
290
+ const String debugMessage = 'dummy message' ;
291
+ const BillingResponse sentCode = BillingResponse .ok;
292
+ const BillingResultWrapper expectedBillingResult = BillingResultWrapper (
293
+ responseCode: sentCode, debugMessage: debugMessage);
294
+
295
+ when (mockApi.launchBillingFlow (any)).thenAnswer ((_) async {
296
+ // Mock java update purchase callback.
297
+ iapAndroidPlatform.billingClientManager.client.hostCallbackHandler
298
+ .onPurchasesUpdated (PlatformPurchasesResponse (
299
+ billingResult: convertToPigeonResult (expectedBillingResult),
300
+ purchases: < PlatformPurchase > [
301
+ PlatformPurchase (
302
+ orderId: 'orderID1' ,
303
+ products: < String > [productDetails.productId],
304
+ isAutoRenewing: false ,
305
+ packageName: 'package' ,
306
+ purchaseTime: 1231231231 ,
307
+ purchaseToken: 'token' ,
308
+ signature: 'sign' ,
309
+ originalJson: 'json' ,
310
+ developerPayload: 'dummy payload' ,
311
+ isAcknowledged: true ,
312
+ purchaseState: PlatformPurchaseState .purchased,
313
+ quantity: 1 ,
314
+ )
315
+ ],
316
+ ));
317
+
318
+ return convertToPigeonResult (expectedBillingResult);
319
+ });
320
+ final Completer <PurchaseDetails > completer = Completer <PurchaseDetails >();
321
+ PurchaseDetails purchaseDetails;
322
+ final Stream <List <PurchaseDetails >> purchaseStream =
323
+ iapAndroidPlatform.purchaseStream;
324
+ late StreamSubscription <List <PurchaseDetails >> subscription;
325
+ subscription = purchaseStream.listen ((List <PurchaseDetails > details) {
326
+ purchaseDetails = details.first;
327
+ completer.complete (purchaseDetails);
328
+ subscription.cancel ();
329
+ }, onDone: () {});
330
+ final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam (
331
+ offerToken:
332
+ productDetails.subscriptionOfferDetails? .first.offerIdToken,
333
+ productDetails:
334
+ GooglePlayProductDetails .fromProductDetails (productDetails).first,
335
+ applicationUserName: accountId);
336
+ final bool launchResult = await iapAndroidPlatform.buyNonConsumable (
337
+ purchaseParam: purchaseParam);
338
+
339
+ final PurchaseDetails result = await completer.future;
340
+ expect (launchResult, isTrue);
341
+ expect (result.purchaseID, 'orderID1' );
342
+ expect (result.status, PurchaseStatus .purchased);
343
+ expect (result.productID, productDetails.productId);
344
+ });
345
+
258
346
test ('buy non consumable, serializes and deserializes data' , () async {
259
347
const ProductDetailsWrapper productDetails = dummyOneTimeProductDetails;
260
348
const String accountId = 'hashedAccountId' ;
0 commit comments