From ed91f7989ea64773f31c8be7e329c56d4686b08e Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 18 Mar 2024 09:46:27 +0000 Subject: [PATCH] Implement kill switch for purchases (#4314) Task/Issue URL: https://app.asana.com/0/0/1206853350033015/f ### Description See task ### Steps to test this PR See task --- .../impl/ui/SubscriptionWebViewViewModel.kt | 40 ++++++++++--------- .../ui/SubscriptionWebViewViewModelTest.kt | 39 ++++++++++++++++++ 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt index 5cf3fa608ffb..aa59eab513ef 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt @@ -28,6 +28,7 @@ import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams import com.duckduckgo.networkprotection.api.NetworkProtectionWaitlist import com.duckduckgo.subscriptions.impl.CurrentPurchase import com.duckduckgo.subscriptions.impl.JSONObjectAdapter +import com.duckduckgo.subscriptions.impl.PrivacyProFeature import com.duckduckgo.subscriptions.impl.SubscriptionsChecker import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ITR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY @@ -67,6 +68,7 @@ class SubscriptionWebViewViewModel @Inject constructor( private val subscriptionsChecker: SubscriptionsChecker, private val networkProtectionWaitlist: NetworkProtectionWaitlist, private val pixelSender: SubscriptionPixelSender, + private val privacyProFeature: PrivacyProFeature, ) : ViewModel() { private val moshi = Moshi.Builder().add(JSONObjectAdapter()).build() @@ -192,28 +194,28 @@ class SubscriptionWebViewViewModel @Inject constructor( private fun getSubscriptionOptions(featureName: String, method: String, id: String) { viewModelScope.launch(dispatcherProvider.io()) { - val offer = subscriptionsManager.getSubscriptionOffer() + var subscriptionOptions = SubscriptionOptionsJson( + options = emptyList(), + features = emptyList(), + ) - val subscriptionOptions = if (offer != null) { - val yearlyJson = OptionsJson( - id = offer.yearlyPlanId, - cost = CostJson(displayPrice = offer.yearlyFormattedPrice, recurrence = YEARLY), - ) + if (privacyProFeature.allowPurchase().isEnabled()) { + subscriptionsManager.getSubscriptionOffer()?.let { offer -> + val yearlyJson = OptionsJson( + id = offer.yearlyPlanId, + cost = CostJson(displayPrice = offer.yearlyFormattedPrice, recurrence = YEARLY), + ) - val monthlyJson = OptionsJson( - id = offer.monthlyPlanId, - cost = CostJson(displayPrice = offer.monthlyFormattedPrice, recurrence = MONTHLY), - ) + val monthlyJson = OptionsJson( + id = offer.monthlyPlanId, + cost = CostJson(displayPrice = offer.monthlyFormattedPrice, recurrence = MONTHLY), + ) - SubscriptionOptionsJson( - options = listOf(yearlyJson, monthlyJson), - features = listOf(FeatureJson(NETP), FeatureJson(ITR), FeatureJson(PIR)), - ) - } else { - SubscriptionOptionsJson( - options = emptyList(), - features = emptyList(), - ) + subscriptionOptions = SubscriptionOptionsJson( + options = listOf(yearlyJson, monthlyJson), + features = listOf(FeatureJson(NETP), FeatureJson(ITR), FeatureJson(PIR)), + ) + } } val response = JsCallbackData( diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt index aa1a08c4c8ca..edecd6b102c5 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt @@ -3,10 +3,14 @@ package com.duckduckgo.subscriptions.impl.ui import androidx.test.ext.junit.runners.AndroidJUnit4 import app.cash.turbine.test import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.feature.toggles.api.FakeFeatureToggleFactory +import com.duckduckgo.feature.toggles.api.FakeToggleStore +import com.duckduckgo.feature.toggles.api.Toggle import com.duckduckgo.networkprotection.api.NetworkProtectionScreens.NetPWaitlistInvitedScreenNoParams import com.duckduckgo.networkprotection.api.NetworkProtectionWaitlist import com.duckduckgo.subscriptions.impl.CurrentPurchase import com.duckduckgo.subscriptions.impl.JSONObjectAdapter +import com.duckduckgo.subscriptions.impl.PrivacyProFeature import com.duckduckgo.subscriptions.impl.SubscriptionOffer import com.duckduckgo.subscriptions.impl.SubscriptionStatus.AUTO_RENEWABLE import com.duckduckgo.subscriptions.impl.SubscriptionStatus.EXPIRED @@ -45,6 +49,7 @@ class SubscriptionWebViewViewModelTest { private val networkProtectionWaitlist: NetworkProtectionWaitlist = mock() private val subscriptionsChecker: SubscriptionsChecker = mock() private val pixelSender: SubscriptionPixelSender = mock() + private val privacyProFeature = FakeFeatureToggleFactory.create(PrivacyProFeature::class.java, FakeToggleStore()) private lateinit var viewModel: SubscriptionWebViewViewModel @@ -57,6 +62,7 @@ class SubscriptionWebViewViewModelTest { subscriptionsChecker, networkProtectionWaitlist, pixelSender, + privacyProFeature, ) } @@ -174,6 +180,8 @@ class SubscriptionWebViewViewModelTest { @Test fun whenGetSubscriptionOptionsThenSendCommand() = runTest { + privacyProFeature.allowPurchase().setEnabled(Toggle.State(enable = true)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn( SubscriptionOffer( monthlyPlanId = "monthly", @@ -200,6 +208,37 @@ class SubscriptionWebViewViewModelTest { @Test fun whenGetSubscriptionsAndNoSubscriptionOfferThenSendCommandWithEmptyData() = runTest { + privacyProFeature.allowPurchase().setEnabled(Toggle.State(enable = true)) + + viewModel.commands().test { + viewModel.processJsCallbackMessage("test", "getSubscriptionOptions", "id", JSONObject("{}")) + + val result = awaitItem() + assertTrue(result is Command.SendResponseToJs) + + val response = (result as Command.SendResponseToJs).data + assertEquals("id", response.id) + assertEquals("test", response.featureName) + assertEquals("getSubscriptionOptions", response.method) + + val params = jsonAdapter.fromJson(response.params.toString())!! + assertEquals(0, params.options.size) + assertEquals(0, params.features.size) + } + } + + @Test + fun whenGetSubscriptionsAndToggleOffThenSendCommandWithEmptyData() = runTest { + privacyProFeature.allowPurchase().setEnabled(Toggle.State(enable = false)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn( + SubscriptionOffer( + monthlyPlanId = "monthly", + monthlyFormattedPrice = "$1", + yearlyPlanId = "yearly", + yearlyFormattedPrice = "$10", + ), + ) + viewModel.commands().test { viewModel.processJsCallbackMessage("test", "getSubscriptionOptions", "id", JSONObject("{}"))