-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[in_app_purchase_storekit] Fix consumable repurchase issue in StoreKit2 #10521
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
base: main
Are you sure you want to change the base?
Changes from all commits
814e600
97dcd3b
cc0994d
41a7230
d031e46
9f90cc6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -415,6 +415,67 @@ final class InAppPurchase2PluginTests: XCTestCase { | |
| await fulfillment(of: [finishExpectation], timeout: 5) | ||
| } | ||
|
|
||
| func testFinishNonExistentTransactionReturnsSuccess() async throws { | ||
| // Test that finishing a non-existent transaction returns success | ||
| // (since if it's not in unfinished transactions, it's already complete) | ||
| let finishExpectation = self.expectation( | ||
| description: "Finishing non-existent transaction should return success") | ||
|
|
||
| plugin.finish(id: 999999) { result in | ||
| switch result { | ||
| case .success(): | ||
| finishExpectation.fulfill() | ||
| case .failure(let error): | ||
| XCTFail("Finish should succeed for non-existent transaction: \(error)") | ||
| } | ||
| } | ||
|
|
||
| await fulfillment(of: [finishExpectation], timeout: 5) | ||
| } | ||
|
|
||
| func testConsumableCanBeRepurchasedAfterFinish() async throws { | ||
| // Test that a consumable can be purchased again after finishing | ||
| let firstPurchaseExpectation = self.expectation(description: "First purchase should succeed") | ||
| let finishExpectation = self.expectation(description: "Finishing purchase should succeed") | ||
| let secondPurchaseExpectation = self.expectation(description: "Second purchase should succeed") | ||
|
|
||
| // First purchase | ||
| plugin.purchase(id: "consumable", options: nil) { result in | ||
| switch result { | ||
| case .success: | ||
| firstPurchaseExpectation.fulfill() | ||
| case .failure(let error): | ||
| XCTFail("First purchase should NOT fail. Failed with \(error)") | ||
| } | ||
| } | ||
|
|
||
| await fulfillment(of: [firstPurchaseExpectation], timeout: 5) | ||
|
|
||
| // Finish the transaction | ||
| plugin.finish(id: 0) { result in | ||
| switch result { | ||
| case .success(): | ||
| finishExpectation.fulfill() | ||
| case .failure(let error): | ||
| XCTFail("Finish should NOT fail. Failed with \(error)") | ||
| } | ||
| } | ||
|
|
||
| await fulfillment(of: [finishExpectation], timeout: 5) | ||
|
Comment on lines
+454
to
+464
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a hardcoded transaction ID let transactionsExpectation = self.expectation(description: "Get transactions")
var transactionId: Int64?
plugin.transactions { result in
switch result {
case .success(let transactions):
transactionId = transactions.first?.id
transactionsExpectation.fulfill()
case .failure(let error):
XCTFail("Getting transactions should NOT fail. Failed with \(error)")
transactionsExpectation.fulfill()
}
}
await fulfillment(of: [transactionsExpectation], timeout: 5)
guard let idToFinish = transactionId else {
XCTFail("Could not get transaction ID to finish")
return
}
// Finish the transaction
plugin.finish(id: idToFinish) { result in
switch result {
case .success():
finishExpectation.fulfill()
case .failure(let error):
XCTFail("Finish should NOT fail. Failed with \(error)")
}
}
await fulfillment(of: [finishExpectation], timeout: 5) |
||
|
|
||
| // Second purchase - this should also succeed | ||
| plugin.purchase(id: "consumable", options: nil) { result in | ||
| switch result { | ||
| case .success: | ||
| secondPurchaseExpectation.fulfill() | ||
| case .failure(let error): | ||
| XCTFail("Second purchase should NOT fail. Failed with \(error)") | ||
| } | ||
| } | ||
|
|
||
| await fulfillment(of: [secondPurchaseExpectation], timeout: 5) | ||
| } | ||
|
|
||
| @available(iOS 18.0, macOS 15.0, *) | ||
| func testIsWinBackOfferEligibleEligible() async throws { | ||
| let purchaseExpectation = self.expectation(description: "Purchase should succeed") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What throws in this method?