ReceiptRefreshPolicy.retryUntilProductIsFound: default to returning "invalid" receipt#2024
Conversation
… "invalid" receipt See #1945. To make this retry mechanism less risky when eventually enabled, this change makes the "worst case scenario" (where retrying didn't help, or `AppleReceipt.containsActivePurchase` has issues) equivalent to `ReceiptFetcher.onlyIfEmpty`.
tonidero
left a comment
There was a problem hiding this comment.
Just a question, if that's ok, this looks good.
| repeat { | ||
| retries += 1 | ||
| let data = await self.refreshReceipt() | ||
| data = await self.refreshReceipt() |
There was a problem hiding this comment.
When the receipt can't be parsed on the last retry, we would return that receipt. Is that correct?
There was a problem hiding this comment.
We could add a couple of tests for these returning an unparseable receipt and an empty receipt if that's the case.
There was a problem hiding this comment.
When the receipt can't be parsed on the last retry, we would return that receipt. Is that correct?
Correct, as explained in the description:
To make this retry mechanism less risky when eventually enabled, this change makes the "worst case scenario" [...] equivalent to
ReceiptFetcher.onlyIfEmpty.
There was a problem hiding this comment.
We could add a couple of tests for these returning an unparseable receipt and an empty receipt if that's the case.
The current tests already cover that though?
There was a problem hiding this comment.
The current tests already cover that though?
Well I think we have tests for receipts without a purchase but not for unparseable receipts? (I might be missing something since I'm not that familiar with the parsing logic)
There was a problem hiding this comment.
Is testStopsRetryingEvenIfDataIsInvalid what you're describing?
There was a problem hiding this comment.
func testStopsRetryingEvenIfDataIsInvalid() async {
self.mock(receipt: Self.receiptWithoutPurchases)
let invalidData = Self.receiptWithoutPurchases.asData
let data = await self.fetch(productIdentifier: Self.productID, retries: 2)
expect(data) == Data()
expect(data) == invalidData
expect(self.mockReceiptParser.invokedParseParametersList) == [
invalidData,
invalidData,
invalidData
]
expect(self.mockRequestFetcher.refreshReceiptCalledCount) == 3
}
That seems to be using a receiptWithoutPurchases. I was thinking more along the lines of a receipt that is missing a critical field or something like that. So basically a test where we make self.receiptParser.parse throw an exception.
There was a problem hiding this comment.
Oooh gotcha, yeah there's no test coverage for that catch. Good catch!
I added that test.
**This is an automatic release.** ### Bugfixes * `ISO8601DateFormatter.withMilliseconds`: fixed iOS 11 crash (#2037) via NachoSoto (@NachoSoto) * Changed `StoreKit2Setting.default` back to `.enabledOnlyForOptimizations` (#2022) via NachoSoto (@NachoSoto) ### Other Changes * `Integration Tests`: changed weekly to monthly subscriptions to work around 0-second subscriptions (#2042) via NachoSoto (@NachoSoto) * `Integration Tests`: fixed `testPurchaseWithAskToBuyPostsReceipt` (#2040) via NachoSoto (@NachoSoto) * `ReceiptRefreshPolicy.retryUntilProductIsFound`: default to returning "invalid" receipt (#2024) via NachoSoto (@NachoSoto) * `CachingProductsManager`: use partial cached products (#2014) via NachoSoto (@NachoSoto) * Added `BackendErrorCode.purchasedProductMissingInAppleReceipt` (#2033) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI`: replaced `Purchases` dependency with `SPM` (#2027) via NachoSoto (@NachoSoto) * `Integration Tests`: changed log output to `raw` (#2031) via NachoSoto (@NachoSoto) * `Integration Tests`: run on iOS 16 (#2035) via NachoSoto (@NachoSoto) * CI: fixed `iOS 14` tests Xcode version (#2030) via NachoSoto (@NachoSoto) * `Async.call`: added non-throwing overload (#2006) via NachoSoto (@NachoSoto) * Documentation: Fixed references in `V4_API_Migration_guide.md` (#2018) via NachoSoto (@NachoSoto) * `eligiblePromotionalOffers`: don't log error if response is ineligible (#2019) via NachoSoto (@NachoSoto) * Runs push-pods after make-release (#2025) via Cesar de la Vega (@vegaro) * Some updates on notify-on-non-patch-release-branches: (#2026) via Cesar de la Vega (@vegaro) * Deploy `PurchaseTesterSwiftUI` to TestFlight (#2003) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI`: added "logs" screen (#2012) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI`: allow configuring API key at runtime (#1999) via NachoSoto (@NachoSoto)
See #1945.
To make this retry mechanism less risky when eventually enabled, this change makes the "worst case scenario" (where retrying didn't help, or
AppleReceipt.containsActivePurchasehas issues) equivalent toReceiptFetcher.onlyIfEmpty.Note: this is currently not enabled in production, only in Integration Tests.