From 29ecd3a89bd9a995be2aefd99a5604f9ec60a881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 27 Feb 2025 14:25:58 +0100 Subject: [PATCH] email pixels --- .../app/settings/NewSettingsViewModel.kt | 3 +- .../app/settings/SettingsPixelDispatcher.kt | 17 ++++++++++ .../app/settings/NewSettingsViewModelTest.kt | 7 +++++ .../settings/SettingsPixelDispatcherTest.kt | 31 +++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/settings/NewSettingsViewModel.kt b/app/src/main/java/com/duckduckgo/app/settings/NewSettingsViewModel.kt index b29af23f7363..a2a73003d6f7 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/NewSettingsViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/NewSettingsViewModel.kt @@ -31,7 +31,6 @@ import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_APPEARANCE_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_APPTP_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_COOKIE_POPUP_PROTECTION_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_DEFAULT_BROWSER_PRESSED -import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_EMAIL_PROTECTION_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_FIRE_BUTTON_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_GENERAL_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_NEXT_STEPS_ADDRESS_BAR @@ -281,7 +280,7 @@ class NewSettingsViewModel @Inject constructor( } this@NewSettingsViewModel.command.send(command) } - pixel.fire(SETTINGS_EMAIL_PROTECTION_PRESSED) + settingsPixelDispatcher.fireEmailPressed() } fun onAppTPSettingClicked() { diff --git a/app/src/main/java/com/duckduckgo/app/settings/SettingsPixelDispatcher.kt b/app/src/main/java/com/duckduckgo/app/settings/SettingsPixelDispatcher.kt index 16a84df550c4..063c9a33eab1 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/SettingsPixelDispatcher.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/SettingsPixelDispatcher.kt @@ -17,8 +17,10 @@ package com.duckduckgo.app.settings import com.duckduckgo.app.di.AppCoroutineScope +import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_EMAIL_PROTECTION_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_SYNC_PRESSED import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.autofill.api.email.EmailManager import com.duckduckgo.common.utils.extensions.toBinaryString import com.duckduckgo.di.scopes.AppScope import com.duckduckgo.duckchat.api.DuckChat @@ -38,6 +40,7 @@ import kotlinx.coroutines.launch interface SettingsPixelDispatcher { fun fireSyncPressed() fun fireDuckChatPressed() + fun fireEmailPressed() } @ContributesBinding(scope = AppScope::class) @@ -47,6 +50,7 @@ class SettingsPixelDispatcherImpl @Inject constructor( private val pixel: Pixel, private val syncStateMonitor: SyncStateMonitor, private val duckChat: DuckChat, + private val emailManager: EmailManager, ) : SettingsPixelDispatcher { override fun fireSyncPressed() { @@ -74,8 +78,21 @@ class SettingsPixelDispatcherImpl @Inject constructor( } } + override fun fireEmailPressed() { + appCoroutineScope.launch { + val isSignedIn = emailManager.isSignedIn() + pixel.fire( + pixel = SETTINGS_EMAIL_PROTECTION_PRESSED, + parameters = mapOf( + PARAM_EMAIL_IS_SIGNED_IN to isSignedIn.toBinaryString(), + ), + ) + } + } + private companion object { const val PARAM_SYNC_IS_ENABLED = "is_enabled" const val PARAM_DUCK_CHAT_USED_BEFORE = "was_used_before" + const val PARAM_EMAIL_IS_SIGNED_IN = "is_signed_in" } } diff --git a/app/src/test/java/com/duckduckgo/app/settings/NewSettingsViewModelTest.kt b/app/src/test/java/com/duckduckgo/app/settings/NewSettingsViewModelTest.kt index 1d09e5f9245c..6ea0f2c4b078 100644 --- a/app/src/test/java/com/duckduckgo/app/settings/NewSettingsViewModelTest.kt +++ b/app/src/test/java/com/duckduckgo/app/settings/NewSettingsViewModelTest.kt @@ -129,4 +129,11 @@ class NewSettingsViewModelTest { verify(settingsPixelDispatcherMock).fireDuckChatPressed() } + + @Test + fun `when Email pressed then pixel is fired`() { + testee.onEmailProtectionSettingClicked() + + verify(settingsPixelDispatcherMock).fireEmailPressed() + } } diff --git a/app/src/test/java/com/duckduckgo/app/settings/SettingsPixelDispatcherTest.kt b/app/src/test/java/com/duckduckgo/app/settings/SettingsPixelDispatcherTest.kt index ac8fde9742b7..9e8a7fcefbd4 100644 --- a/app/src/test/java/com/duckduckgo/app/settings/SettingsPixelDispatcherTest.kt +++ b/app/src/test/java/com/duckduckgo/app/settings/SettingsPixelDispatcherTest.kt @@ -16,8 +16,10 @@ package com.duckduckgo.app.settings +import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_EMAIL_PROTECTION_PRESSED import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_SYNC_PRESSED import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.autofill.api.email.EmailManager import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.duckchat.api.DuckChat import com.duckduckgo.duckchat.impl.DuckChatPixelName @@ -45,6 +47,8 @@ class SettingsPixelDispatcherTest { @Mock private lateinit var duckChatMock: DuckChat + @Mock private lateinit var emailManagerMock: EmailManager + lateinit var testee: SettingsPixelDispatcherImpl @Before @@ -143,10 +147,37 @@ class SettingsPixelDispatcherTest { ) } + @Test + fun `when fireEmailPressed and is not signed in, then send a pixel with not actively used information`() = runTest { + whenever(emailManagerMock.isSignedIn()).thenReturn(false) + + val testee = createTestee() + testee.fireEmailPressed() + + verify(pixelMock).fire( + pixel = SETTINGS_EMAIL_PROTECTION_PRESSED, + parameters = mapOf("is_signed_in" to "0"), + ) + } + + @Test + fun `when fireEmailPressed and is signed in, then send a pixel with actively used information`() = runTest { + whenever(emailManagerMock.isSignedIn()).thenReturn(true) + + val testee = createTestee() + testee.fireEmailPressed() + + verify(pixelMock).fire( + pixel = SETTINGS_EMAIL_PROTECTION_PRESSED, + parameters = mapOf("is_signed_in" to "1"), + ) + } + private fun createTestee() = SettingsPixelDispatcherImpl( appCoroutineScope = coroutinesTestRule.testScope, pixel = pixelMock, syncStateMonitor = syncStateMonitorMock, duckChat = duckChatMock, + emailManager = emailManagerMock, ) }