Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.duckduckgo.app.browser.rating.di.RatingModule
import com.duckduckgo.app.global.exception.UncaughtExceptionModule
import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule
import com.duckduckgo.app.onboarding.di.OnboardingModule
import com.duckduckgo.app.onboarding.di.WelcomePageModule
import com.duckduckgo.app.surrogates.di.ResourceSurrogateModule
import com.duckduckgo.app.trackerdetection.di.TrackerDetectionModule
import com.duckduckgo.app.usage.di.AppUsageModule
Expand Down Expand Up @@ -72,7 +73,8 @@ import javax.inject.Singleton
UncaughtExceptionModule::class,
PlayStoreReferralModule::class,
CoroutinesModule::class,
CertificateTrustedStoreModule::class
CertificateTrustedStoreModule::class,
WelcomePageModule::class
]
)
interface TestAppComponent : AppComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package com.duckduckgo.app.onboarding.ui

import com.duckduckgo.app.browser.defaultbrowsing.DefaultBrowserDetector
import com.duckduckgo.app.global.DefaultRoleBrowserDialog
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import org.junit.Assert.assertEquals
Expand All @@ -33,11 +33,11 @@ class OnboardingPageManagerPageCountTest(private val testCase: TestCase) {
private lateinit var testee: OnboardingPageManager
private val onboardingPageBuilder: OnboardingPageBuilder = mock()
private val mockDefaultBrowserDetector: DefaultBrowserDetector = mock()
private val variantManager: VariantManager = mock()
private val defaultRoleBrowserDialog: DefaultRoleBrowserDialog = mock()

@Before
fun setup() {
testee = OnboardingPageManagerWithTrackerBlocking(variantManager, onboardingPageBuilder, mockDefaultBrowserDetector)
testee = OnboardingPageManagerWithTrackerBlocking(defaultRoleBrowserDialog, onboardingPageBuilder, mockDefaultBrowserDetector)
}

@Test
Expand All @@ -49,7 +49,6 @@ class OnboardingPageManagerPageCountTest(private val testCase: TestCase) {
}

private fun configureDefaultBrowserPageConfig() {
whenever(variantManager.getVariant()).thenReturn(testCase.variant)
if (testCase.defaultBrowserPage) {
configureDeviceSupportsDefaultBrowser()
} else {
Expand All @@ -60,20 +59,13 @@ class OnboardingPageManagerPageCountTest(private val testCase: TestCase) {
companion object {

private val otherVariant = Variant(key = "variant", features = listOf(), filterBy = { true })
private val defaultBrowserVariant = Variant(
key = "variant",
features = listOf(VariantManager.VariantFeature.SetDefaultBrowserDialog),
filterBy = { true }
)

@JvmStatic
@Parameterized.Parameters(name = "Test case: {index} - {0}")
fun testData(): Array<TestCase> {
return arrayOf(
TestCase(false, 1, otherVariant),
TestCase(true, 2, otherVariant),
TestCase(false, 1, defaultBrowserVariant),
TestCase(true, 1, defaultBrowserVariant)
TestCase(true, 2, otherVariant)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
package com.duckduckgo.app.onboarding.ui

import com.duckduckgo.app.browser.defaultbrowsing.DefaultBrowserDetector
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.global.DefaultRoleBrowserDialog
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import org.junit.Assert.assertEquals
Expand All @@ -30,35 +29,29 @@ class OnboardingPageManagerTest {
private lateinit var testee: OnboardingPageManager
private val onboardingPageBuilder: OnboardingPageBuilder = mock()
private val mockDefaultBrowserDetector: DefaultBrowserDetector = mock()
private val variantManager: VariantManager = mock()
private val defaultBrowserVariant = Variant(
key = "variant",
features = listOf(VariantManager.VariantFeature.SetDefaultBrowserDialog),
filterBy = { true }
)
private val otherVariant = Variant(key = "variant", features = listOf(), filterBy = { true })
private val defaultRoleBrowserDialog: DefaultRoleBrowserDialog = mock()

@Before
fun setup() {
testee = OnboardingPageManagerWithTrackerBlocking(variantManager, onboardingPageBuilder, mockDefaultBrowserDetector)
testee = OnboardingPageManagerWithTrackerBlocking(defaultRoleBrowserDialog, onboardingPageBuilder, mockDefaultBrowserDetector)
}

@Test
fun whenDDGIsNotDefaultBrowserThenExpectedOnboardingPagesAreTwo() {
configureDeviceSupportsDefaultBrowser()
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(false)
whenever(variantManager.getVariant()).thenReturn(otherVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(false)

testee.buildPageBlueprints()

assertEquals(2, testee.pageCount())
}

@Test
fun whenDDGIsNotDefaultBrowserAndBrowserDialogVariantThenExpectedOnboardingPagesAre1() {
fun whenDDGIsNotDefaultBrowserAndShouldShowBrowserDialogThenExpectedOnboardingPagesAre1() {
configureDeviceSupportsDefaultBrowser()
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(false)
whenever(variantManager.getVariant()).thenReturn(defaultBrowserVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(true)

testee.buildPageBlueprints()

Expand All @@ -69,18 +62,18 @@ class OnboardingPageManagerTest {
fun whenDDGAsDefaultBrowserThenSinglePageOnBoarding() {
configureDeviceSupportsDefaultBrowser()
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(true)
whenever(variantManager.getVariant()).thenReturn(otherVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(false)

testee.buildPageBlueprints()

assertEquals(1, testee.pageCount())
}

@Test
fun whenDDGAsDefaultBrowserAndBrowserDialogVariantThenSinglePageOnBoarding() {
fun whenDDGAsDefaultBrowserAndShouldShowBrowserDialogThenSinglePageOnBoarding() {
configureDeviceSupportsDefaultBrowser()
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(true)
whenever(variantManager.getVariant()).thenReturn(defaultBrowserVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(true)

testee.buildPageBlueprints()

Expand All @@ -90,17 +83,17 @@ class OnboardingPageManagerTest {
@Test
fun whenDeviceDoesNotSupportDefaultBrowserThenSinglePageOnBoarding() {
configureDeviceDoesNotSupportDefaultBrowser()
whenever(variantManager.getVariant()).thenReturn(otherVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(false)

testee.buildPageBlueprints()

assertEquals(1, testee.pageCount())
}

@Test
fun whenDeviceDoesNotSupportDefaultBrowserAndBrowserDialogVariantThenSinglePageOnBoarding() {
fun whenDeviceDoesNotSupportDefaultBrowserAndShouldShowBrowserDialogThenSinglePageOnBoarding() {
configureDeviceDoesNotSupportDefaultBrowser()
whenever(variantManager.getVariant()).thenReturn(defaultBrowserVariant)
whenever(defaultRoleBrowserDialog.shouldShowDialog()).thenReturn(true)

testee.buildPageBlueprints()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import android.content.Intent
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.app.global.DefaultRoleBrowserDialogExperiment
import com.duckduckgo.app.global.DefaultRoleBrowserDialog
import com.duckduckgo.app.global.install.AppInstallStore
import com.duckduckgo.app.runBlocking
import com.duckduckgo.app.statistics.pixels.Pixel
Expand Down Expand Up @@ -58,7 +58,7 @@ class WelcomePageViewModelTest {
private lateinit var appInstallStore: AppInstallStore

@Mock
private lateinit var defaultRoleBrowserDialogExperiment: DefaultRoleBrowserDialogExperiment
private lateinit var defaultRoleBrowserDialog: DefaultRoleBrowserDialog

private val events = ConflatedBroadcastChannel<WelcomePageView.Event>()

Expand All @@ -73,15 +73,15 @@ class WelcomePageViewModelTest {
appInstallStore,
InstrumentationRegistry.getInstrumentation().targetContext,
pixel,
defaultRoleBrowserDialogExperiment
defaultRoleBrowserDialog
)

viewEvents = events.asFlow().flatMapLatest { viewModel.reduce(it) }
}

@Test
fun whenOnPrimaryCtaClickedAndShouldNotShowXpThenFinish() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialogExperiment.shouldShowExperiment())
fun whenOnPrimaryCtaClickedAndShouldNotShowDialogThenFinish() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialog.shouldShowDialog())
.thenReturn(false)

val launch = launch {
Expand All @@ -95,11 +95,11 @@ class WelcomePageViewModelTest {
}

@Test
fun whenOnPrimaryCtaClickedAndShouldShowXpAndShowThenEmitShowDialog() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialogExperiment.shouldShowExperiment())
fun whenOnPrimaryCtaClickedAndShouldShowDialogAndShowThenEmitShowDialog() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialog.shouldShowDialog())
.thenReturn(true)
val intent = Intent()
whenever(defaultRoleBrowserDialogExperiment.createIntent(any()))
whenever(defaultRoleBrowserDialog.createIntent(any()))
.thenReturn(intent)

val launch = launch {
Expand All @@ -113,10 +113,10 @@ class WelcomePageViewModelTest {
}

@Test
fun whenOnPrimaryCtaClickedAndShouldShowXpNullIntentThenFireAndFinish() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialogExperiment.shouldShowExperiment())
fun whenOnPrimaryCtaClickedAndShouldShowDialogNullIntentThenFireAndFinish() = coroutineRule.runBlocking {
whenever(defaultRoleBrowserDialog.shouldShowDialog())
.thenReturn(true)
whenever(defaultRoleBrowserDialogExperiment.createIntent(any()))
whenever(defaultRoleBrowserDialog.createIntent(any()))
.thenReturn(null)

val launch = launch {
Expand All @@ -132,15 +132,15 @@ class WelcomePageViewModelTest {
}

@Test
fun whenOnDefaultBrowserSetThenCallExperimentShownFireAndFinish() = coroutineRule.runBlocking {
fun whenOnDefaultBrowserSetThenCallDialogShownFireAndFinish() = coroutineRule.runBlocking {
val launch = launch {
viewEvents.collect { state ->
assertTrue(state == WelcomePageView.State.Finish)
}
}
events.send(WelcomePageView.Event.OnDefaultBrowserSet)

verify(defaultRoleBrowserDialogExperiment).experimentShown()
verify(defaultRoleBrowserDialog).dialogShown()
verify(pixel).fire(
Pixel.PixelName.DEFAULT_BROWSER_SET,
mapOf(Pixel.PixelParameter.DEFAULT_BROWSER_SET_FROM_ONBOARDING to true.toString())
Expand All @@ -150,15 +150,15 @@ class WelcomePageViewModelTest {
}

@Test
fun whenOnDefaultBrowserNotSetThenCallExperimentShownFireAndFinish() = coroutineRule.runBlocking {
fun whenOnDefaultBrowserNotSetThenCallDialogShownFireAndFinish() = coroutineRule.runBlocking {
val launch = launch {
viewEvents.collect { state ->
assertTrue(state == WelcomePageView.State.Finish)
}
}
events.send(WelcomePageView.Event.OnDefaultBrowserNotSet)

verify(defaultRoleBrowserDialogExperiment).experimentShown()
verify(defaultRoleBrowserDialog).dialogShown()
verify(pixel).fire(
Pixel.PixelName.DEFAULT_BROWSER_NOT_SET,
mapOf(Pixel.PixelParameter.DEFAULT_BROWSER_SET_FROM_ONBOARDING to true.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,6 @@ class VariantManagerTest {
assertEquals(SerpHeaderQueryReplacement, variant.features[0])
}

@Test
fun roleManagerDefaultBrowserDialogControlHasExpectedWeightAndFeatures() {
val variant = variants.first { it.key == "zt" }
assertEqualsDouble(1.0, variant.weight)
assertTrue(variant.features.isEmpty())
}

@Test
fun roleManagerDefaultBrowserDialogTreatmentHasExpectedWeightAndFeatures() {
val variant = variants.first { it.key == "zu" }
assertEqualsDouble(1.0, variant.weight)
assertTrue(variant.features == listOf(SetDefaultBrowserDialog))
}

@Test
fun verifyNoDuplicateVariantNames() {
val existingNames = mutableSetOf<String>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import com.duckduckgo.app.launch.LaunchBridgeActivity
import com.duckduckgo.app.location.ui.LocationPermissionsActivity
import com.duckduckgo.app.location.ui.SiteLocationPermissionDialog
import com.duckduckgo.app.notification.NotificationHandlerService
import com.duckduckgo.app.onboarding.di.WelcomePageModule
import com.duckduckgo.app.onboarding.ui.OnboardingActivity
import com.duckduckgo.app.onboarding.ui.page.DefaultBrowserPage
import com.duckduckgo.app.onboarding.ui.page.WelcomePage
Expand Down Expand Up @@ -185,9 +184,7 @@ abstract class AndroidBindingModule {
@ContributesAndroidInjector
abstract fun brokenSiteNegativeFeedbackFragment(): BrokenSiteNegativeFeedbackFragment

@ContributesAndroidInjector(
modules = [WelcomePageModule::class]
)
@ContributesAndroidInjector
abstract fun welcomePage(): WelcomePage

@ContributesAndroidInjector
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/duckduckgo/app/di/AppComponent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.duckduckgo.app.global.DuckDuckGoApplication
import com.duckduckgo.app.global.exception.UncaughtExceptionModule
import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule
import com.duckduckgo.app.onboarding.di.OnboardingModule
import com.duckduckgo.app.onboarding.di.WelcomePageModule
import com.duckduckgo.app.surrogates.di.ResourceSurrogateModule
import com.duckduckgo.app.trackerdetection.di.TrackerDetectionModule
import com.duckduckgo.app.usage.di.AppUsageModule
Expand Down Expand Up @@ -70,7 +71,8 @@ import javax.inject.Singleton
UncaughtExceptionModule::class,
PlayStoreReferralModule::class,
CoroutinesModule::class,
CertificateTrustedStoreModule::class
CertificateTrustedStoreModule::class,
WelcomePageModule::class
]
)
interface AppComponent : AndroidInjector<DuckDuckGoApplication> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,17 @@ import android.content.Context
import android.content.Intent
import android.os.Build
import com.duckduckgo.app.global.install.AppInstallStore
import com.duckduckgo.app.statistics.VariantManager
import timber.log.Timber

interface DefaultRoleBrowserDialogExperiment {
interface DefaultRoleBrowserDialog {
fun createIntent(context: Context): Intent?
fun shouldShowExperiment(): Boolean
fun experimentShown()
fun shouldShowDialog(): Boolean
fun dialogShown()
}

class RealDefaultRoleBrowserDialogExperiment(
private val appInstallStore: AppInstallStore,
private val variantManager: VariantManager
) : DefaultRoleBrowserDialogExperiment {
class RealDefaultRoleBrowserDialog(
private val appInstallStore: AppInstallStore
) : DefaultRoleBrowserDialog {

/**
* @return an Intent to launch the role browser dialog
Expand All @@ -56,14 +54,14 @@ class RealDefaultRoleBrowserDialogExperiment(
return null
}

override fun shouldShowExperiment(): Boolean {
override fun shouldShowDialog(): Boolean {
// The second and subsequent times the dialog is shown, the system allows the user to click on "don't show again"
// we will get the same result as if the dialog was just dismissed.
return variantManager.getVariant().hasFeature(VariantManager.VariantFeature.SetDefaultBrowserDialog) &&
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
appInstallStore.newDefaultBrowserDialogCount < DEFAULT_BROWSER_DIALOG_MAX_ATTEMPTS
}

override fun experimentShown() {
override fun dialogShown() {
appInstallStore.newDefaultBrowserDialogCount++
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package com.duckduckgo.app.onboarding.di

import com.duckduckgo.app.browser.defaultbrowsing.DefaultBrowserDetector
import com.duckduckgo.app.global.DefaultRoleBrowserDialog
import com.duckduckgo.app.onboarding.ui.OnboardingFragmentPageBuilder
import com.duckduckgo.app.onboarding.ui.OnboardingPageBuilder
import com.duckduckgo.app.onboarding.ui.OnboardingPageManager
import com.duckduckgo.app.onboarding.ui.OnboardingPageManagerWithTrackerBlocking
import com.duckduckgo.app.statistics.VariantManager
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
Expand All @@ -31,11 +31,11 @@ class OnboardingModule {

@Provides
fun onboardingPageManger(
variantManager: VariantManager,
defaultRoleBrowserDialog: DefaultRoleBrowserDialog,
onboardingPageBuilder: OnboardingPageBuilder,
defaultBrowserDetector: DefaultBrowserDetector
): OnboardingPageManager {
return OnboardingPageManagerWithTrackerBlocking(variantManager, onboardingPageBuilder, defaultBrowserDetector)
return OnboardingPageManagerWithTrackerBlocking(defaultRoleBrowserDialog, onboardingPageBuilder, defaultBrowserDetector)
}

@Provides
Expand Down
Loading