From 543e7d96cca3f0f7fcabbef5409cbf7a284817b0 Mon Sep 17 00:00:00 2001 From: Jonathan Klee Date: Thu, 8 Jan 2026 10:32:13 +0100 Subject: [PATCH] refactor: improve Stores abstraction --- .../java/foundation/e/apps/data/Stores.kt | 87 ++++++++++++------- .../foundation/e/apps/data/StoreConfigTest.kt | 76 ++++++++++++++++ .../java/foundation/e/apps/data/StoresTest.kt | 5 ++ 3 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 app/src/test/java/foundation/e/apps/data/StoreConfigTest.kt diff --git a/app/src/main/java/foundation/e/apps/data/Stores.kt b/app/src/main/java/foundation/e/apps/data/Stores.kt index 2437dbc87..a819fb925 100644 --- a/app/src/main/java/foundation/e/apps/data/Stores.kt +++ b/app/src/main/java/foundation/e/apps/data/Stores.kt @@ -32,12 +32,19 @@ import javax.inject.Singleton @Singleton class Stores @Inject constructor( - private val playStoreRepository: PlayStoreRepository, - private val cleanApkAppsRepository: CleanApkAppsRepository, - private val cleanApkPwaRepository: CleanApkPwaRepository, - private val appLoungePreference: AppLoungePreference + playStoreRepository: PlayStoreRepository, + cleanApkAppsRepository: CleanApkAppsRepository, + cleanApkPwaRepository: CleanApkPwaRepository, + appLoungePreference: AppLoungePreference ) { + private val storeConfigs: Map = buildStoreConfigs( + playStoreRepository, + cleanApkAppsRepository, + cleanApkPwaRepository, + appLoungePreference + ) + /** * Retrieves a map of enabled store repositories based on user preferences. * @@ -45,38 +52,54 @@ class Stores @Inject constructor( * the values are their corresponding [StoreRepository] instances. */ fun getStores(): Map { - val showOpenSourceApps = appLoungePreference.isOpenSourceSelected() - val showPwaApps = appLoungePreference.isPWASelected() - val showPlayStoreApps = appLoungePreference.isPlayStoreSelected() - - return buildMap { - if (showPlayStoreApps) { - put(PLAY_STORE, playStoreRepository) - } - if (showOpenSourceApps) { - put(OPEN_SOURCE, cleanApkAppsRepository) - } - if (showPwaApps) { - put(PWA, cleanApkPwaRepository) - } - } + return storeConfigs + .filterValues { it.isEnabled() } + .mapValues { it.value.repository } } fun getStore(source: Source): StoreRepository? = getStores()[source] - fun enableStore(source: Source) = when (source) { - OPEN_SOURCE -> appLoungePreference.enableOpenSource() - PWA -> appLoungePreference.enablePwa() - PLAY_STORE -> appLoungePreference.enablePlayStore() - else -> error("No matching Store found for $source.") - } + fun enableStore(source: Source) = + storeConfigs[source]?.enable?.invoke() + ?: error("No matching Store found for $source.") - fun disableStore(source: Source) = when (source) { - OPEN_SOURCE -> appLoungePreference.disableOpenSource() - PWA -> appLoungePreference.disablePwa() - PLAY_STORE -> appLoungePreference.disablePlayStore() - else -> error("No matching Store found for $source.") - } + fun disableStore(source: Source) = + storeConfigs[source]?.disable?.invoke() + ?: error("No matching Store found for $source.") - fun isStoreEnabled(source: Source): Boolean = getStores().containsKey(source) + fun isStoreEnabled(source: Source): Boolean = + storeConfigs[source]?.isEnabled?.invoke() == true } + +internal data class StoreConfig( + val repository: StoreRepository, + val isEnabled: () -> Boolean, + val enable: () -> Unit, + val disable: () -> Unit, +) + +internal fun buildStoreConfigs( + playStoreRepository: PlayStoreRepository, + cleanApkAppsRepository: CleanApkAppsRepository, + cleanApkPwaRepository: CleanApkPwaRepository, + appLoungePreference: AppLoungePreference +): Map = mapOf( + PLAY_STORE to StoreConfig( + repository = playStoreRepository, + isEnabled = { appLoungePreference.isPlayStoreSelected() }, + enable = { appLoungePreference.enablePlayStore() }, + disable = { appLoungePreference.disablePlayStore() }, + ), + OPEN_SOURCE to StoreConfig( + repository = cleanApkAppsRepository, + isEnabled = { appLoungePreference.isOpenSourceSelected() }, + enable = { appLoungePreference.enableOpenSource() }, + disable = { appLoungePreference.disableOpenSource() }, + ), + PWA to StoreConfig( + repository = cleanApkPwaRepository, + isEnabled = { appLoungePreference.isPWASelected() }, + enable = { appLoungePreference.enablePwa() }, + disable = { appLoungePreference.disablePwa() }, + ), +) diff --git a/app/src/test/java/foundation/e/apps/data/StoreConfigTest.kt b/app/src/test/java/foundation/e/apps/data/StoreConfigTest.kt new file mode 100644 index 000000000..b029726c1 --- /dev/null +++ b/app/src/test/java/foundation/e/apps/data/StoreConfigTest.kt @@ -0,0 +1,76 @@ +package foundation.e.apps.data + +import com.google.common.truth.Truth.assertThat +import foundation.e.apps.data.cleanapk.repositories.CleanApkAppsRepository +import foundation.e.apps.data.cleanapk.repositories.CleanApkPwaRepository +import foundation.e.apps.data.enums.Source +import foundation.e.apps.data.playstore.PlayStoreRepository +import foundation.e.apps.data.preference.AppLoungePreference +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Before +import org.junit.Test + +class StoreConfigTest { + + private val playStoreRepository: PlayStoreRepository = mockk(relaxed = true) + private val cleanApkAppsRepository: CleanApkAppsRepository = mockk(relaxed = true) + private val cleanApkPwaRepository: CleanApkPwaRepository = mockk(relaxed = true) + private val preference: AppLoungePreference = mockk(relaxed = true) + + @Before + fun setup() { + every { preference.isPlayStoreSelected() } returns true + every { preference.isOpenSourceSelected() } returns false + every { preference.isPWASelected() } returns true + } + + @Test + fun buildStoreConfigsFiltersByPreference() { + val configs = buildStoreConfigs( + playStoreRepository, + cleanApkAppsRepository, + cleanApkPwaRepository, + preference + ) + + assertThat(configs.keys).containsExactly(Source.PLAY_STORE, Source.PWA, Source.OPEN_SOURCE) + + val enabled = configs[Source.PLAY_STORE]!!.isEnabled.invoke() + val disabled = configs[Source.OPEN_SOURCE]!!.isEnabled.invoke() + + assertThat(enabled).isTrue() + assertThat(disabled).isFalse() + } + + @Test + fun storeConfigDelegatesEnableDisable() { + val configs = buildStoreConfigs( + playStoreRepository, + cleanApkAppsRepository, + cleanApkPwaRepository, + preference + ) + + configs[Source.PWA]!!.enable.invoke() + configs[Source.PWA]!!.disable.invoke() + + verify { preference.enablePwa() } + verify { preference.disablePwa() } + } + + @Test + fun storeConfigHoldsRepositoryReference() { + val configs = buildStoreConfigs( + playStoreRepository, + cleanApkAppsRepository, + cleanApkPwaRepository, + preference + ) + + assertThat(configs[Source.PLAY_STORE]!!.repository).isSameInstanceAs(playStoreRepository) + assertThat(configs[Source.OPEN_SOURCE]!!.repository).isSameInstanceAs(cleanApkAppsRepository) + assertThat(configs[Source.PWA]!!.repository).isSameInstanceAs(cleanApkPwaRepository) + } +} diff --git a/app/src/test/java/foundation/e/apps/data/StoresTest.kt b/app/src/test/java/foundation/e/apps/data/StoresTest.kt index 0a0902a4a..19ff1de84 100644 --- a/app/src/test/java/foundation/e/apps/data/StoresTest.kt +++ b/app/src/test/java/foundation/e/apps/data/StoresTest.kt @@ -61,4 +61,9 @@ class StoresTest { assertThat(enabled).isTrue() assertThat(disabled).isFalse() } + + @Test(expected = IllegalStateException::class) + fun enableStoreThrowsForUnknownSource() { + stores.enableStore(Source.SYSTEM_APP) + } } -- GitLab