From 12af2fa32bab19c2aba3fa5228864785d2174ab8 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 19 Oct 2023 15:44:50 -0300 Subject: [PATCH] [db] reset the preferred repo when it gets disabled or deleted --- .../java/org/fdroid/database/AppDaoTest.kt | 6 ++ .../org/fdroid/database/AppPrefsDaoTest.kt | 57 +++++++++++++++++++ .../java/org/fdroid/database/RepositoryDao.kt | 16 +++++- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 libs/database/src/dbTest/java/org/fdroid/database/AppPrefsDaoTest.kt diff --git a/libs/database/src/dbTest/java/org/fdroid/database/AppDaoTest.kt b/libs/database/src/dbTest/java/org/fdroid/database/AppDaoTest.kt index 5c3d0aa24..77e09654b 100644 --- a/libs/database/src/dbTest/java/org/fdroid/database/AppDaoTest.kt +++ b/libs/database/src/dbTest/java/org/fdroid/database/AppDaoTest.kt @@ -2,6 +2,7 @@ package org.fdroid.database import androidx.core.os.LocaleListCompat import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.fdroid.database.TestUtils.getOrAwaitValue import org.fdroid.database.TestUtils.getOrFail import org.fdroid.database.TestUtils.toMetadataV2 import org.fdroid.test.TestRepoUtils.getRandomRepo @@ -10,6 +11,7 @@ import org.fdroid.test.TestVersionUtils.getRandomPackageVersionV2 import org.junit.Test import org.junit.runner.RunWith import kotlin.test.assertEquals +import kotlin.test.assertNull import kotlin.test.assertTrue import kotlin.test.fail @@ -82,6 +84,10 @@ internal class AppDaoTest : AppTest() { // prefer repo1 for this app appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1)) assertEquals(app1, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort()) + + // preferring non-existent repo for this app makes query return nothing (avoid this!) + appPrefsDao.update(AppPrefs(packageName, preferredRepoId = 1337L)) + assertNull(appDao.getApp(packageName).getOrAwaitValue()) } @Test diff --git a/libs/database/src/dbTest/java/org/fdroid/database/AppPrefsDaoTest.kt b/libs/database/src/dbTest/java/org/fdroid/database/AppPrefsDaoTest.kt new file mode 100644 index 000000000..2abae586b --- /dev/null +++ b/libs/database/src/dbTest/java/org/fdroid/database/AppPrefsDaoTest.kt @@ -0,0 +1,57 @@ +package org.fdroid.database + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.fdroid.database.TestUtils.getOrFail +import org.fdroid.database.TestUtils.toMetadataV2 +import org.fdroid.test.TestRepoUtils.getRandomRepo +import org.fdroid.test.TestUtils.sort +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.test.assertEquals + +@RunWith(AndroidJUnit4::class) +internal class AppPrefsDaoTest : AppTest() { + + @Test + fun testDisablingPreferredRepo() { + // insert same app into three repos (repoId3 has highest weight) + val repoId1 = repoDao.insertOrReplace(getRandomRepo()) + val repoId2 = repoDao.insertOrReplace(getRandomRepo()) + val repoId3 = repoDao.insertOrReplace(getRandomRepo()) + appDao.insert(repoId1, packageName, app1, locales) + appDao.insert(repoId2, packageName, app2, locales) + appDao.insert(repoId2, packageName, app3, locales) + + // app from preferred repo gets returned + appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1)) + assertEquals(app1, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort()) + + // preferred repo gets disabled + repoDao.setRepositoryEnabled(repoId1, false) + + // now app from repo with highest weight is returned + assertEquals(app3, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort()) + } + + @Test + fun testRemovingPreferredRepo() { + // insert same app into three repos (repoId3 has highest weight) + val repoId1 = repoDao.insertOrReplace(getRandomRepo()) + val repoId2 = repoDao.insertOrReplace(getRandomRepo()) + val repoId3 = repoDao.insertOrReplace(getRandomRepo()) + appDao.insert(repoId1, packageName, app1, locales) + appDao.insert(repoId2, packageName, app2, locales) + appDao.insert(repoId2, packageName, app3, locales) + + // app from preferred repo gets returned + appPrefsDao.update(AppPrefs(packageName, preferredRepoId = repoId1)) + assertEquals(app1, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort()) + + // preferred repo gets removed + repoDao.deleteRepository(repoId1) + + // now app from repo with highest weight is returned + assertEquals(app3, appDao.getApp(packageName).getOrFail()?.toMetadataV2()?.sort()) + } + +} diff --git a/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt b/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt index 022b50510..281d68122 100644 --- a/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt +++ b/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt @@ -329,8 +329,19 @@ internal interface RepositoryDaoInt : RepositoryDao { ) } + @Transaction + override fun setRepositoryEnabled(repoId: Long, enabled: Boolean) { + // When disabling a repository, we need to remove it as preferred repo for all apps, + // otherwise our queries that ignore disabled repos will not return anything anymore. + if (!enabled) resetPreferredRepoInAppPrefs(repoId) + setRepositoryEnabledInternal(repoId, enabled) + } + @Query("UPDATE ${RepositoryPreferences.TABLE} SET enabled = :enabled WHERE repoId = :repoId") - override fun setRepositoryEnabled(repoId: Long, enabled: Boolean) + fun setRepositoryEnabledInternal(repoId: Long, enabled: Boolean) + + @Query("UPDATE ${AppPrefs.TABLE} SET preferredRepoId = NULL WHERE preferredRepoId = :repoId") + fun resetPreferredRepoInAppPrefs(repoId: Long) @Query("""UPDATE ${RepositoryPreferences.TABLE} SET userMirrors = :mirrors WHERE repoId = :repoId""") @@ -350,6 +361,9 @@ internal interface RepositoryDaoInt : RepositoryDao { // we don't use cascading delete for preferences, // so we can replace index data on full updates deleteRepositoryPreferences(repoId) + // When deleting a repository, we need to remove it as preferred repo for all apps, + // otherwise our queries will not return anything anymore. + resetPreferredRepoInAppPrefs(repoId) } @Query("DELETE FROM ${CoreRepository.TABLE} WHERE repoId = :repoId")