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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import com.duckduckgo.app.global.install.AppInstallStore
import com.duckduckgo.app.global.model.SiteFactory
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao
import com.duckduckgo.app.privacy.db.NetworkLeaderboardEntry
import com.duckduckgo.app.privacy.db.SiteVisitedEntity
import com.duckduckgo.app.privacy.model.PrivacyPractices
import com.duckduckgo.app.privacy.store.PrevalenceStore
import com.duckduckgo.app.settings.db.SettingsDataStore
Expand Down Expand Up @@ -298,7 +297,7 @@ class BrowserTabViewModelTest {
fun whenTrackerDetectedThenNetworkLeaderboardUpdated() {
val event = TrackingEvent("http://www.example.com", "http://www.tracker.com/tracker.js", TrackerNetwork("Network1", "www.tracker.com"), false)
testee.trackerDetected(event)
verify(mockNetworkLeaderboardDao).insert(NetworkLeaderboardEntry("Network1", "www.example.com"))
verify(mockNetworkLeaderboardDao).incrementNetworkCount("Network1")
}

@Test
Expand Down Expand Up @@ -389,15 +388,15 @@ class BrowserTabViewModelTest {
isBrowsing(true)
testee.loadingStarted("http://example.com/abc")
testee.loadingFinished("http://example.com/abc")
verify(mockNetworkLeaderboardDao).insert(SiteVisitedEntity("example.com"))
verify(mockNetworkLeaderboardDao).incrementSitesVisited()
}

@Test
fun whenNotBrowsingAndLoadingFinishedWithUrlThenSiteVisitedEntryNotAddedToLeaderboardDao() {
isBrowsing(false)
testee.loadingStarted("http://example.com/abc")
testee.loadingFinished("http://example.com/abc")
verify(mockNetworkLeaderboardDao, never()).insert(SiteVisitedEntity("example.com"))
verify(mockNetworkLeaderboardDao, never()).incrementSitesVisited()
}

@Test
Expand Down Expand Up @@ -443,13 +442,13 @@ class BrowserTabViewModelTest {
@Test
fun whenLoadingFinishedWithNoUrlThenSiteVisitedEntryNotAddedToLeaderboardDao() {
testee.loadingFinished(null)
verify(mockNetworkLeaderboardDao, never()).insert(SiteVisitedEntity("example.com"))
verify(mockNetworkLeaderboardDao, never()).incrementSitesVisited()
}

@Test
fun whenTrackerDetectedThenSiteVisitedEntryAddedToLeaderboardDao() {
testee.trackerDetected(TrackingEvent("http://example.com/abc", "http://tracker.com", TrackerNetwork("Network", "http:// netwotk.com"), true))
verify(mockNetworkLeaderboardDao).insert(SiteVisitedEntity("example.com"))
verify(mockNetworkLeaderboardDao).incrementSitesVisited()
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AppDatabaseTest {
testHelper.createDatabase(TEST_DB_NAME, 2).use {
it.execSQL("INSERT INTO `network_leaderboard` VALUES ('Network2', 'example.com')")
}
assertTrue(database().networkLeaderboardDao().trackerNetworkTally().blockingObserve()!!.isEmpty())
assertTrue(database().networkLeaderboardDao().trackerNetworkLeaderboard().blockingObserve()!!.isEmpty())
}

@Test
Expand Down Expand Up @@ -120,6 +120,11 @@ class AppDatabaseTest {
createDatabaseAndMigrate(11, 12, AppDatabase.MIGRATION_11_TO_12)
}

@Test
fun whenMigratingFromVersion12To13ThenValidationSucceeds() {
createDatabaseAndMigrate(12, 13, AppDatabase.MIGRATION_12_TO_13)
}

@Test
fun whenMigratingFromVersion11To12ThenTabsDoNotSkipHome() {
testHelper.createDatabase(TEST_DB_NAME, 11).use {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import androidx.room.Room
import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.blockingObserve
import com.duckduckgo.app.global.db.AppDatabase
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.NetworkTally
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
Expand Down Expand Up @@ -54,31 +53,34 @@ class NetworkLeaderboardDaoTest {
}

@Test
fun whenNetworksInsertedThenAddedToTallyWithCount() {
dao.insert(NetworkLeaderboardEntry("Network1", domainVisited = "www.example1.com"))
dao.insert(NetworkLeaderboardEntry("Network2", domainVisited = "www.example2.com"))
dao.insert(NetworkLeaderboardEntry("Network3", domainVisited = "www.example3.com"))

val data: List<NetworkTally>? = dao.trackerNetworkTally().blockingObserve()
assertEquals(3, data!!.size)
assertTrue(data.contains(NetworkTally("Network1", 1)))
assertTrue(data.contains(NetworkTally("Network2", 1)))
assertTrue(data.contains(NetworkTally("Network3", 1)))
fun whenNetworkThatDoesNotExistIncrementedThenAddedToDatabase() {
dao.incrementNetworkCount("Network1")
val data: List<NetworkLeaderboardEntry>? = dao.trackerNetworkLeaderboard().blockingObserve()
assertEquals(1, data!!.size)
assertTrue(data.contains(NetworkLeaderboardEntry("Network1", 1)))
}


@Test
fun whenNetworksHaveMultipleDomainsThenAddedToTallyWithCountInDescendingOrder() {
dao.insert(NetworkLeaderboardEntry("Network1", domainVisited = "www.example1.com"))
dao.insert(NetworkLeaderboardEntry("Network2", domainVisited = "www.example1.com"))
dao.insert(NetworkLeaderboardEntry("Network2", domainVisited = "www.example2.com"))
dao.insert(NetworkLeaderboardEntry("Network2", domainVisited = "www.example3.com"))
dao.insert(NetworkLeaderboardEntry("Network3", domainVisited = "www.example3.com"))
dao.insert(NetworkLeaderboardEntry("Network3", domainVisited = "www.example4.com"))
fun whenNetworksIncrementedMultipleTimesThenReturnedWithCountInDescendingOrder() {
dao.incrementNetworkCount("Network1")
dao.incrementNetworkCount("Network2")
dao.incrementNetworkCount("Network2")
dao.incrementNetworkCount("Network2")
dao.incrementNetworkCount("Network3")
dao.incrementNetworkCount("Network3")

val data: List<NetworkLeaderboardEntry> = dao.trackerNetworkLeaderboard().blockingObserve()!!
assertEquals(NetworkLeaderboardEntry("Network2", 3), data[0])
assertEquals(NetworkLeaderboardEntry("Network3", 2), data[1])
assertEquals(NetworkLeaderboardEntry("Network1", 1), data[2])
}

val data: List<NetworkTally> = dao.trackerNetworkTally().blockingObserve()!!
assertEquals(NetworkTally("Network2", 3), data[0])
assertEquals(NetworkTally("Network3", 2), data[1])
assertEquals(NetworkTally("Network1", 1), data[2])
@Test
fun whenSiteVisitedIncremenetedThenSiteVisitedCountIncreaesByOne() {
dao.incrementSitesVisited()
assertEquals(1, dao.sitesVisited().blockingObserve())
dao.incrementSitesVisited()
assertEquals(2, dao.sitesVisited().blockingObserve())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package com.duckduckgo.app.privacy.renderer

import androidx.test.platform.app.InstrumentationRegistry
import com.duckduckgo.app.browser.R
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.NetworkTally
import com.duckduckgo.app.privacy.db.NetworkLeaderboardEntry
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
Expand Down Expand Up @@ -65,26 +65,26 @@ class TrackersRendererTest {
}

@Test
fun whenTotalDomainsIsZeroThenPercentageIsBlank() {
val text = testee.networkPercentage(NetworkTally("", 10), 0)
fun whenSitestVisitedIsZeroThenPercentageIsBlank() {
val text = testee.networkPercentage(NetworkLeaderboardEntry("", 10), 0)
assertEquals("", text)
}

@Test
fun whenDomainCountIsZeroThenPercentageIsBlank() {
val text = testee.networkPercentage(NetworkTally("", 0), 10)
fun whenNetworkCountIsZeroThenPercentageIsBlank() {
val text = testee.networkPercentage(NetworkLeaderboardEntry("", 0), 10)
assertEquals("", text)
}

@Test
fun whenPortionIsRecurringFractionThenPercentageIsRoundNumber() {
val text = testee.networkPercentage(NetworkTally("", 10), 30)
val text = testee.networkPercentage(NetworkLeaderboardEntry("", 10), 30)
assertEquals("33%", text)
}

@Test
fun whenPortionIsHalfThenPercentageIs50Percent() {
val text = testee.networkPercentage(NetworkTally("", 10), 20)
val text = testee.networkPercentage(NetworkLeaderboardEntry("", 10), 20)
assertEquals("50%", text)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import com.duckduckgo.app.global.model.Site
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.NetworkTally
import com.duckduckgo.app.privacy.db.NetworkLeaderboardEntry
import com.duckduckgo.app.privacy.model.HttpsStatus
import com.duckduckgo.app.privacy.model.PrivacyGrade
import com.duckduckgo.app.privacy.model.PrivacyPractices
Expand All @@ -47,23 +47,23 @@ class PrivacyDashboardViewModelTest {

private var viewStateObserver: Observer<PrivacyDashboardViewModel.ViewState> = mock()
private var settingStore: PrivacySettingsStore = mock()
private var networkLeaderboard: NetworkLeaderboardDao = mock()
private var networkTallyLiveData: LiveData<List<NetworkTally>> = mock()
private var domainsVisitedLiveData: LiveData<Int> = mock()
private var networkLeaderboardDao: NetworkLeaderboardDao = mock()
private var networkLeaserboardLiveData: LiveData<List<NetworkLeaderboardEntry>> = mock()
private var sitesVisitedLiveData: LiveData<Int> = mock()
private var mockPixel: Pixel = mock()

private val testee: PrivacyDashboardViewModel by lazy {
val model = PrivacyDashboardViewModel(settingStore, networkLeaderboard, mockPixel)
val model = PrivacyDashboardViewModel(settingStore, networkLeaderboardDao, mockPixel)
model.viewState.observeForever(viewStateObserver)
model
}

@Before
fun before() {
whenever(domainsVisitedLiveData.value).thenReturn(0)
whenever(networkTallyLiveData.value).thenReturn(emptyList())
whenever(networkLeaderboard.domainsVisitedCount()).thenReturn(domainsVisitedLiveData)
whenever(networkLeaderboard.trackerNetworkTally()).thenReturn(networkTallyLiveData)
whenever(sitesVisitedLiveData.value).thenReturn(0)
whenever(networkLeaserboardLiveData.value).thenReturn(emptyList())
whenever(networkLeaderboardDao.sitesVisited()).thenReturn(sitesVisitedLiveData)
whenever(networkLeaderboardDao.trackerNetworkLeaderboard()).thenReturn(networkLeaserboardLiveData)
}

@After
Expand Down Expand Up @@ -151,50 +151,50 @@ class PrivacyDashboardViewModelTest {
}

@Test
fun whenNetworkCountIsAtLeastThreeAndTotalDomainsIsOverThirtyThenShowSummaryIsTrue() {
val first = NetworkTally("Network1", 5)
val second = NetworkTally("Network2", 3)
val third = NetworkTally("Network3", 3)
testee.onTrackerNetworkTallyChanged(listOf(first, second, third))
testee.onDomainsVisitedChanged(31)
fun whenNetworkCountIsAtLeastThreeAndTotalSitesIsOverThirtyThenShowSummaryIsTrue() {
val first = NetworkLeaderboardEntry("Network1", 5)
val second = NetworkLeaderboardEntry("Network2", 3)
val third = NetworkLeaderboardEntry("Network3", 3)
testee.onTrackerNetworkEntriesChanged(listOf(first, second, third))
testee.onSitesVisitedChanged(31)
assertTrue(testee.viewState.value!!.showTrackerNetworkLeaderboard)
}

@Test
fun whenNetworkCountIsLessThanThreeThenShowSummaryIsFalse() {
val first = NetworkTally("Network1", 5)
val second = NetworkTally("Network2", 3)
testee.onTrackerNetworkTallyChanged(listOf(first, second))
testee.onDomainsVisitedChanged(31)
val first = NetworkLeaderboardEntry("Network1", 5)
val second = NetworkLeaderboardEntry("Network2", 3)
testee.onTrackerNetworkEntriesChanged(listOf(first, second))
testee.onSitesVisitedChanged(31)
assertFalse(testee.viewState.value!!.showTrackerNetworkLeaderboard)
}

@Test
fun whenDomainsIsNotOverThirtyThenShowSummaryIsFalse() {
val first = NetworkTally("Network1", 5)
val second = NetworkTally("Network2", 3)
val third = NetworkTally("Network3", 3)
testee.onTrackerNetworkTallyChanged(listOf(first, second, third))
testee.onDomainsVisitedChanged(30)
fun whenSitesIsNotOverThirtyThenShowSummaryIsFalse() {
val first = NetworkLeaderboardEntry("Network1", 5)
val second = NetworkLeaderboardEntry("Network2", 3)
val third = NetworkLeaderboardEntry("Network3", 3)
testee.onTrackerNetworkEntriesChanged(listOf(first, second, third))
testee.onSitesVisitedChanged(30)
assertFalse(testee.viewState.value!!.showTrackerNetworkLeaderboard)
}

@Test
fun whenNetworkLeaderboardDataAvailableThenViewStateUpdated() {
val first = NetworkTally("Network1", 5)
val second = NetworkTally("Network2", 3)
testee.onTrackerNetworkTallyChanged(listOf(first, second))
val first = NetworkLeaderboardEntry("Network1", 5)
val second = NetworkLeaderboardEntry("Network2", 3)
testee.onTrackerNetworkEntriesChanged(listOf(first, second))

val viewState = testee.viewState.value!!
assertEquals(first, viewState.trackerNetworkTally[0])
assertEquals(second, viewState.trackerNetworkTally[1])
assertEquals(first, viewState.trackerNetworkEntries[0])
assertEquals(second, viewState.trackerNetworkEntries[1])
}

@Test
fun whenNoNetworkLeaderboardDataThenDefaultValuesAreUsed() {
testee.onTrackerNetworkTallyChanged(emptyList())
testee.onTrackerNetworkEntriesChanged(emptyList())
val viewState = testee.viewState.value!!
assertEquals(emptyList<NetworkTally>(), viewState.trackerNetworkTally)
assertEquals(emptyList<NetworkLeaderboardEntry>(), viewState.trackerNetworkEntries)
assertFalse(viewState.showTrackerNetworkLeaderboard)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ import com.duckduckgo.app.global.db.AppConfigurationEntity
import com.duckduckgo.app.global.model.Site
import com.duckduckgo.app.global.model.SiteFactory
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao
import com.duckduckgo.app.privacy.db.NetworkLeaderboardEntry
import com.duckduckgo.app.privacy.db.SiteVisitedEntity
import com.duckduckgo.app.privacy.model.PrivacyGrade
import com.duckduckgo.app.settings.db.SettingsDataStore
import com.duckduckgo.app.statistics.api.StatisticsUpdater
Expand Down Expand Up @@ -431,9 +429,8 @@ class BrowserTabViewModel(
}

private fun registerSiteVisit() {
val domainVisited = url?.toUri()?.host ?: return
Schedulers.io().scheduleDirect {
networkLeaderboardDao.insert(SiteVisitedEntity(domainVisited))
networkLeaderboardDao.incrementSitesVisited()
}
}

Expand Down Expand Up @@ -515,9 +512,8 @@ class BrowserTabViewModel(

private fun updateNetworkLeaderboard(event: TrackingEvent) {
val networkName = event.trackerNetwork?.name ?: return
val domainVisited = Uri.parse(event.documentUrl).host ?: return
networkLeaderboardDao.insert(NetworkLeaderboardEntry(networkName, domainVisited))
networkLeaderboardDao.insert(SiteVisitedEntity(domainVisited))
networkLeaderboardDao.incrementNetworkCount(networkName)
networkLeaderboardDao.incrementSitesVisited()
}

override fun pageHasHttpResources(page: String?) {
Expand Down
18 changes: 14 additions & 4 deletions app/src/main/java/com/duckduckgo/app/global/db/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import com.duckduckgo.app.notification.model.Notification
import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao
import com.duckduckgo.app.privacy.db.NetworkLeaderboardEntry
import com.duckduckgo.app.privacy.db.PrivacyProtectionCountDao
import com.duckduckgo.app.privacy.db.SiteVisitedEntity
import com.duckduckgo.app.privacy.db.SitesVisitedEntity
import com.duckduckgo.app.privacy.model.PrivacyProtectionCountsEntity
import com.duckduckgo.app.survey.db.SurveyDao
import com.duckduckgo.app.survey.model.Survey
Expand All @@ -55,12 +55,12 @@ import com.duckduckgo.app.usage.search.SearchCountDao
import com.duckduckgo.app.usage.search.SearchCountEntity

@Database(
exportSchema = true, version = 12, entities = [
exportSchema = true, version = 13, entities = [
DisconnectTracker::class,
HttpsBloomFilterSpec::class,
HttpsWhitelistedDomain::class,
NetworkLeaderboardEntry::class,
SiteVisitedEntity::class,
SitesVisitedEntity::class,
AppConfigurationEntity::class,
TabEntity::class,
TabSelectionEntity::class,
Expand Down Expand Up @@ -188,6 +188,15 @@ abstract class AppDatabase : RoomDatabase() {
}
}

val MIGRATION_12_TO_13: Migration = object : Migration(12, 13) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE `site_visited`")
database.execSQL("DROP TABLE `network_leaderboard`")
database.execSQL("CREATE TABLE IF NOT EXISTS `sites_visited` (`key` TEXT NOT NULL, `count` INTEGER NOT NULL, PRIMARY KEY(`key`))")
database.execSQL("CREATE TABLE IF NOT EXISTS `network_leaderboard` (`networkName` TEXT NOT NULL, `count` INTEGER NOT NULL, PRIMARY KEY(`networkName`))")
}
}

val ALL_MIGRATIONS: List<Migration>
get() = listOf(
MIGRATION_1_TO_2,
Expand All @@ -200,7 +209,8 @@ abstract class AppDatabase : RoomDatabase() {
MIGRATION_8_TO_9,
MIGRATION_9_TO_10,
MIGRATION_10_TO_11,
MIGRATION_11_TO_12
MIGRATION_11_TO_12,
MIGRATION_12_TO_13
)
}
}
Loading