Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the way to handle the error if purchase(sk2Product) fails due to an error when posting the receipt #1177

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion Purchases/Purchasing/PurchasesOrchestrator.swift
Expand Up @@ -201,8 +201,10 @@ class PurchasesOrchestrator {
let result = await purchase(sk2Product: product)
DispatchQueue.main.async {
switch result {
case .failure(let error):
case .failure(let error) where error is StoreKitError:
completion(nil, nil, ErrorUtils.purchasesError(withStoreKitError: error), false)
case .failure(let error):
completion(nil, nil, error, false)
case .success(let (customerInfo, userCancelled)):
// todo: change API and send transaction
if userCancelled {
Expand Down
30 changes: 29 additions & 1 deletion StoreKitUnitTests/PurchasesOrchestratorTests.swift
Expand Up @@ -203,6 +203,34 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(mockListener.invokedHandle) == false
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
func testPurchaseSK2PackageReturnsMissingReceiptErrorIfSendReceiptFailed() async throws {
try AvailabilityChecks.iOS15APIAvailableOrSkipTest()

receiptFetcher.shouldReturnReceipt = false
let expectedError = ErrorUtils.missingReceiptFileError()

let storeProduct = try await fetchSk2StoreProduct()
let package = Package(identifier: "package",
packageType: .monthly,
storeProduct: storeProduct,
offeringIdentifier: "offering")

let (transaction, customerInfo, error, userCancelled) = await withCheckedContinuation { continuation in
orchestrator.purchase(package: package) { transaction, customerInfo, error, userCancelled in
continuation.resume(returning: (transaction, customerInfo, error, userCancelled))
}
}

expect(transaction).to(beNil())
expect(userCancelled) == false
expect(customerInfo).to(beNil())
expect(error).toNot(beNil())
expect(error).to(matchError(expectedError))
let mockListener = try XCTUnwrap(orchestrator.storeKit2Listener as? MockStoreKit2TransactionListener)
expect(mockListener.invokedHandle) == true
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
func testStoreKit2TransactionListenerDelegate() async throws {
try AvailabilityChecks.iOS15APIAvailableOrSkipTest()
Expand All @@ -215,7 +243,7 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(self.backend.invokedPostReceiptDataParameters?.isRestore).to(beFalse())
}

func testStoreKit2TransactionListenerDelegateWithObesrverMode() async throws {
func testStoreKit2TransactionListenerDelegateWithObserverMode() async throws {
Copy link
Contributor Author

@Juanpe Juanpe Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix a typo 🙂

try AvailabilityChecks.iOS15APIAvailableOrSkipTest()

try setUpSystemInfo(finishTransactions: false)
Expand Down