From 83875194f2a94ed9d1dcfc5945ea2b4c42c69912 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 12:33:04 +0200 Subject: [PATCH 01/10] Added currency code and numerical price to product detail model. --- .../lib/src/in_app_purchase/product_details.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 151086d90f92..8f96e403185a 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; import 'in_app_purchase_connection.dart'; @@ -17,6 +19,8 @@ class ProductDetails { required this.title, required this.description, required this.price, + required this.rawPrice, + required this.currencyCode, this.skProduct, this.skuDetail}); @@ -33,6 +37,13 @@ class ProductDetails { /// Formatted with currency symbol ("$0.99"). final String price; + // The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. + final double rawPrice; + + // The currency code for the price of the product. + // Based on the price specified in the App Store Connect or Sku in Google Play console based on the platform. + final String currencyCode; + /// Points back to the `StoreKits`'s [SKProductWrapper] object that generated this [ProductDetails] object. /// /// This is `null` on Android. @@ -49,6 +60,8 @@ class ProductDetails { this.title = product.localizedTitle, this.description = product.localizedDescription, this.price = product.priceLocale.currencySymbol + product.price, + this.rawPrice = double.tryParse(product.price) ?? 0, + this.currencyCode = product.priceLocale.currencyCode, this.skProduct = product, this.skuDetail = null; @@ -58,6 +71,8 @@ class ProductDetails { this.title = skuDetails.title, this.description = skuDetails.description, this.price = skuDetails.price, + this.rawPrice = ((skuDetails.priceAmountMicros) / 1000000.0).toDouble(), + this.currencyCode = skuDetails.priceCurrencyCode, this.skProduct = null, this.skuDetail = skuDetails; } From f2b38bc62615d2a9b42f3d5398ed3741b00dc904 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 12:33:04 +0200 Subject: [PATCH 02/10] Added currency code and numerical price to product detail model. --- .../lib/src/in_app_purchase/product_details.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 151086d90f92..8f96e403185a 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:io'; + import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; import 'in_app_purchase_connection.dart'; @@ -17,6 +19,8 @@ class ProductDetails { required this.title, required this.description, required this.price, + required this.rawPrice, + required this.currencyCode, this.skProduct, this.skuDetail}); @@ -33,6 +37,13 @@ class ProductDetails { /// Formatted with currency symbol ("$0.99"). final String price; + // The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. + final double rawPrice; + + // The currency code for the price of the product. + // Based on the price specified in the App Store Connect or Sku in Google Play console based on the platform. + final String currencyCode; + /// Points back to the `StoreKits`'s [SKProductWrapper] object that generated this [ProductDetails] object. /// /// This is `null` on Android. @@ -49,6 +60,8 @@ class ProductDetails { this.title = product.localizedTitle, this.description = product.localizedDescription, this.price = product.priceLocale.currencySymbol + product.price, + this.rawPrice = double.tryParse(product.price) ?? 0, + this.currencyCode = product.priceLocale.currencyCode, this.skProduct = product, this.skuDetail = null; @@ -58,6 +71,8 @@ class ProductDetails { this.title = skuDetails.title, this.description = skuDetails.description, this.price = skuDetails.price, + this.rawPrice = ((skuDetails.priceAmountMicros) / 1000000.0).toDouble(), + this.currencyCode = skuDetails.priceCurrencyCode, this.skProduct = null, this.skuDetail = skuDetails; } From dbf2793d9731c586c965a9a84238ea83ac597cfa Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 15:32:02 +0200 Subject: [PATCH 03/10] Update changelog and pubspec --- packages/in_app_purchase/in_app_purchase/CHANGELOG.md | 4 ++++ packages/in_app_purchase/in_app_purchase/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md index beb4356dc398..b7189687e604 100644 --- a/packages/in_app_purchase/in_app_purchase/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.2 + +* Added `rawPrice` and `currencyCode` to the ProductDetails model. + ## 0.5.1+2 * Update README to provide a better instruction of the plugin. diff --git a/packages/in_app_purchase/in_app_purchase/pubspec.yaml b/packages/in_app_purchase/in_app_purchase/pubspec.yaml index 5a0a3ba565ed..c7226078c722 100644 --- a/packages/in_app_purchase/in_app_purchase/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase/pubspec.yaml @@ -1,7 +1,7 @@ name: in_app_purchase description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play. homepage: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase -version: 0.5.1+2 +version: 0.5.2 dependencies: flutter: From 89f8df539f4a3813245e4be5cd2e7600db866258 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 16:10:10 +0200 Subject: [PATCH 04/10] Added unit test. Fixed analysis feedback. --- .../src/in_app_purchase/product_details.dart | 2 - .../product_details_test.dart | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 8f96e403185a..722114a0a7be 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io'; - import 'package:in_app_purchase/store_kit_wrappers.dart'; import 'package:in_app_purchase/billing_client_wrappers.dart'; import 'in_app_purchase_connection.dart'; diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart new file mode 100644 index 000000000000..debaed529667 --- /dev/null +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart @@ -0,0 +1,51 @@ +// 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 'package:flutter_test/flutter_test.dart'; +import 'package:in_app_purchase/in_app_purchase.dart'; +import 'package:in_app_purchase/src/store_kit_wrappers/sk_product_wrapper.dart'; + +void main() { + group('Constructor Tests', () { + test('fromSkProduct should correctly parse the price data', () { + final SKProductWrapper dummyProductWrapper = SKProductWrapper( + productIdentifier: 'id', + localizedTitle: 'title', + localizedDescription: 'description', + priceLocale: + SKPriceLocaleWrapper(currencySymbol: '\$', currencyCode: 'USD'), + subscriptionGroupIdentifier: 'com.group', + price: '13.37', + ); + + ProductDetails productDetails = + ProductDetails.fromSKProduct(dummyProductWrapper); + expect(productDetails.rawPrice, equals(13.37)); + }); + + test('fromSkuDetails should correctly parse the price data', () { + final SkuDetailsWrapper dummyDetailWRapper = SkuDetailsWrapper( + description: 'description', + freeTrialPeriod: 'freeTrialPeriod', + introductoryPrice: 'introductoryPrice', + introductoryPriceMicros: 'introductoryPriceMicros', + introductoryPriceCycles: 1, + introductoryPricePeriod: 'introductoryPricePeriod', + price: '13.37', + priceAmountMicros: 13370000, + priceCurrencyCode: 'usd', + sku: 'sku', + subscriptionPeriod: 'subscriptionPeriod', + title: 'title', + type: SkuType.inapp, + originalPrice: 'originalPrice', + originalPriceAmountMicros: 1000, + ); + + ProductDetails productDetails = + ProductDetails.fromSkuDetails(dummyDetailWRapper); + expect(productDetails.rawPrice, equals(13.37)); + }); + }); +} From c210e54875cafb21f4dabfd1fb2fdd8638ddb1be Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 16:12:42 +0200 Subject: [PATCH 05/10] Fix typo --- .../test/in_app_purchase_connection/product_details_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart index debaed529667..4123f1f3331d 100644 --- a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart @@ -25,7 +25,7 @@ void main() { }); test('fromSkuDetails should correctly parse the price data', () { - final SkuDetailsWrapper dummyDetailWRapper = SkuDetailsWrapper( + final SkuDetailsWrapper dummyDetailWrapper = SkuDetailsWrapper( description: 'description', freeTrialPeriod: 'freeTrialPeriod', introductoryPrice: 'introductoryPrice', @@ -44,7 +44,7 @@ void main() { ); ProductDetails productDetails = - ProductDetails.fromSkuDetails(dummyDetailWRapper); + ProductDetails.fromSkuDetails(dummyDetailWrapper); expect(productDetails.rawPrice, equals(13.37)); }); }); From e48fbc2dd1a6154c3046eb30a83f935926a2812f Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 16:18:24 +0200 Subject: [PATCH 06/10] Add missing `/` needed for dart documentation --- .../lib/src/in_app_purchase/product_details.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 722114a0a7be..36fd069d3068 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -35,11 +35,11 @@ class ProductDetails { /// Formatted with currency symbol ("$0.99"). final String price; - // The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. + /// The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. final double rawPrice; - // The currency code for the price of the product. - // Based on the price specified in the App Store Connect or Sku in Google Play console based on the platform. + /// The currency code for the price of the product. + /// Based on the price specified in the App Store Connect or Sku in Google Play console based on the platform. final String currencyCode; /// Points back to the `StoreKits`'s [SKProductWrapper] object that generated this [ProductDetails] object. From 28d25187506d87a1dc02688dd09cf5a5ad7bb565 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 7 Apr 2021 16:41:53 +0200 Subject: [PATCH 07/10] Change double parse --- .../lib/src/in_app_purchase/product_details.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 36fd069d3068..1fb99ea8ff48 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -58,7 +58,7 @@ class ProductDetails { this.title = product.localizedTitle, this.description = product.localizedDescription, this.price = product.priceLocale.currencySymbol + product.price, - this.rawPrice = double.tryParse(product.price) ?? 0, + this.rawPrice = double.parse(product.price), this.currencyCode = product.priceLocale.currencyCode, this.skProduct = product, this.skuDetail = null; From 277b96b13a74253bdb09ff9e62da2a630de05567 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 8 Apr 2021 09:44:38 +0200 Subject: [PATCH 08/10] Improved property documentation --- .../in_app_purchase/lib/src/in_app_purchase/product_details.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index 1fb99ea8ff48..fd23962b6b53 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -36,6 +36,7 @@ class ProductDetails { final String price; /// The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. + /// The currency unit for this value can be found in the [currencyCode] property. final double rawPrice; /// The currency code for the price of the product. From 9cefe81884fd2bcf048967bec9c4a772e1f7ecfc Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Thu, 8 Apr 2021 09:49:37 +0200 Subject: [PATCH 09/10] Improved function documentation --- .../in_app_purchase/lib/src/in_app_purchase/product_details.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart index fd23962b6b53..ccdec42b7303 100644 --- a/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart +++ b/packages/in_app_purchase/in_app_purchase/lib/src/in_app_purchase/product_details.dart @@ -37,6 +37,7 @@ class ProductDetails { /// The unformatted price of the product, specified in the App Store Connect or Sku in Google Play console based on the platform. /// The currency unit for this value can be found in the [currencyCode] property. + /// The value always describes full units of the currency. (e.g. 2.45 in the case of $2.45) final double rawPrice; /// The currency code for the price of the product. From 5e49a4f613188949cafaf88d5918c3374168da57 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Fri, 9 Apr 2021 12:06:51 +0200 Subject: [PATCH 10/10] Expand unit tests --- .../product_details_test.dart | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart index 4123f1f3331d..a67baf8f5dc6 100644 --- a/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart +++ b/packages/in_app_purchase/in_app_purchase/test/in_app_purchase_connection/product_details_test.dart @@ -8,7 +8,9 @@ import 'package:in_app_purchase/src/store_kit_wrappers/sk_product_wrapper.dart'; void main() { group('Constructor Tests', () { - test('fromSkProduct should correctly parse the price data', () { + test( + 'fromSkProduct should correctly parse data from a SKProductWrapper instance.', + () { final SKProductWrapper dummyProductWrapper = SKProductWrapper( productIdentifier: 'id', localizedTitle: 'title', @@ -21,10 +23,20 @@ void main() { ProductDetails productDetails = ProductDetails.fromSKProduct(dummyProductWrapper); + expect(productDetails.id, equals(dummyProductWrapper.productIdentifier)); + expect(productDetails.title, equals(dummyProductWrapper.localizedTitle)); + expect(productDetails.description, + equals(dummyProductWrapper.localizedDescription)); expect(productDetails.rawPrice, equals(13.37)); + expect(productDetails.currencyCode, + equals(dummyProductWrapper.priceLocale.currencyCode)); + expect(productDetails.skProduct, equals(dummyProductWrapper)); + expect(productDetails.skuDetail, isNull); }); - test('fromSkuDetails should correctly parse the price data', () { + test( + 'fromSkuDetails should correctly parse data from a SkuDetailsWrapper instance', + () { final SkuDetailsWrapper dummyDetailWrapper = SkuDetailsWrapper( description: 'description', freeTrialPeriod: 'freeTrialPeriod', @@ -45,7 +57,16 @@ void main() { ProductDetails productDetails = ProductDetails.fromSkuDetails(dummyDetailWrapper); + expect(productDetails.id, equals(dummyDetailWrapper.sku)); + expect(productDetails.title, equals(dummyDetailWrapper.title)); + expect( + productDetails.description, equals(dummyDetailWrapper.description)); + expect(productDetails.price, equals(dummyDetailWrapper.price)); expect(productDetails.rawPrice, equals(13.37)); + expect(productDetails.currencyCode, + equals(dummyDetailWrapper.priceCurrencyCode)); + expect(productDetails.skProduct, isNull); + expect(productDetails.skuDetail, equals(dummyDetailWrapper)); }); }); }