Skip to content

Commit 65f09c8

Browse files
committed
[PM-33518] feat: Add isInAppUpgradeAvailableFlow to PremiumStateManager
Combine isInAppBillingSupportedFlow and MobilePremiumUpgrade feature flag into a single StateFlow for determining whether to route premium upgrade CTAs to the in-app PlanScreen or the web vault URL.
1 parent 581f032 commit 65f09c8

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

app/src/main/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManager.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.x8bit.bitwarden.data.billing.manager
22

3+
import com.bitwarden.core.data.manager.model.FlagKey
34
import kotlinx.coroutines.flow.StateFlow
45

56
/**
@@ -16,6 +17,13 @@ interface PremiumStateManager {
1617
*/
1718
val isPremiumUpgradeBannerEligibleFlow: StateFlow<Boolean>
1819

20+
/**
21+
* Emits `true` when the in-app upgrade flow is available (i.e., in-app billing is
22+
* supported and the [FlagKey.MobilePremiumUpgrade] feature flag is enabled),
23+
* or `false` otherwise.
24+
*/
25+
val isInAppUpgradeAvailableFlow: StateFlow<Boolean>
26+
1927
/**
2028
* Marks the Premium upgrade banner as dismissed for the current user.
2129
*/

app/src/main/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerImpl.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ class PremiumStateManagerImpl(
8989
initialValue = false,
9090
)
9191

92+
override val isInAppUpgradeAvailableFlow: StateFlow<Boolean> =
93+
combine(
94+
billingRepository.isInAppBillingSupportedFlow,
95+
featureFlagManager.getFeatureFlagFlow(FlagKey.MobilePremiumUpgrade),
96+
) { isInAppBillingSupported, featureFlagEnabled ->
97+
isInAppBillingSupported && featureFlagEnabled
98+
}
99+
.stateIn(
100+
scope = unconfinedScope,
101+
started = SharingStarted.Eagerly,
102+
initialValue = false,
103+
)
104+
92105
override fun dismissPremiumUpgradeBanner() {
93106
val activeUserId = authDiskSource.userState?.activeUserId ?: return
94107
settingsDiskSource.storePremiumUpgradeBannerDismissed(

app/src/test/kotlin/com/x8bit/bitwarden/data/billing/manager/PremiumStateManagerImplTest.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,46 @@ class PremiumStateManagerImplTest {
330330
}
331331
}
332332

333+
@Test
334+
fun `isInAppUpgradeAvailableFlow should emit true when billing supported and flag enabled`() =
335+
runTest {
336+
val manager = createManager()
337+
manager.isInAppUpgradeAvailableFlow.test {
338+
assertTrue(awaitItem())
339+
}
340+
}
341+
342+
@Test
343+
fun `isInAppUpgradeAvailableFlow should emit false when billing not supported`() =
344+
runTest {
345+
mutableIsInAppBillingSupportedFlow.value = false
346+
val manager = createManager()
347+
manager.isInAppUpgradeAvailableFlow.test {
348+
assertFalse(awaitItem())
349+
}
350+
}
351+
352+
@Test
353+
fun `isInAppUpgradeAvailableFlow should emit false when feature flag disabled`() =
354+
runTest {
355+
mutableMobilePremiumUpgradeFlagFlow.value = false
356+
val manager = createManager()
357+
manager.isInAppUpgradeAvailableFlow.test {
358+
assertFalse(awaitItem())
359+
}
360+
}
361+
362+
@Test
363+
fun `isInAppUpgradeAvailableFlow should emit false when both conditions are false`() =
364+
runTest {
365+
mutableIsInAppBillingSupportedFlow.value = false
366+
mutableMobilePremiumUpgradeFlagFlow.value = false
367+
val manager = createManager()
368+
manager.isInAppUpgradeAvailableFlow.test {
369+
assertFalse(awaitItem())
370+
}
371+
}
372+
333373
@Test
334374
fun `dismissPremiumUpgradeBanner should store dismissed state for active user`() {
335375
val manager = createManager()

0 commit comments

Comments
 (0)