From 67b1d0b1c3c274458c0403b848e8b99a474467bb Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Wed, 2 Nov 2022 10:51:00 -0700 Subject: [PATCH] `eligiblePromotionalOffers`: don't log error if response is ineligible When calling this method, we were logging a message saying that determining eligibility failed, when in fact it didn't. It successfully detected that it's not eligible. I've also added a small test for this scenario. --- Sources/Misc/Purchases+async.swift | 2 + .../PurchasesOrchestratorTests.swift | 44 +++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Sources/Misc/Purchases+async.swift b/Sources/Misc/Purchases+async.swift index 6ae7d163d9..558333dbf0 100644 --- a/Sources/Misc/Purchases+async.swift +++ b/Sources/Misc/Purchases+async.swift @@ -150,6 +150,8 @@ extension Purchases { forProductDiscount: discount, product: product ) + } catch RevenueCat.ErrorCode.ineligibleError { + return nil } catch { Logger.error( Strings.purchase.check_eligibility_failed( diff --git a/Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift b/Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift index e1fd123db5..286041153d 100644 --- a/Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift +++ b/Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift @@ -194,9 +194,8 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase { expect(self.backend.invokedPostReceiptDataParameters?.productData).toNot(beNil()) } - func testPurchaseSK1PromotionalOffer() async throws { + func testGetSK1PromotionalOffer() async throws { customerInfoManager.stubbedCachedCustomerInfoResult = mockCustomerInfo - backend.stubbedPostReceiptResult = .success(mockCustomerInfo) offerings.stubbedPostOfferCompletionResult = .success(("signature", "identifier", UUID(), 12345)) let product = try await fetchSk1Product() @@ -210,16 +209,55 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase { numberOfPeriods: 2, type: .promotional) - _ = try await Async.call { completion in + let result = try await Async.call { completion in orchestrator.promotionalOffer(forProductDiscount: storeProductDiscount, product: StoreProduct(sk1Product: product), completion: completion) } + expect(result.signedData.identifier) == storeProductDiscount.offerIdentifier + expect(self.offerings.invokedPostOfferCount) == 1 expect(self.offerings.invokedPostOfferParameters?.offerIdentifier) == storeProductDiscount.offerIdentifier } + func testGetSK1PromotionalOfferFailsWithIneligibleDiscount() async throws { + self.customerInfoManager.stubbedCachedCustomerInfoResult = mockCustomerInfo + self.offerings.stubbedPostOfferCompletionResult = .failure( + .networkError( + .errorResponse( + .init(code: .userIneligibleForPromoOffer), + .success + ) + ) + ) + + let product = try await self.fetchSk1Product() + + let storeProductDiscount = MockStoreProductDiscount(offerIdentifier: "offerid1", + currencyCode: product.priceLocale.currencyCode, + price: 11.1, + localizedPriceString: "$11.10", + paymentMode: .payAsYouGo, + subscriptionPeriod: .init(value: 1, unit: .month), + numberOfPeriods: 2, + type: .promotional) + + do { + _ = try await Async.call { completion in + self.orchestrator.promotionalOffer(forProductDiscount: storeProductDiscount, + product: StoreProduct(sk1Product: product), + completion: completion) + } + + fail("Expected error") + } catch let purchasesError as PurchasesError { + expect(purchasesError.error).to(matchError(ErrorCode.ineligibleError)) + } catch { + fail("Unexpected error: \(error)") + } + } + func testPurchaseSK1PackageWithDiscountSendsReceiptToBackendIfSuccessful() async throws { customerInfoManager.stubbedCachedCustomerInfoResult = mockCustomerInfo offerings.stubbedPostOfferCompletionResult = .success(("signature", "identifier", UUID(), 12345))