Skip to content

Commit e67d09d

Browse files
committed
support post subscription duckai card click
1 parent 3d70b4e commit e67d09d

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

subscriptions/subscriptions-impl/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ dependencies {
6060
implementation project(':survey-api')
6161
implementation project(':vpn-api')
6262
implementation project(':content-scope-scripts-api')
63+
implementation project(':duckchat-api')
6364

6465
implementation AndroidX.appCompat
6566
implementation KotlinX.coroutines.core

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ object SubscriptionsConstants {
4545
const val ITR = "Identity Theft Restoration"
4646
const val ROW_ITR = "Global Identity Theft Restoration"
4747
const val PIR = "Data Broker Protection"
48+
const val DUCK_AI = "Duck.ai"
4849

4950
// Platform
5051
const val PLATFORM = "android"

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixel.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ enum class SubscriptionPixel(
141141
type = Unique(),
142142
includedParameters = setOf(ATB, APP_VERSION),
143143
),
144+
ONBOARDING_DUCK_AI_CLICK(
145+
baseName = "m_privacy-pro_welcome_duck-ai_click",
146+
type = Unique(),
147+
includedParameters = setOf(ATB, APP_VERSION),
148+
),
144149
SUBSCRIPTION_SETTINGS_SHOWN(
145150
baseName = "m_privacy-pro_settings_screen_impression",
146151
type = Count,

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pixels/SubscriptionPixelSender.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.OFFER_RESTORE_
3939
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.OFFER_SCREEN_SHOWN
4040
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.OFFER_SUBSCRIBE_CLICK
4141
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ONBOARDING_ADD_DEVICE_CLICK
42+
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ONBOARDING_DUCK_AI_CLICK
4243
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ONBOARDING_IDTR_CLICK
4344
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ONBOARDING_PIR_CLICK
4445
import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixel.ONBOARDING_VPN_CLICK
@@ -89,6 +90,7 @@ interface SubscriptionPixelSender {
8990
fun reportOnboardingVpnClick()
9091
fun reportOnboardingPirClick()
9192
fun reportOnboardingIdtrClick()
93+
fun reportOnboardingDuckAiClick()
9294
fun reportSubscriptionSettingsShown()
9395
fun reportAppSettingsPirClick()
9496
fun reportAppSettingsIdtrClick()
@@ -191,6 +193,9 @@ class SubscriptionPixelSenderImpl @Inject constructor(
191193
override fun reportOnboardingIdtrClick() =
192194
fire(ONBOARDING_IDTR_CLICK)
193195

196+
override fun reportOnboardingDuckAiClick() =
197+
fire(ONBOARDING_DUCK_AI_CLICK)
198+
194199
override fun reportSubscriptionSettingsShown() =
195200
fire(SUBSCRIPTION_SETTINGS_SHOWN)
196201

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import com.duckduckgo.subscriptions.impl.JSONObjectAdapter
3232
import com.duckduckgo.subscriptions.impl.PrivacyProFeature
3333
import com.duckduckgo.subscriptions.impl.SubscriptionOffer
3434
import com.duckduckgo.subscriptions.impl.SubscriptionsChecker
35+
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.DUCK_AI
3536
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ITR
3637
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.LEGACY_FE_ITR
3738
import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.LEGACY_FE_NETP
@@ -192,13 +193,15 @@ class SubscriptionWebViewViewModel @Inject constructor(
192193
NETP, LEGACY_FE_NETP -> networkProtectionAccessState.getScreenForCurrentState()?.let { GoToNetP(it) }
193194
ITR, LEGACY_FE_ITR, ROW_ITR -> GoToITR
194195
PIR, LEGACY_FE_PIR -> GoToPIR
196+
DUCK_AI -> GoToDuckAI
195197
else -> null
196198
}
197199
if (hasPurchasedSubscription()) {
198200
when (commandToSend) {
199201
GoToITR -> pixelSender.reportOnboardingIdtrClick()
200202
is GoToNetP -> pixelSender.reportOnboardingVpnClick()
201203
GoToPIR -> pixelSender.reportOnboardingPirClick()
204+
GoToDuckAI -> pixelSender.reportOnboardingDuckAiClick()
202205
else -> {} // no-op
203206
}
204207
}
@@ -427,6 +430,7 @@ class SubscriptionWebViewViewModel @Inject constructor(
427430
data object GoToITR : Command()
428431
data object GoToPIR : Command()
429432
data class GoToNetP(val activityParams: ActivityParams) : Command()
433+
data object GoToDuckAI : Command()
430434
data object Reload : Command()
431435
}
432436

subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import com.duckduckgo.downloads.api.DownloadStateListener
5858
import com.duckduckgo.downloads.api.DownloadsFileActions
5959
import com.duckduckgo.downloads.api.FileDownloader
6060
import com.duckduckgo.downloads.api.FileDownloader.PendingFileDownload
61+
import com.duckduckgo.duckchat.api.DuckChat
6162
import com.duckduckgo.js.messaging.api.JsCallbackData
6263
import com.duckduckgo.js.messaging.api.JsMessageCallback
6364
import com.duckduckgo.js.messaging.api.JsMessaging
@@ -78,6 +79,7 @@ import com.duckduckgo.subscriptions.impl.ui.RestoreSubscriptionActivity.Companio
7879
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command
7980
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.BackToSettings
8081
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.BackToSettingsActivateSuccess
82+
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.GoToDuckAI
8183
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.GoToITR
8284
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.GoToNetP
8385
import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command.GoToPIR
@@ -161,6 +163,9 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
161163
@Inject
162164
lateinit var pixelSender: SubscriptionPixelSender
163165

166+
@Inject
167+
lateinit var duckChat: DuckChat
168+
164169
private val viewModel: SubscriptionWebViewViewModel by bindViewModel()
165170

166171
private val binding: ActivitySubscriptionsWebviewBinding by viewBinding()
@@ -422,6 +427,7 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
422427
is GoToITR -> goToITR()
423428
is GoToPIR -> goToPIR()
424429
is GoToNetP -> goToNetP(command.activityParams)
430+
is GoToDuckAI -> goToDuckAI()
425431
Reload -> binding.webview.reload()
426432
}
427433
}
@@ -447,6 +453,10 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD
447453
globalActivityStarter.start(this, params)
448454
}
449455

456+
private fun goToDuckAI() {
457+
duckChat.openDuckChat()
458+
}
459+
450460
private fun renderPurchaseState(purchaseState: PurchaseStateView) {
451461
when (purchaseState) {
452462
is PurchaseStateView.InProgress, PurchaseStateView.Inactive -> {

subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,20 @@ class SubscriptionWebViewViewModelTest {
487487
}
488488
}
489489

490+
@Test
491+
fun whenFeatureSelectedAndFeatureIsDuckAiThenCommandSent() = runTest {
492+
givenSubscriptionStatus(EXPIRED)
493+
viewModel.commands().test {
494+
viewModel.processJsCallbackMessage(
495+
"test",
496+
"featureSelected",
497+
null,
498+
JSONObject("""{"feature":"${SubscriptionsConstants.DUCK_AI}"}"""),
499+
)
500+
assertTrue(awaitItem() is Command.GoToDuckAI)
501+
}
502+
}
503+
490504
@Test
491505
fun whenSubscriptionSelectedThenPixelIsSent() = runTest {
492506
viewModel.processJsCallbackMessage(
@@ -622,6 +636,34 @@ class SubscriptionWebViewViewModelTest {
622636
verifyNoInteractions(pixelSender)
623637
}
624638

639+
@Test
640+
fun whenFeatureSelectedAndFeatureIsDuckAiAndInPurchaseFlowThenPixelIsSent() = runTest {
641+
givenSubscriptionStatus(AUTO_RENEWABLE)
642+
whenever(subscriptionsManager.currentPurchaseState).thenReturn(flowOf(CurrentPurchase.Success))
643+
viewModel.start()
644+
645+
viewModel.processJsCallbackMessage(
646+
featureName = "test",
647+
method = "featureSelected",
648+
id = null,
649+
data = JSONObject("""{"feature":"${SubscriptionsConstants.DUCK_AI}"}"""),
650+
)
651+
verify(pixelSender).reportOnboardingDuckAiClick()
652+
}
653+
654+
@Test
655+
fun whenFeatureSelectedAndFeatureIsDuckAiAndNotInPurchaseFlowThenPixelIsNotSent() = runTest {
656+
givenSubscriptionStatus(AUTO_RENEWABLE)
657+
658+
viewModel.processJsCallbackMessage(
659+
featureName = "test",
660+
method = "featureSelected",
661+
id = null,
662+
data = JSONObject("""{"feature":"${SubscriptionsConstants.DUCK_AI}"}"""),
663+
)
664+
verifyNoInteractions(pixelSender)
665+
}
666+
625667
@Test
626668
fun whenSubscriptionsWelcomeFaqClickedAndInPurchaseFlowThenPixelIsSent() = runTest {
627669
givenSubscriptionStatus(AUTO_RENEWABLE)

0 commit comments

Comments
 (0)