Skip to content
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

Update offerings cache when switchUser(to:) is called #2455

Merged
merged 7 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/Identity/IdentityManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class IdentityManager: CurrentUserProvider {
}

func switchUser(to newAppUserID: String) {
Logger.debug(Strings.identity.switching_user(newUserId: newAppUserID))
Logger.debug(Strings.identity.switching_user(newUserID: newAppUserID))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed param for consistency with others

self.resetCacheAndSave(newUserID: newAppUserID)
}

Expand Down
11 changes: 8 additions & 3 deletions Sources/Logging/Strings/IdentityStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ enum IdentityStrings {

case invalidating_cached_customer_info

case switching_user(newUserId: String)
case switching_user(newUserID: String)

case switching_user_same_app_user_id(newUserID: String)

}

Expand Down Expand Up @@ -68,8 +70,11 @@ extension IdentityStrings: CustomStringConvertible {
return "Attempt to delete attributes for user, but there were none to delete"
case .invalidating_cached_customer_info:
return "Detected unverified cached CustomerInfo but verification is enabled. Invalidating cache."
case let .switching_user(newUserId):
return "Switching to user '\(newUserId)'."
case let .switching_user(newUserID):
return "Switching to user '\(newUserID)'."
case let .switching_user_same_app_user_id(newUserID):
return "switchUser(to:) called with the same appUserID as the current user (\(newUserID)). " +
"This has no effect."
}
}

Expand Down
25 changes: 20 additions & 5 deletions Sources/Purchasing/Purchases/Purchases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -681,27 +681,42 @@ public extension Purchases {

}

#else
#endif

// - MARK: - Custom entitlement computation API

public extension Purchases {
extension Purchases {

#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION
///
/// Updates the current appUserID to a new one, without associating the two.
/// - Important: This method is **only available** in Custom Entitlements Computation mode.
/// Receipts posted by the SDK to the RevenueCat backend after calling this method will be sent
/// with the newAppUserID.
///
@objc(switchUserToNewAppUserID:)
func switchUser(to newAppUserID: String) {
public func switchUser(to newAppUserID: String) {
self.internalSwitchUser(to: newAppUserID)
}
#endif

internal func internalSwitchUser(to newAppUserID: String) {
guard self.identityManager.currentAppUserID != newAppUserID else {
Logger.warn(Strings.identity.switching_user_same_app_user_id(newUserID: newAppUserID))
return
}

self.identityManager.switchUser(to: newAppUserID)

self.systemInfo.isApplicationBackgrounded { isBackgrounded in
self.offeringsManager.updateOfferingsCache(appUserID: self.appUserID,
isAppBackgrounded: isBackgrounded,
completion: nil)
}
}

}

#endif

// MARK: Purchasing

public extension Purchases {
Expand Down
33 changes: 28 additions & 5 deletions Tests/UnitTests/Purchasing/Purchases/PurchasesLogInTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,20 +100,43 @@ class PurchasesLogInTests: BasePurchasesTests {

// MARK: - Switch user

#if ENABLE_CUSTOM_ENTITLEMENT_COMPUTATION

func testSwitchUser() {
func testSwitchUserSwitchesUser() {
self.systemInfo = MockSystemInfo(finishTransactions: true, customEntitlementsComputation: true)
Purchases.clearSingleton()
self.initializePurchasesInstance(appUserId: "old-test-user-id")

self.purchases.switchUser(to: "test-user-id")
self.purchases.internalSwitchUser(to: "test-user-id")

expect(self.identityManager.invokedSwitchUser) == true
expect(self.identityManager.invokedSwitchUserParametersList) == ["test-user-id"]
}

#endif
func testSwitchUserRefreshesOfferingsCache() {
self.systemInfo = MockSystemInfo(finishTransactions: true, customEntitlementsComputation: true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This initialization is duplicated in several tests now, might be worth extracting.

Purchases.clearSingleton()
self.initializePurchasesInstance(appUserId: "old-test-user-id")

let baselineOfferingsCallCount = self.mockOfferingsManager.invokedUpdateOfferingsCacheCount

self.purchases.internalSwitchUser(to: "test-user-id")

expect(self.mockOfferingsManager.invokedUpdateOfferingsCacheCount) == baselineOfferingsCallCount + 1
}

func testSwitchUserNoOpIfAppUserIDIsSameAsCurrent() {
self.systemInfo = MockSystemInfo(finishTransactions: true, customEntitlementsComputation: true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto duplicated initialization.

Purchases.clearSingleton()
let appUserId = "test-user-id"
self.initializePurchasesInstance(appUserId: appUserId)

let baselineOfferingsCallCount = self.mockOfferingsManager.invokedUpdateOfferingsCacheCount
self.identityManager.mockAppUserID = appUserId
self.identityManager.mockIsAnonymous = false
self.purchases.internalSwitchUser(to: appUserId)

expect(self.identityManager.invokedSwitchUser) == false
expect(self.mockOfferingsManager.invokedUpdateOfferingsCacheCount) == baselineOfferingsCallCount
}

// MARK: - Update offerings cache

Expand Down