mirror of
https://github.com/f-droid/fdroidclient.git
synced 2026-04-20 06:47:06 -04:00
[db] allow setting a preferred repo per app
This commit is contained in:
@@ -62,6 +62,28 @@ internal class AppDaoTest : AppTest() {
|
||||
assertEquals(0, appDao.countLocalizedFileLists())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAppRepoPref() {
|
||||
// insert same app into three repos (repoId1 has highest weight)
|
||||
val repoId2 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId3 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId1 = repoDao.insertOrReplace(getRandomRepo())
|
||||
appDao.insert(repoId1, packageName, app1, locales)
|
||||
appDao.insert(repoId2, packageName, app2, locales)
|
||||
appDao.insert(repoId3, packageName, app3, locales)
|
||||
|
||||
// app from repo with highest weight is returned, if no prefs are set
|
||||
assertEquals(app1, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort())
|
||||
|
||||
// prefer repo3 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId3))
|
||||
assertEquals(app3, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort())
|
||||
|
||||
// prefer repo1 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1))
|
||||
assertEquals(app1, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSameAppFromTwoReposOneDisabled() {
|
||||
// insert same app into two repos (repoId2 has highest weight)
|
||||
@@ -149,6 +171,13 @@ internal class AppDaoTest : AppTest() {
|
||||
assertEquals(3, appDao.getNumberOfAppsInCategory("A"))
|
||||
assertEquals(2, appDao.getNumberOfAppsInCategory("B"))
|
||||
assertEquals(0, appDao.getNumberOfAppsInCategory("C"))
|
||||
|
||||
// app1 as a variant of app2 in another repo will show one more app in B
|
||||
val repoId2 = repoDao.insertOrReplace(getRandomRepo())
|
||||
appDao.insert(repoId2, packageName2, app1, locales)
|
||||
assertEquals(3, appDao.getNumberOfAppsInCategory("A"))
|
||||
assertEquals(3, appDao.getNumberOfAppsInCategory("B"))
|
||||
assertEquals(0, appDao.getNumberOfAppsInCategory("C"))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -451,6 +451,48 @@ internal class AppListItemsTest : AppTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFromRepoFromAppPrefs() {
|
||||
// insert same app into three repos (repoId1 has highest weight)
|
||||
val repoId2 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId3 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId1 = repoDao.insertOrReplace(getRandomRepo())
|
||||
appDao.insert(repoId2, packageName, app2, locales)
|
||||
appDao.insert(repoId1, packageName, app1, locales)
|
||||
appDao.insert(repoId3, packageName, app3, locales)
|
||||
|
||||
// app from repo1 with highest weight gets returned
|
||||
getItems { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(packageName, apps[0].packageName)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
|
||||
// prefer repo3 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId3))
|
||||
getItems { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(packageName, apps[0].packageName)
|
||||
assertEquals(app3, apps[0])
|
||||
}
|
||||
|
||||
// prefer repo2 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId2))
|
||||
getItems { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(packageName, apps[0].packageName)
|
||||
assertEquals(app2, apps[0])
|
||||
}
|
||||
|
||||
// prefer repo1 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1))
|
||||
getItems { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(packageName, apps[0].packageName)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnlyFromGivenCategories() {
|
||||
// insert three apps
|
||||
@@ -476,6 +518,16 @@ internal class AppListItemsTest : AppTest() {
|
||||
).forEach { apps ->
|
||||
assertEquals(0, apps.size)
|
||||
}
|
||||
|
||||
// we'll add app1 as a variant of app2, so it should be in category B as well
|
||||
val repoId2 = repoDao.insertOrReplace(getRandomRepo())
|
||||
appDao.insert(repoId2, packageName2, app1, locales)
|
||||
listOf(
|
||||
appDao.getAppListItemsByName("B").getOrFail(),
|
||||
appDao.getAppListItemsByLastUpdated("B").getOrFail(),
|
||||
).forEach { apps ->
|
||||
assertEquals(3, apps.size) // all apps are in B now
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -159,6 +159,63 @@ internal class AppOverviewItemsTest : AppTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetByRepoPref() {
|
||||
// insert same app into three repos (repoId1 has highest weight)
|
||||
val repoId2 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId3 = repoDao.insertOrReplace(getRandomRepo())
|
||||
val repoId1 = repoDao.insertOrReplace(getRandomRepo())
|
||||
appDao.insert(repoId1, packageName, app1, locales)
|
||||
appDao.insert(repoId2, packageName, app2, locales)
|
||||
appDao.insert(repoId3, packageName, app3, locales)
|
||||
|
||||
// app is returned correctly from repo1
|
||||
appDao.getAppOverviewItems().getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
appDao.getAppOverviewItems("A").getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
|
||||
// prefer repo3 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId3))
|
||||
appDao.getAppOverviewItems().getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app3, apps[0])
|
||||
}
|
||||
appDao.getAppOverviewItems("B").getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app3, apps[0])
|
||||
}
|
||||
|
||||
// prefer repo2 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId2))
|
||||
appDao.getAppOverviewItems().getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app2, apps[0])
|
||||
}
|
||||
appDao.getAppOverviewItems("A").getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app2, apps[0])
|
||||
}
|
||||
appDao.getAppOverviewItems("B").getOrFail().let { apps ->
|
||||
assertEquals(0, apps.size) // app2 is not in category B
|
||||
}
|
||||
|
||||
// prefer repo1 for this app
|
||||
appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1))
|
||||
appDao.getAppOverviewItems().getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
appDao.getAppOverviewItems("A").getOrFail().let { apps ->
|
||||
assertEquals(1, apps.size)
|
||||
assertEquals(app1, apps[0])
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSortOrder() {
|
||||
// insert two apps with one version each
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.mockk.every
|
||||
import io.mockk.mockkObject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import org.fdroid.database.TestUtils.assertRepoEquals
|
||||
import org.fdroid.database.TestUtils.getOrFail
|
||||
import org.fdroid.database.TestUtils.toMetadataV2
|
||||
import org.fdroid.database.TestUtils.toPackageVersionV2
|
||||
import org.fdroid.index.v1.IndexV1StreamProcessor
|
||||
@@ -111,7 +112,7 @@ internal abstract class DbTest {
|
||||
packageV2.metadata,
|
||||
appDao.getApp(repoId, packageName)?.toMetadataV2()?.sort()
|
||||
)
|
||||
val versions = versionDao.getAppVersions(repoId, packageName).map {
|
||||
val versions = versionDao.getAppVersions(repoId, packageName).getOrFail().map {
|
||||
it.toPackageVersionV2()
|
||||
}.associateBy { it.file.sha256 }
|
||||
assertEquals(packageV2.versions.size, versions.size, "number of versions")
|
||||
|
||||
@@ -255,7 +255,7 @@ internal class RepositoryDaoTest : DbTest() {
|
||||
// data is there as expected
|
||||
assertEquals(1, repoDao.getRepositories().size)
|
||||
assertEquals(1, appDao.getAppMetadata().size)
|
||||
assertEquals(1, versionDao.getAppVersions(repoId, packageName).size)
|
||||
assertEquals(1, versionDao.getAppVersions(repoId, packageName).getOrFail().size)
|
||||
assertTrue(versionDao.getVersionedStrings(repoId, packageName).isNotEmpty())
|
||||
|
||||
// clearing the repo removes apps and versions
|
||||
@@ -264,7 +264,7 @@ internal class RepositoryDaoTest : DbTest() {
|
||||
assertEquals(0, appDao.countApps())
|
||||
assertEquals(0, appDao.countLocalizedFiles())
|
||||
assertEquals(0, appDao.countLocalizedFileLists())
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).size)
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).getOrFail().size)
|
||||
assertEquals(0, versionDao.getVersionedStrings(repoId, packageName).size)
|
||||
// preferences are not touched by clearing
|
||||
assertEquals(repositoryPreferences, repoDao.getRepositoryPreferences(repoId))
|
||||
|
||||
@@ -35,6 +35,22 @@ internal class VersionTest : DbTest() {
|
||||
versionId2 to packageVersion2,
|
||||
)
|
||||
|
||||
private fun getAppVersion1(repoId: Long): AppVersion {
|
||||
val version = getVersion1(repoId)
|
||||
return AppVersion(
|
||||
version = version,
|
||||
versionedStrings = packageVersion1.manifest.getVersionedStrings(version),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getAppVersion2(repoId: Long): AppVersion {
|
||||
val version = getVersion2(repoId)
|
||||
return AppVersion(
|
||||
version = version,
|
||||
versionedStrings = packageVersion2.manifest.getVersionedStrings(version),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getVersion1(repoId: Long) =
|
||||
packageVersion1.toVersion(repoId, packageName, versionId1, isCompatible1)
|
||||
|
||||
@@ -55,25 +71,22 @@ internal class VersionTest : DbTest() {
|
||||
appDao.insert(repoId, packageName, getRandomMetadataV2())
|
||||
versionDao.insert(repoId, packageName, versionId1, packageVersion1, isCompatible1)
|
||||
|
||||
val appVersions = versionDao.getAppVersions(repoId, packageName)
|
||||
val appVersions = versionDao.getAppVersions(repoId, packageName).getOrFail()
|
||||
assertEquals(1, appVersions.size)
|
||||
val appVersion = appVersions[0]
|
||||
assertEquals(versionId1, appVersion.version.versionId)
|
||||
assertEquals(getVersion1(repoId), appVersion.version)
|
||||
val manifest = packageVersion1.manifest
|
||||
assertEquals(manifest.usesPermission.toSet(), appVersion.usesPermission.toSet())
|
||||
assertEquals(manifest.usesPermissionSdk23.toSet(), appVersion.usesPermissionSdk23.toSet())
|
||||
assertEquals(
|
||||
manifest.features.map { it.name }.toSet(),
|
||||
appVersion.version.manifest.features?.toSet()
|
||||
)
|
||||
assertEquals(getAppVersion1(repoId), appVersions[0])
|
||||
|
||||
val manifest = packageVersion1.manifest
|
||||
val versionedStrings = versionDao.getVersionedStrings(repoId, packageName)
|
||||
val expectedSize = manifest.usesPermission.size + manifest.usesPermissionSdk23.size
|
||||
assertEquals(expectedSize, versionedStrings.size)
|
||||
|
||||
// getting version by repo produces same result
|
||||
val versionsByRepo = versionDao.getAppVersions(repoId, packageName).getOrFail()
|
||||
assertEquals(1, versionsByRepo.size)
|
||||
assertEquals(getAppVersion1(repoId), versionsByRepo[0])
|
||||
|
||||
versionDao.deleteAppVersion(repoId, packageName, versionId1)
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).size)
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).getOrFail().size)
|
||||
assertEquals(0, versionDao.getVersionedStrings(repoId, packageName).size)
|
||||
}
|
||||
|
||||
@@ -86,39 +99,29 @@ internal class VersionTest : DbTest() {
|
||||
versionDao.insert(repoId, packageName, versionId2, packageVersion2, isCompatible2)
|
||||
|
||||
// get app versions from DB and assign them correctly
|
||||
val appVersions = versionDao.getAppVersions(packageName).getOrFail()
|
||||
assertEquals(2, appVersions.size)
|
||||
val appVersion = if (versionId1 == appVersions[0].version.versionId) {
|
||||
appVersions[0]
|
||||
} else appVersions[1]
|
||||
val appVersion2 = if (versionId2 == appVersions[0].version.versionId) {
|
||||
appVersions[0]
|
||||
} else appVersions[1]
|
||||
listOf(
|
||||
versionDao.getAppVersions(packageName).getOrFail(),
|
||||
versionDao.getAppVersions(repoId, packageName).getOrFail(),
|
||||
).forEach { appVersions ->
|
||||
assertEquals(2, appVersions.size)
|
||||
val appVersion = if (versionId1 == appVersions[0].version.versionId) {
|
||||
appVersions[0]
|
||||
} else appVersions[1]
|
||||
val appVersion2 = if (versionId2 == appVersions[0].version.versionId) {
|
||||
appVersions[0]
|
||||
} else appVersions[1]
|
||||
|
||||
// check first version matches
|
||||
assertEquals(getVersion1(repoId), appVersion.version)
|
||||
val manifest = packageVersion1.manifest
|
||||
assertEquals(manifest.usesPermission.toSet(), appVersion.usesPermission.toSet())
|
||||
assertEquals(manifest.usesPermissionSdk23.toSet(), appVersion.usesPermissionSdk23.toSet())
|
||||
assertEquals(
|
||||
manifest.features.map { it.name }.toSet(),
|
||||
appVersion.version.manifest.features?.toSet()
|
||||
)
|
||||
// check first version matches
|
||||
assertEquals(getAppVersion1(repoId), appVersion)
|
||||
|
||||
// check second version matches
|
||||
assertEquals(getVersion2(repoId), appVersion2.version)
|
||||
val manifest2 = packageVersion2.manifest
|
||||
assertEquals(manifest2.usesPermission.toSet(), appVersion2.usesPermission.toSet())
|
||||
assertEquals(manifest2.usesPermissionSdk23.toSet(),
|
||||
appVersion2.usesPermissionSdk23.toSet())
|
||||
assertEquals(
|
||||
manifest.features.map { it.name }.toSet(),
|
||||
appVersion.version.manifest.features?.toSet()
|
||||
)
|
||||
// check second version matches
|
||||
assertEquals(getAppVersion2(repoId), appVersion2)
|
||||
}
|
||||
|
||||
// delete app and check that all associated data also gets deleted
|
||||
appDao.deleteAppMetadata(repoId, packageName)
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).size)
|
||||
assertEquals(0, versionDao.getAppVersions(packageName).getOrFail().size)
|
||||
assertEquals(0, versionDao.getAppVersions(repoId, packageName).getOrFail().size)
|
||||
assertEquals(0, versionDao.getVersionedStrings(repoId, packageName).size)
|
||||
}
|
||||
|
||||
@@ -138,6 +141,10 @@ internal class VersionTest : DbTest() {
|
||||
assertEquals(3, versionDao.getAppVersions(packageName).getOrFail().size)
|
||||
assertEquals(3, versionDao.getVersions(listOf(packageName)).size)
|
||||
|
||||
// query by repo only returns the versions from each repo
|
||||
assertEquals(2, versionDao.getAppVersions(repoId, packageName).getOrFail().size)
|
||||
assertEquals(1, versionDao.getAppVersions(repoId2, packageName).getOrFail().size)
|
||||
|
||||
// disable second repo
|
||||
repoDao.setRepositoryEnabled(repoId2, false)
|
||||
|
||||
@@ -155,8 +162,10 @@ internal class VersionTest : DbTest() {
|
||||
versionDao.insert(repoId, packageName, versionId3, packageVersion3, true)
|
||||
val versions1 = versionDao.getAppVersions(packageName).getOrFail()
|
||||
val versions2 = versionDao.getVersions(listOf(packageName))
|
||||
val versions3 = versionDao.getAppVersions(repoId, packageName).getOrFail()
|
||||
assertEquals(3, versions1.size)
|
||||
assertEquals(3, versions2.size)
|
||||
assertEquals(3, versions3.size)
|
||||
|
||||
// check that they are sorted as expected
|
||||
listOf(
|
||||
@@ -166,6 +175,7 @@ internal class VersionTest : DbTest() {
|
||||
).sortedDescending().forEachIndexed { i, versionCode ->
|
||||
assertEquals(versionCode, versions1[i].version.manifest.versionCode)
|
||||
assertEquals(versionCode, versions2[i].versionCode)
|
||||
assertEquals(versionCode, versions3[i].version.manifest.versionCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user