From 1987808d6f0d3c17465d3b062269629dbcb70af1 Mon Sep 17 00:00:00 2001 From: Mark Villacampa Date: Fri, 5 Jul 2024 14:39:36 +0200 Subject: [PATCH 1/2] Raise error if no app transactions and no transactions present --- .../Purchases/PurchasesOrchestrator.swift | 8 +++++++ .../PurchasesOrchestratorSK2Tests.swift | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift index fafa1cbd4c..08ef6e68c7 100644 --- a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift +++ b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift @@ -1129,6 +1129,14 @@ private extension PurchasesOrchestrator { return } + // We dont have an AppTransactionJWS, and no transaction, return error + if appTransactionJWS == nil { + completion?(.failure(ErrorUtils.storeProblemError( + withMessage: Strings.storeKit.sk2_app_transaction_unavailable.description + ))) + return + } + self.backend.post(receipt: .empty, productData: nil, transactionData: .init(appUserID: currentAppUserID, diff --git a/Tests/StoreKitUnitTests/PurchasesOrchestratorSK2Tests.swift b/Tests/StoreKitUnitTests/PurchasesOrchestratorSK2Tests.swift index ee1632319c..8447793976 100644 --- a/Tests/StoreKitUnitTests/PurchasesOrchestratorSK2Tests.swift +++ b/Tests/StoreKitUnitTests/PurchasesOrchestratorSK2Tests.swift @@ -726,6 +726,27 @@ class PurchasesOrchestratorSK2Tests: BasePurchasesOrchestratorTests, PurchasesOr expect(customerInfo) == mockCustomerInfo } + func testSyncPurchasesSK2DoesNotPostReceiptAndRaisesErrorIfNoTransactionsAndNoAppTransactionJWSToken() + async throws { + self.mockTransactionFetcher.stubbedFirstVerifiedTransaction = nil + self.mockTransactionFetcher.stubbedAppTransactionJWS = nil + self.customerInfoManager.stubbedCachedCustomerInfoResult = CustomerInfo.missingOriginalApplicationVersion + + do { + _ = try await self.orchestrator.syncPurchases(receiptRefreshPolicy: .always, + isRestore: true, + initiationSource: .restore) + fail("Expected error") + } catch { + expect(error).to(matchError(ErrorCode.storeProblemError)) + } + + expect(self.backend.invokedPostReceiptData).to(beFalse()) + + expect(self.customerInfoManager.invokedCachedCustomerInfo).to(beTrue()) + expect(self.customerInfoManager.invokedCachedCustomerInfoCount) == 1 + } + func testSyncPurchasesCallsSuccessDelegateMethod() async throws { let transaction = try await createTransaction(finished: true) self.mockTransactionFetcher.stubbedFirstVerifiedTransaction = transaction From af1f0ddf630144d40121f30e6d6211e1f7a6d36f Mon Sep 17 00:00:00 2001 From: Mark Villacampa Date: Tue, 16 Jul 2024 20:55:11 +0200 Subject: [PATCH 2/2] dispatch on main thread --- Sources/Purchasing/Purchases/PurchasesOrchestrator.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift index 08ef6e68c7..77fb432e32 100644 --- a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift +++ b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift @@ -1131,9 +1131,11 @@ private extension PurchasesOrchestrator { // We dont have an AppTransactionJWS, and no transaction, return error if appTransactionJWS == nil { - completion?(.failure(ErrorUtils.storeProblemError( - withMessage: Strings.storeKit.sk2_app_transaction_unavailable.description - ))) + self.operationDispatcher.dispatchOnMainActor { + completion?(.failure(ErrorUtils.storeProblemError( + withMessage: Strings.storeKit.sk2_app_transaction_unavailable.description + ))) + } return }