Skip to content

Commit

Permalink
Re-enable use our app experiment (#1156)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosholgado committed Apr 9, 2021
1 parent 6206eea commit be5132b
Show file tree
Hide file tree
Showing 16 changed files with 409 additions and 53 deletions.
Expand Up @@ -1819,14 +1819,6 @@ class BrowserTabViewModelTest {
verify(mockPixel).fire(cta.shownPixel!!, cta.pixelShownParameters())
}

@Test
fun whenManualCtaShownThenFirePixel() {
val cta = HomePanelCta.Survey(Survey("abc", "http://example.com", daysInstalled = 1, status = Survey.Status.SCHEDULED))

testee.onManualCtaShown(cta)
verify(mockPixel).fire(cta.shownPixel!!, cta.pixelShownParameters())
}

@Test
fun whenRegisterDaxBubbleCtaDismissedThenRegisterInDatabase() = coroutineRule.runBlocking {
val cta = DaxBubbleCta.DaxIntroCta(mockOnboardingStore, mockAppInstallStore)
Expand Down
Expand Up @@ -17,28 +17,65 @@
package com.duckduckgo.app.browser.shortcut

import android.content.Intent
import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.app.global.events.db.UserEventKey
import com.duckduckgo.app.global.events.db.UserEventsStore
import com.duckduckgo.app.global.useourapp.UseOurAppDetector
import com.duckduckgo.app.pixels.AppPixelName
import com.duckduckgo.app.runBlocking
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.statistics.pixels.Pixel
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test

@ExperimentalCoroutinesApi
class ShortcutReceiverTest {

@get:Rule
var coroutinesTestRule = CoroutineTestRule()

private val mockUserEventsStore: UserEventsStore = mock()
private val mockPixel: Pixel = mock()
private val mockVariantManager: VariantManager = mock()
private lateinit var testee: ShortcutReceiver

@Before
fun before() {
testee = ShortcutReceiver(UseOurAppDetector(mockUserEventsStore), mockPixel)
testee = ShortcutReceiver(UseOurAppDetector(mockUserEventsStore), mockPixel, mockUserEventsStore, coroutinesTestRule.testDispatcherProvider, mockVariantManager)
}

@Test
fun whenIntentReceivedIfUrlIsFromUseOurAppDomainAndVariantIsInAppUsageThenRegisterTimestamp() = coroutinesTestRule.runBlocking {
setInAppUsageVariant()
val intent = Intent()
intent.putExtra(ShortcutBuilder.SHORTCUT_URL_ARG, "https://facebook.com")
intent.putExtra(ShortcutBuilder.SHORTCUT_TITLE_ARG, "Title")
testee.onReceive(null, intent)

verify(mockUserEventsStore).registerUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)
}

@Test
fun whenIntentReceivedIfUrlIsFromUseOurAppDomainAndVariantIsNotInAppUsageThenDoNotRegisterTimestamp() = coroutinesTestRule.runBlocking {
setDefaultVariant()
val intent = Intent()
intent.putExtra(ShortcutBuilder.SHORTCUT_URL_ARG, "https://facebook.com")
intent.putExtra(ShortcutBuilder.SHORTCUT_TITLE_ARG, "Title")
testee.onReceive(null, intent)

verify(mockUserEventsStore, never()).registerUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)
}

@Test
fun whenIntentReceivedIfUrlContainsUseOurAppDomainThenFirePixel() {
setDefaultVariant()
val intent = Intent()
intent.putExtra(ShortcutBuilder.SHORTCUT_URL_ARG, "https://facebook.com")
intent.putExtra(ShortcutBuilder.SHORTCUT_TITLE_ARG, "Title")
Expand All @@ -47,8 +84,20 @@ class ShortcutReceiverTest {
verify(mockPixel).fire(AppPixelName.USE_OUR_APP_SHORTCUT_ADDED)
}

@Test
fun whenIntentReceivedIfUrlIsNotFromUseOurAppDomainThenDoNotRegisterEvent() = coroutinesTestRule.runBlocking {
setDefaultVariant()
val intent = Intent()
intent.putExtra(ShortcutBuilder.SHORTCUT_URL_ARG, "www.example.com")
intent.putExtra(ShortcutBuilder.SHORTCUT_TITLE_ARG, "Title")
testee.onReceive(null, intent)

verify(mockUserEventsStore, never()).registerUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)
}

@Test
fun whenIntentReceivedIfUrlIsNotFromUseOurAppDomainThenFireShortcutAddedPixel() {
setDefaultVariant()
val intent = Intent()
intent.putExtra(ShortcutBuilder.SHORTCUT_URL_ARG, "www.example.com")
intent.putExtra(ShortcutBuilder.SHORTCUT_TITLE_ARG, "Title")
Expand All @@ -57,4 +106,21 @@ class ShortcutReceiverTest {
verify(mockPixel).fire(AppPixelName.SHORTCUT_ADDED)
}

private fun setDefaultVariant() {
whenever(mockVariantManager.getVariant()).thenReturn(VariantManager.DEFAULT_VARIANT)
}

private fun setInAppUsageVariant() {
whenever(mockVariantManager.getVariant()).thenReturn(
Variant(
"test",
features = listOf(
VariantManager.VariantFeature.InAppUsage,
VariantManager.VariantFeature.RemoveDay1AndDay3Notifications,
VariantManager.VariantFeature.KillOnboarding
),
filterBy = { true }
)
)
}
}
Expand Up @@ -29,6 +29,9 @@ import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.app.notification.NotificationScheduler.ClearDataNotificationWorker
import com.duckduckgo.app.notification.NotificationScheduler.PrivacyNotificationWorker
import com.duckduckgo.app.notification.model.SchedulableNotification
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.statistics.VariantManager.Companion.DEFAULT_VARIANT
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand All @@ -47,6 +50,8 @@ class AndroidNotificationSchedulerTest {

private val clearNotification: SchedulableNotification = mock()
private val privacyNotification: SchedulableNotification = mock()
private val useOurAppNotification: SchedulableNotification = mock()
private val variantManager: VariantManager = mock()

private val context = InstrumentationRegistry.getInstrumentation().targetContext
private lateinit var workManager: WorkManager
Expand All @@ -59,7 +64,9 @@ class AndroidNotificationSchedulerTest {
testee = NotificationScheduler(
workManager,
clearNotification,
privacyNotification
privacyNotification,
useOurAppNotification,
variantManager
)
}

Expand All @@ -76,6 +83,7 @@ class AndroidNotificationSchedulerTest {

@Test
fun whenPrivacyNotificationClearDataCanShowThenPrivacyNotificationIsScheduled() = runBlocking<Unit> {
setDefaultVariant()
whenever(privacyNotification.canShow()).thenReturn(true)
whenever(clearNotification.canShow()).thenReturn(true)
testee.scheduleNextNotification()
Expand All @@ -85,6 +93,7 @@ class AndroidNotificationSchedulerTest {

@Test
fun whenPrivacyNotificationCanShowButClearDataCannotThenPrivacyNotificationIsScheduled() = runBlocking<Unit> {
setDefaultVariant()
whenever(privacyNotification.canShow()).thenReturn(true)
whenever(clearNotification.canShow()).thenReturn(false)
testee.scheduleNextNotification()
Expand All @@ -94,6 +103,7 @@ class AndroidNotificationSchedulerTest {

@Test
fun whenPrivacyNotificationCannotShowAndClearNotificationCanShowThenClearNotificationIsScheduled() = runBlocking<Unit> {
setDefaultVariant()
whenever(privacyNotification.canShow()).thenReturn(false)
whenever(clearNotification.canShow()).thenReturn(true)
testee.scheduleNextNotification()
Expand All @@ -103,13 +113,137 @@ class AndroidNotificationSchedulerTest {

@Test
fun whenPrivacyNotificationAndClearNotificationCannotShowThenNoNotificationScheduled() = runBlocking<Unit> {
setDefaultVariant()
whenever(privacyNotification.canShow()).thenReturn(false)
whenever(clearNotification.canShow()).thenReturn(false)
testee.scheduleNextNotification()

assertNoNotificationScheduled()
}

@Test
fun whenInAppUsageVariantAndUseOurAppNotificationCanShowThenNotificationScheduled() = runBlocking {
givenNoInactiveUserNotifications()
setInAppUsageVariant()
whenever(useOurAppNotification.canShow()).thenReturn(true)

testee.scheduleNextNotification()

assertNotificationScheduled(NotificationScheduler.UseOurAppNotificationWorker::class.jvmName, NotificationScheduler.USE_OUR_APP_WORK_REQUEST_TAG)
}

@Test
fun whenInAppUsageVariantUseOurAppNotificationCannotShowThenNoNotificationScheduled() = runBlocking {
givenNoInactiveUserNotifications()
setInAppUsageVariant()
whenever(useOurAppNotification.canShow()).thenReturn(false)

testee.scheduleNextNotification()

assertNoNotificationScheduled(NotificationScheduler.USE_OUR_APP_WORK_REQUEST_TAG)
}

@Test
fun whenInAppUsageSecondControlVariantThenNoNotificationScheduled() = runBlocking<Unit> {
setInAppUsageSecondControlVariant()
whenever(useOurAppNotification.canShow()).thenReturn(true)

testee.scheduleNextNotification()

assertNoNotificationScheduled(NotificationScheduler.USE_OUR_APP_WORK_REQUEST_TAG)
}

@Test
fun whenInAppUsageControlVariantThenNoNotificationScheduled() = runBlocking<Unit> {
givenNoInactiveUserNotifications()
setInAppUsageControlVariant()
whenever(useOurAppNotification.canShow()).thenReturn(true)

testee.scheduleNextNotification()

assertNoNotificationScheduled(NotificationScheduler.USE_OUR_APP_WORK_REQUEST_TAG)
}

@Test
fun whenInAppUsageControlVariantAndPrivacyNotificationClearDataCanShowThenPrivacyNotificationIsScheduled() = runBlocking<Unit> {
setInAppUsageControlVariant()
whenever(privacyNotification.canShow()).thenReturn(true)
whenever(clearNotification.canShow()).thenReturn(true)
testee.scheduleNextNotification()

assertNotificationScheduled(PrivacyNotificationWorker::class.jvmName)
}

@Test
fun whenInAppUsageControlVariantAndPrivacyNotificationCanShowButClearDataCannotThenPrivacyNotificationIsScheduled() = runBlocking<Unit> {
setInAppUsageControlVariant()
whenever(privacyNotification.canShow()).thenReturn(true)
whenever(clearNotification.canShow()).thenReturn(false)
testee.scheduleNextNotification()

assertNotificationScheduled(PrivacyNotificationWorker::class.jvmName)
}

@Test
fun whenInAppUsageControlVariantAndPrivacyNotificationCannotShowAndClearNotificationCanShowThenClearNotificationScheduled() = runBlocking<Unit> {
setInAppUsageControlVariant()
whenever(privacyNotification.canShow()).thenReturn(false)
whenever(clearNotification.canShow()).thenReturn(true)
testee.scheduleNextNotification()

assertNotificationScheduled(ClearDataNotificationWorker::class.jvmName)
}

@Test
fun whenInAppUsageControlVariantAndPrivacyNotificationAndClearNotificationCannotShowThenNoNotificationScheduled() = runBlocking<Unit> {
setDefaultVariant()
whenever(privacyNotification.canShow()).thenReturn(false)
whenever(clearNotification.canShow()).thenReturn(false)
testee.scheduleNextNotification()

assertNoNotificationScheduled()
}

private suspend fun givenNoInactiveUserNotifications() {
whenever(privacyNotification.canShow()).thenReturn(false)
whenever(clearNotification.canShow()).thenReturn(false)
}

private fun setInAppUsageVariant() {
whenever(variantManager.getVariant()).thenReturn(
Variant(
"test",
features = listOf(
VariantManager.VariantFeature.InAppUsage,
VariantManager.VariantFeature.RemoveDay1AndDay3Notifications,
VariantManager.VariantFeature.KillOnboarding
),
filterBy = { true }
)
)
}

private fun setInAppUsageSecondControlVariant() {
whenever(variantManager.getVariant()).thenReturn(
Variant(
"test",
features = listOf(
VariantManager.VariantFeature.RemoveDay1AndDay3Notifications,
VariantManager.VariantFeature.KillOnboarding
),
filterBy = { true }
)
)
}

private fun setInAppUsageControlVariant() {
whenever(variantManager.getVariant()).thenReturn(Variant("test", features = emptyList(), filterBy = { true }))
}

private fun setDefaultVariant() {
whenever(variantManager.getVariant()).thenReturn(DEFAULT_VARIANT)
}

private fun assertNotificationScheduled(workerName: String, tag: String = NotificationScheduler.UNUSED_APP_WORK_REQUEST_TAG) {
assertTrue(getScheduledWorkers(tag).any { it.tags.contains(workerName) })
}
Expand Down

0 comments on commit be5132b

Please sign in to comment.