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
866 changes: 866 additions & 0 deletions app/schemas/com.duckduckgo.app.global.db.AppDatabase/34.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,15 @@ import com.duckduckgo.app.cta.ui.CtaViewModel
import com.duckduckgo.app.cta.ui.DaxBubbleCta
import com.duckduckgo.app.cta.ui.DaxDialogCta
import com.duckduckgo.app.cta.ui.HomePanelCta
import com.duckduckgo.app.cta.ui.UseOurAppCta
import com.duckduckgo.app.email.EmailManager
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteDao
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteRepository
import com.duckduckgo.app.global.db.AppDatabase
import com.duckduckgo.app.global.events.db.UserEventEntity
import com.duckduckgo.app.global.events.db.UserEventKey
import com.duckduckgo.app.global.events.db.UserEventsStore
import com.duckduckgo.app.global.install.AppInstallStore
import com.duckduckgo.app.global.model.Site
import com.duckduckgo.app.global.model.SiteFactory
import com.duckduckgo.app.global.useourapp.UseOurAppDetector
import com.duckduckgo.app.global.useourapp.UseOurAppDetector.Companion.USE_OUR_APP_DOMAIN
import com.duckduckgo.app.global.useourapp.UseOurAppDetector.Companion.USE_OUR_APP_SHORTCUT_URL
import com.duckduckgo.app.globalprivacycontrol.GlobalPrivacyControlManager
import com.duckduckgo.app.globalprivacycontrol.GlobalPrivacyControlManager.Companion.GPC_HEADER
import com.duckduckgo.app.globalprivacycontrol.GlobalPrivacyControlManager.Companion.GPC_HEADER_VALUE
Expand All @@ -88,7 +82,6 @@ import com.duckduckgo.app.location.data.LocationPermissionType
import com.duckduckgo.app.location.data.LocationPermissionsDao
import com.duckduckgo.app.location.data.LocationPermissionsRepository
import com.duckduckgo.app.notification.db.NotificationDao
import com.duckduckgo.app.notification.model.UseOurAppNotification
import com.duckduckgo.app.onboarding.store.AppStage
import com.duckduckgo.app.onboarding.store.OnboardingStore
import com.duckduckgo.app.onboarding.store.UserStageStore
Expand Down Expand Up @@ -317,12 +310,9 @@ class BrowserTabViewModelTest {
mockWidgetCapabilities,
mockDismissedCtaDao,
mockUserWhitelistDao,
mockVariantManager,
mockSettingsStore,
mockOnboardingStore,
mockUserStageStore,
mockUserEventsStore,
UseOurAppDetector(mockUserEventsStore),
mockTabRepository,
coroutineRule.testDispatcherProvider
)
Expand Down Expand Up @@ -370,7 +360,6 @@ class BrowserTabViewModelTest {
navigationAwareLoginDetector = mockNavigationAwareLoginDetector,
userEventsStore = mockUserEventsStore,
notificationDao = mockNotificationDao,
useOurAppDetector = UseOurAppDetector(mockUserEventsStore),
variantManager = mockVariantManager,
fileDownloader = mockFileDownloader,
globalPrivacyControl = GlobalPrivacyControlManager(mockSettingsStore),
Expand Down Expand Up @@ -427,25 +416,14 @@ class BrowserTabViewModelTest {
}

@Test
fun whenViewBecomesVisibleAndHomeShowingAndUserIsNotInUseOurAppOnboardingStageThenKeyboardShown() = coroutineRule.runBlocking {
whenever(mockUserStageStore.getUserAppStage()).thenReturn(AppStage.ESTABLISHED)
fun whenViewBecomesVisibleAndHomeShowingThenKeyboardShown() = coroutineRule.runBlocking {
setBrowserShowing(false)

testee.onViewVisible()
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
assertTrue(commandCaptor.allValues.contains(Command.ShowKeyboard))
}

@Test
fun whenViewBecomesVisibleAndHomeShowingAndUserIsInUseOurAppOnboardingStageThenKeyboardHidden() = coroutineRule.runBlocking {
whenever(mockUserStageStore.getUserAppStage()).thenReturn(AppStage.USE_OUR_APP_ONBOARDING)
setBrowserShowing(false)

testee.onViewVisible()
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
assertTrue(commandCaptor.allValues.contains(Command.HideKeyboard))
}

@Test
fun whenViewBecomesVisibleAndHomeCtaPresentThenKeyboardHidden() = coroutineRule.runBlocking {
givenExpectedCtaAddWidgetInstructions()
Expand Down Expand Up @@ -1890,16 +1868,6 @@ class BrowserTabViewModelTest {
assertCommandIssued<Command.LaunchLegacyAddWidget>()
}

@Test
fun whenUserClickedUseOurAppCtaOkButtonThenLaunchAddHomeShortcutAndNavigateCommand() {
whenever(mockOmnibarConverter.convertQueryToUrl(USE_OUR_APP_SHORTCUT_URL, null)).thenReturn(USE_OUR_APP_SHORTCUT_URL)
val cta = UseOurAppCta()
setCta(cta)
testee.onUserClickCtaOkButton()
assertCommandIssued<Command.AddHomeShortcut>()
assertCommandIssued<Navigate>()
}

@Test
fun whenSurveyCtaDismissedAndNoOtherCtaPossibleCtaIsNull() = coroutineRule.runBlocking {
givenShownCtas(CtaId.DAX_INTRO, CtaId.DAX_END)
Expand Down Expand Up @@ -1977,14 +1945,6 @@ class BrowserTabViewModelTest {
verify(mockSurveyDao).cancelScheduledSurveys()
}

@Test
fun whenUserClickedSecondaryCtaButtonInUseOurAppCtaThenLaunchShowKeyboardCommand() {
val cta = UseOurAppCta()
setCta(cta)
testee.onUserClickCtaSecondaryButton()
assertCommandIssued<Command.ShowKeyboard>()
}

@Test
fun whenSurrogateDetectedThenSiteUpdated() {
givenOneActiveTabSelected()
Expand Down Expand Up @@ -2177,30 +2137,6 @@ class BrowserTabViewModelTest {
}
}

@Test
fun whenLoginDetectedAndUrlIsUseOurAppThenRegisterUserEvent() = coroutineRule.runBlocking {
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_FIREPROOF_DIALOG_SEEN)).thenReturn(null)
loginEventLiveData.value = givenLoginDetected(USE_OUR_APP_SHORTCUT_URL)

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

@Test
fun whenLoginDetectedAndUrlIsNotUseOurAppThenDoNotRegisterUserEvent() = coroutineRule.runBlocking {
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_FIREPROOF_DIALOG_SEEN)).thenReturn(null)
loginEventLiveData.value = givenLoginDetected("example.com")

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

@Test
fun whenLoginDetectedAndDialogAlreadySeenThenDoNotRegisterUserEvent() = coroutineRule.runBlocking {
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_FIREPROOF_DIALOG_SEEN)).thenReturn(UserEventEntity(UserEventKey.USE_OUR_APP_FIREPROOF_DIALOG_SEEN))
loginEventLiveData.value = givenLoginDetected(USE_OUR_APP_SHORTCUT_URL)

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

@Test
fun whenUserBrowsingPressesBackThenCannotAddBookmark() {
setupNavigation(skipHome = false, isBrowsing = true, canGoBack = false)
Expand Down Expand Up @@ -2333,163 +2269,6 @@ class BrowserTabViewModelTest {
testee.onUserSubmittedQuery("about:blank")
}

@Test
fun whenViewReadyIfDomainSameAsUseOurAppAfterNotificationSeenThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
whenever(mockNotificationDao.exists(UseOurAppNotification.ID)).thenReturn(true)

testee.onViewReady()

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_NOTIFICATION)
}

@Test
fun whenViewReadyIfDomainSameAsUseOurAppAfterShortcutAddedThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)).thenReturn(UserEventEntity(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED))

testee.onViewReady()

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_SHORTCUT)
}

@Test
fun whenViewReadyIfDomainSameAsUseOurAppAfterDeleteCtaShownThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
whenever(mockDismissedCtaDao.exists(CtaId.USE_OUR_APP_DELETION)).thenReturn(true)

testee.onViewReady()

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_DELETE_CTA)
}

@Test
fun whenViewReadyIfDomainSameAsUseOurAppThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()

testee.onViewReady()

verify(mockPixel).fire(AppPixelName.UOA_VISITED)
}

@Test
fun whenViewReadyIfDomainIsNotTheSameAsUseOurAppAfterNotificationSeenThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockNotificationDao.exists(UseOurAppNotification.ID)).thenReturn(true)

testee.onViewReady()

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_NOTIFICATION)
}

@Test
fun whenViewReadyIfDomainIsNotTheSameAsUseOurAppAfterShortcutAddedThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)).thenReturn(UserEventEntity(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED))

testee.onViewReady()

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_SHORTCUT)
}

@Test
fun whenViewReadyIfDomainIsNotTheSameAsUseOurAppAfterDeleteCtaShownThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockDismissedCtaDao.exists(CtaId.USE_OUR_APP_DELETION)).thenReturn(true)

testee.onViewReady()

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_DELETE_CTA)
}

@Test
fun whenViewReadyIfDomainIsNotTheSameAsUseOurAppAThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()

testee.onViewReady()

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED)
}

@Test
fun whenPageChangedIfPreviousOneWasNotUseOurAppSiteAfterNotificationSeenThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockNotificationDao.exists(UseOurAppNotification.ID)).thenReturn(true)

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_NOTIFICATION)
}

@Test
fun whenPageChangedIfPreviousOneWasNotUseOurAppSiteAfterShortcutAddedThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)).thenReturn(UserEventEntity(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED))

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_SHORTCUT)
}

@Test
fun whenPageChangedIfPreviousOneWasNotUseOurAppSiteAfterDeleteCtaShownThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()
whenever(mockDismissedCtaDao.exists(CtaId.USE_OUR_APP_DELETION)).thenReturn(true)

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel).fire(AppPixelName.UOA_VISITED_AFTER_DELETE_CTA)
}

@Test
fun whenPageChangedIfPreviousOneWasNotUseOurAppSiteThenPixelSent() = coroutineRule.runBlocking {
givenUseOurAppSiteIsNotSelected()

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel).fire(AppPixelName.UOA_VISITED)
}

@Test
fun whenPageChangedIfPreviousOneWasUseOurAppSiteAfterNotificationSeenThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
whenever(mockNotificationDao.exists(UseOurAppNotification.ID)).thenReturn(true)

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_NOTIFICATION)
}

@Test
fun whenPageChangedIfPreviousOneWasUseOurAppSiteAfterShortcutAddedThenPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
val timestampEntity = UserEventEntity(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)
whenever(mockUserEventsStore.getUserEvent(UserEventKey.USE_OUR_APP_SHORTCUT_ADDED)).thenReturn(timestampEntity)

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_SHORTCUT)
}

@Test
fun whenPageChangedIfPreviousOneWasUseOurAppSiteThenAfterDeleteCtaShownPixelNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()
whenever(mockDismissedCtaDao.exists(CtaId.USE_OUR_APP_DELETION)).thenReturn(true)

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED_AFTER_DELETE_CTA)
}

@Test
fun whenPageChangedIfPreviousOneWasUseOurAppSiteThenNotSent() = coroutineRule.runBlocking {
givenUseOurAppSiteSelected()

loadUrl(USE_OUR_APP_DOMAIN, isBrowserShowing = true)

verify(mockPixel, never()).fire(AppPixelName.UOA_VISITED)
}

@Test
fun whenDosAttackDetectedThenErrorIsShown() {
testee.dosAttackDetected()
Expand Down Expand Up @@ -3365,26 +3144,6 @@ class BrowserTabViewModelTest {
testee.loadData("TAB_ID", "https://example.com", false)
}

private fun givenUseOurAppSiteSelected() {
whenever(mockOmnibarConverter.convertQueryToUrl(USE_OUR_APP_DOMAIN, null)).thenReturn(USE_OUR_APP_DOMAIN)
val site: Site = mock()
whenever(site.url).thenReturn(USE_OUR_APP_DOMAIN)
val siteLiveData = MutableLiveData<Site>()
siteLiveData.value = site
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
testee.loadData("TAB_ID", USE_OUR_APP_DOMAIN, false)
}

private fun givenUseOurAppSiteIsNotSelected() {
whenever(mockOmnibarConverter.convertQueryToUrl("example.com", null)).thenReturn("example.com")
val site: Site = mock()
whenever(site.url).thenReturn("example.com")
val siteLiveData = MutableLiveData<Site>()
siteLiveData.value = site
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
testee.loadData("TAB_ID", "example.com", false)
}

private fun givenFireproofWebsiteDomain(vararg fireproofWebsitesDomain: String) {
fireproofWebsitesDomain.forEach {
fireproofWebsiteDao.insert(FireproofWebsiteEntity(domain = it))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import com.duckduckgo.app.global.rating.AppEnjoymentPromptEmitter
import com.duckduckgo.app.global.rating.AppEnjoymentPromptOptions
import com.duckduckgo.app.global.rating.AppEnjoymentUserEventRecorder
import com.duckduckgo.app.global.rating.PromptCount
import com.duckduckgo.app.global.useourapp.UseOurAppDetector
import com.duckduckgo.app.global.useourapp.UseOurAppDetector.Companion.USE_OUR_APP_DOMAIN
import com.duckduckgo.app.pixels.AppPixelName
import com.duckduckgo.app.privacy.ui.PrivacyDashboardActivity
import com.duckduckgo.app.runBlocking
Expand Down Expand Up @@ -101,7 +99,6 @@ class BrowserViewModelTest {
dataClearer = mockAutomaticDataClearer,
appEnjoymentPromptEmitter = mockAppEnjoymentPromptEmitter,
appEnjoymentUserEventRecorder = mockAppEnjoymentUserEventRecorder,
useOurAppDetector = UseOurAppDetector(mockUserEventsStore),
dispatchers = coroutinesTestRule.testDispatcherProvider,
pixel = mockPixel
)
Expand Down Expand Up @@ -204,15 +201,7 @@ class BrowserViewModelTest {
}

@Test
fun whenOpenShortcutIfUrlIsUseOurAppDomainThenFirePixel() {
val url = "http://m.$USE_OUR_APP_DOMAIN"
whenever(mockOmnibarEntryConverter.convertQueryToUrl(url)).thenReturn(url)
testee.onOpenShortcut(url)
verify(mockPixel).fire(AppPixelName.USE_OUR_APP_SHORTCUT_OPENED)
}

@Test
fun whenOpenShortcutIfUrlIsNotUSeOurAppUrlThenFirePixel() {
fun whenOpenShortcutThenFirePixel() {
val url = "example.com"
whenever(mockOmnibarEntryConverter.convertQueryToUrl(url)).thenReturn(url)
testee.onOpenShortcut(url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import androidx.test.annotation.UiThreadTest
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.app.browser.logindetection.LoginDetectionJavascriptInterface.Companion.JAVASCRIPT_INTERFACE_NAME
import com.duckduckgo.app.global.events.db.UserEventsStore
import com.duckduckgo.app.global.useourapp.UseOurAppDetector
import com.duckduckgo.app.runBlocking
import com.duckduckgo.app.settings.db.SettingsDataStore
import com.nhaarman.mockitokotlin2.*
Expand All @@ -40,9 +38,7 @@ class JsLoginDetectorTest {
var coroutinesTestRule = CoroutineTestRule()

private val settingsDataStore: SettingsDataStore = mock()
private val userEventsStore: UserEventsStore = mock()

private val testee = JsLoginDetector(settingsDataStore, UseOurAppDetector(userEventsStore))
private val testee = JsLoginDetector(settingsDataStore)

@UiThreadTest
@Test
Expand Down
Loading