diff --git a/Tests/BackendIntegrationTests/BaseStoreKitIntegrationTests.swift b/Tests/BackendIntegrationTests/BaseStoreKitIntegrationTests.swift index 52ab2d8a29..b56989c83b 100644 --- a/Tests/BackendIntegrationTests/BaseStoreKitIntegrationTests.swift +++ b/Tests/BackendIntegrationTests/BaseStoreKitIntegrationTests.swift @@ -294,6 +294,19 @@ extension BaseStoreKitIntegrationTests { ) } + func verifyReceiptIsEventuallyPosted( + file: FileString = #file, + line: UInt = #line + ) async throws { + try await self.logger.verifyMessageIsEventuallyLogged( + Strings.network.operation_state(PostReceiptDataOperation.self, state: "Finished").description, + timeout: .seconds(3), + pollInterval: .milliseconds(100), + file: file, + line: line + ) + } + func expireSubscription(_ entitlement: EntitlementInfo) async throws { guard let expirationDate = entitlement.expirationDate else { return } diff --git a/Tests/BackendIntegrationTests/StoreKitIntegrationTests.swift b/Tests/BackendIntegrationTests/StoreKitIntegrationTests.swift index 405c1e7eba..9981baa7a7 100644 --- a/Tests/BackendIntegrationTests/StoreKitIntegrationTests.swift +++ b/Tests/BackendIntegrationTests/StoreKitIntegrationTests.swift @@ -332,6 +332,102 @@ class StoreKit1IntegrationTests: BaseStoreKitIntegrationTests { self.assertNoPurchases(currentCustomerInfo) } + func testRenewalsOnASeparateUserDontTransferPurchases() async throws { + let prefix = UUID().uuidString + let userID1 = "\(prefix)-user-1" + let userID2 = "\(prefix)-user-2" + + let anonymousUser = try self.purchases.appUserID + let productIdentifier = try await self.monthlyPackage.storeProduct.productIdentifier + + // 1. Purchase with user 1 + let user1CustomerInfo = try await self.purchases.logIn(userID1).customerInfo + self.assertNoPurchases(user1CustomerInfo) + expect(user1CustomerInfo.originalAppUserId) == anonymousUser + try await self.purchaseMonthlyOffering() + + // 2. Change to user 2 + let (identifiedCustomerInfo, _) = try await self.purchases.logIn(userID2) + self.assertNoPurchases(identifiedCustomerInfo) + + // 3. Renew subscription + self.logger.clearMessages() + + try self.testSession.forceRenewalOfSubscription(productIdentifier: productIdentifier) + + try await self.verifyReceiptIsEventuallyPosted() + + // 4. Verify new user does not have entitlement + let currentCustomerInfo = try await self.purchases.customerInfo(fetchPolicy: .fetchCurrent) + expect(currentCustomerInfo.originalAppUserId) == userID2 + self.assertNoPurchases(currentCustomerInfo) + } + + func testUserCanMakePurchaseAfterTransferBlocked() async throws { + let prefix = UUID().uuidString + let userID1 = "\(prefix)-user-1" + let userID2 = "\(prefix)-user-2" + + let anonymousUser = try self.purchases.appUserID + let productIdentifier = try await self.monthlyPackage.storeProduct.productIdentifier + + // 1. Purchase with user 1 + var user1CustomerInfo = try await self.purchases.logIn(userID1).customerInfo + self.assertNoPurchases(user1CustomerInfo) + expect(user1CustomerInfo.originalAppUserId) == anonymousUser + try await self.purchaseMonthlyOffering() + + // 2. Change to user 2 + let (identifiedCustomerInfo, _) = try await self.purchases.logIn(userID2) + self.assertNoPurchases(identifiedCustomerInfo) + + // 3. Renew subscription + self.logger.clearMessages() + + try self.testSession.forceRenewalOfSubscription(productIdentifier: productIdentifier) + + try await self.verifyReceiptIsEventuallyPosted() + + // 4. Verify new user does not have entitlement + var currentCustomerInfo = try await self.purchases.customerInfo(fetchPolicy: .fetchCurrent) + expect(currentCustomerInfo.originalAppUserId) == userID2 + self.assertNoPurchases(currentCustomerInfo) + + // 5. Make purchase with user 2 + self.logger.clearMessages() + currentCustomerInfo = try await self.purchaseMonthlyOffering().customerInfo + try await self.verifyReceiptIsEventuallyPosted() + + // 6. Verify user 2 has purchases + expect(currentCustomerInfo.originalAppUserId) == userID2 + expect(currentCustomerInfo.entitlements.all).toNot(beEmpty()) + + // 7. Verify that user 1 does not have purchases because they were transferred to user 2 + user1CustomerInfo = try await self.purchases.logIn(userID1).customerInfo + self.assertNoPurchases(user1CustomerInfo) + } + + func testPurchaseAfterSigningIntoNewUser() async throws { + let prefix = UUID().uuidString + let userID1 = "\(prefix)-user-1" + let userID2 = "\(prefix)-user-2" + + let anonymousUser = try self.purchases.appUserID + + // 1. Purchase with user 1 + let user1CustomerInfo = try await self.purchases.logIn(userID1).customerInfo + expect(user1CustomerInfo.originalAppUserId) == anonymousUser + try await self.purchaseMonthlyOffering() + + // 2. Change to user 2 + let (identifiedCustomerInfo, _) = try await self.purchases.logIn(userID2) + self.assertNoPurchases(identifiedCustomerInfo) + + // 3. Purchase again and verify user gets entitlement + let newCustomerInfo = try await self.purchaseMonthlyOffering().customerInfo + expect(newCustomerInfo.originalAppUserId) == userID2 + } + func testLogOutRemovesEntitlements() async throws { let anonUserID = try self.purchases.appUserID let identifiedUserID = "identified_\(anonUserID)".replacingOccurrences(of: "RCAnonymous", with: "") diff --git a/Tests/BackendIntegrationTests/StoreKitObserverModeIntegrationTests.swift b/Tests/BackendIntegrationTests/StoreKitObserverModeIntegrationTests.swift index 4d6c5b31d0..3f8229b115 100644 --- a/Tests/BackendIntegrationTests/StoreKitObserverModeIntegrationTests.swift +++ b/Tests/BackendIntegrationTests/StoreKitObserverModeIntegrationTests.swift @@ -76,11 +76,7 @@ class StoreKit2ObserverModeIntegrationTests: StoreKit1ObserverModeIntegrationTes try self.testSession.forceRenewalOfSubscription(productIdentifier: productID) - try await self.logger.verifyMessageIsEventuallyLogged( - Strings.network.operation_state(PostReceiptDataOperation.self, state: "Finished").description, - timeout: .seconds(3), - pollInterval: .milliseconds(100) - ) + try await self.verifyReceiptIsEventuallyPosted() } }