Remove unused FeatureFlagRepository and FeatureFlagDiskSource (#4998)

This commit is contained in:
Patrick Honkonen
2025-04-07 13:07:13 +00:00
committed by GitHub
parent 538f1feb2e
commit 62cfcbbd72
10 changed files with 0 additions and 344 deletions
@@ -1,20 +0,0 @@
package com.bitwarden.authenticator.data.platform.datasource.disk
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import kotlinx.coroutines.flow.Flow
/**
* Primary access point for feature flag configuration.
*/
interface FeatureFlagDiskSource {
/**
* The currently persisted [FeatureFlagsConfiguration].
*/
var featureFlagsConfiguration: FeatureFlagsConfiguration?
/**
* Emits updates to track [FeatureFlagsConfiguration]. This will replay the last known value.
*/
val featureFlagsConfigurationFlow: Flow<FeatureFlagsConfiguration?>
}
@@ -1,41 +0,0 @@
package com.bitwarden.authenticator.data.platform.datasource.disk
import android.content.SharedPreferences
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import com.bitwarden.core.data.util.decodeFromStringOrNull
import com.bitwarden.data.datasource.disk.BaseDiskSource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onSubscription
import kotlinx.serialization.json.Json
private const val KEY_FEATURE_FLAGS = "featureFlags"
/**
* Primary implementation of [FeatureFlagDiskSource].
*/
class FeatureFlagDiskSourceImpl(
sharedPreferences: SharedPreferences,
private val json: Json,
) : BaseDiskSource(sharedPreferences = sharedPreferences),
FeatureFlagDiskSource {
private val mutableFeatureFlagsConfigurationFlow =
bufferedMutableSharedFlow<FeatureFlagsConfiguration?>(replay = 1)
override val featureFlagsConfigurationFlow: Flow<FeatureFlagsConfiguration?>
get() = mutableFeatureFlagsConfigurationFlow.onSubscription {
emit(featureFlagsConfiguration)
}
override var featureFlagsConfiguration: FeatureFlagsConfiguration?
get() = getString(key = KEY_FEATURE_FLAGS)
?.let { json.decodeFromStringOrNull(it) }
set(value) {
putString(
key = KEY_FEATURE_FLAGS,
value = value.let { json.encodeToString(it) },
)
mutableFeatureFlagsConfigurationFlow.tryEmit(value)
}
}
@@ -1,8 +1,6 @@
package com.bitwarden.authenticator.data.platform.datasource.disk.di
import android.content.SharedPreferences
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagDiskSourceImpl
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagOverrideDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagOverrideDiskSourceImpl
import com.bitwarden.authenticator.data.platform.datasource.disk.SettingsDiskSource
@@ -42,17 +40,6 @@ object PlatformDiskModule {
): SettingsDiskSource =
SettingsDiskSourceImpl(sharedPreferences = sharedPreferences)
@Provides
@Singleton
fun provideFeatureFlagDiskSource(
@UnencryptedPreferences sharedPreferences: SharedPreferences,
json: Json,
): FeatureFlagDiskSource =
FeatureFlagDiskSourceImpl(
sharedPreferences = sharedPreferences,
json = json,
)
@Provides
@Singleton
fun provideFeatureFlagOverrideDiskSource(
@@ -1,20 +0,0 @@
package com.bitwarden.authenticator.data.platform.repository
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import kotlinx.coroutines.flow.StateFlow
/**
* Provides an API for observing the server config state.
*/
interface FeatureFlagRepository {
/**
* Emits updates that track [FeatureFlagsConfiguration].
*/
val featureFlagConfigStateFlow: StateFlow<FeatureFlagsConfiguration?>
/**
* Gets the state [FeatureFlagsConfiguration].
*/
suspend fun getFeatureFlagsConfiguration(): FeatureFlagsConfiguration
}
@@ -1,47 +0,0 @@
package com.bitwarden.authenticator.data.platform.repository
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.authenticator.data.platform.manager.DispatcherManager
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.serialization.json.JsonPrimitive
/**
* Primary implementation of [FeatureFlagRepositoryImpl].
*/
class FeatureFlagRepositoryImpl(
private val featureFlagDiskSource: FeatureFlagDiskSource,
dispatcherManager: DispatcherManager,
) : FeatureFlagRepository {
private val unconfinedScope = CoroutineScope(dispatcherManager.unconfined)
override val featureFlagConfigStateFlow: StateFlow<FeatureFlagsConfiguration?>
get() = featureFlagDiskSource
.featureFlagsConfigurationFlow
.stateIn(
scope = unconfinedScope,
started = SharingStarted.Eagerly,
initialValue = featureFlagDiskSource.featureFlagsConfiguration,
)
override suspend fun getFeatureFlagsConfiguration() =
featureFlagDiskSource.featureFlagsConfiguration
?: initLocalFeatureFlagsConfiguration()
private fun initLocalFeatureFlagsConfiguration(): FeatureFlagsConfiguration {
val config = FeatureFlagsConfiguration(
mapOf(
FlagKey.BitwardenAuthenticationEnabled.keyName to JsonPrimitive(
FlagKey.BitwardenAuthenticationEnabled.defaultValue,
),
),
)
featureFlagDiskSource.featureFlagsConfiguration = config
return config
}
}
@@ -2,15 +2,12 @@ package com.bitwarden.authenticator.data.platform.repository.di
import com.bitwarden.authenticator.data.auth.datasource.disk.AuthDiskSource
import com.bitwarden.authenticator.data.authenticator.datasource.sdk.AuthenticatorSdkSource
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagOverrideDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.SettingsDiskSource
import com.bitwarden.authenticator.data.platform.manager.BiometricsEncryptionManager
import com.bitwarden.authenticator.data.platform.manager.DispatcherManager
import com.bitwarden.authenticator.data.platform.repository.DebugMenuRepository
import com.bitwarden.authenticator.data.platform.repository.DebugMenuRepositoryImpl
import com.bitwarden.authenticator.data.platform.repository.FeatureFlagRepository
import com.bitwarden.authenticator.data.platform.repository.FeatureFlagRepositoryImpl
import com.bitwarden.authenticator.data.platform.repository.ServerConfigRepository
import com.bitwarden.authenticator.data.platform.repository.ServerConfigRepositoryImpl
import com.bitwarden.authenticator.data.platform.repository.SettingsRepository
@@ -63,17 +60,6 @@ object PlatformRepositoryModule {
dispatcherManager = dispatcherManager,
)
@Provides
@Singleton
fun provideFeatureFlagRepo(
featureFlagDiskSource: FeatureFlagDiskSource,
dispatcherManager: DispatcherManager,
): FeatureFlagRepository =
FeatureFlagRepositoryImpl(
featureFlagDiskSource = featureFlagDiskSource,
dispatcherManager = dispatcherManager,
)
@Provides
@Singleton
fun provideDebugMenuRepository(
@@ -1,71 +0,0 @@
package com.bitwarden.authenticator.data.platform.datasource.disk
import androidx.core.content.edit
import app.cash.turbine.test
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
import com.bitwarden.core.di.CoreModule
import com.bitwarden.data.datasource.disk.base.FakeSharedPreferences
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.JsonPrimitive
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
class FeatureFlagDiskSourceTest {
private val json = CoreModule.providesJson()
private val fakeSharedPreferences = FakeSharedPreferences()
private val featureFlagDiskSource = FeatureFlagDiskSourceImpl(
sharedPreferences = fakeSharedPreferences,
json = json,
)
@Test
fun `featureFlagsConfiguration should pull from and update SharedPreferences`() {
val featureFlagsConfigKey = "bwPreferencesStorage:featureFlags"
assertNull(featureFlagDiskSource.featureFlagsConfiguration)
assertNull(fakeSharedPreferences.getString(featureFlagsConfigKey, null))
featureFlagDiskSource.featureFlagsConfiguration = FEATURE_FLAGS_CONFIGURATION
assertEquals(
json.parseToJsonElement(
FEATURE_FLAGS_CONFIGURATION_JSON,
),
json.parseToJsonElement(
fakeSharedPreferences.getString(featureFlagsConfigKey, null)!!,
),
)
fakeSharedPreferences.edit { putString(featureFlagsConfigKey, null) }
assertNull(featureFlagDiskSource.featureFlagsConfiguration)
}
@Test
fun `featureFlagsConfigFlow should react to changes in featureFlagsConfig`() = runTest {
featureFlagDiskSource.featureFlagsConfigurationFlow.test {
assertNull(featureFlagDiskSource.featureFlagsConfiguration)
assertNull(awaitItem())
featureFlagDiskSource.featureFlagsConfiguration = FEATURE_FLAGS_CONFIGURATION
assertEquals(FEATURE_FLAGS_CONFIGURATION, awaitItem())
}
}
}
private const val FEATURE_FLAGS_CONFIGURATION_JSON = """
{
"featureFlags" : {
"bitwarden-authentication-enabled" : true
}
}
"""
private val FEATURE_FLAGS_CONFIGURATION = FeatureFlagsConfiguration(
featureFlags = mapOf(
FlagKey.BitwardenAuthenticationEnabled.keyName to JsonPrimitive(true),
),
)
@@ -1,27 +0,0 @@
package com.bitwarden.authenticator.data.platform.datasource.disk.util
import com.bitwarden.authenticator.data.platform.datasource.disk.FeatureFlagDiskSource
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onSubscription
/**
* A faked implementation of [FeatureFlagDiskSource] for testing.
*/
class FakeFeatureFlagDiskSource : FeatureFlagDiskSource {
private var configuration: FeatureFlagsConfiguration? = null
private val mutableConfigurationFlow =
bufferedMutableSharedFlow<FeatureFlagsConfiguration?>(replay = 1)
override var featureFlagsConfiguration: FeatureFlagsConfiguration?
get() = configuration
set(value) {
configuration = value
mutableConfigurationFlow.tryEmit(value)
}
override val featureFlagsConfigurationFlow: Flow<FeatureFlagsConfiguration?>
get() = mutableConfigurationFlow
.onSubscription { emit(configuration) }
}
@@ -1,53 +0,0 @@
package com.bitwarden.authenticator.data.platform.repository
import app.cash.turbine.test
import com.bitwarden.authenticator.data.platform.base.FakeDispatcherManager
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.authenticator.data.platform.datasource.disk.util.FakeFeatureFlagDiskSource
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.JsonPrimitive
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
class FeatureFlagRepositoryTest {
private val fakeFeatureFlagDiskSource = FakeFeatureFlagDiskSource()
private val featureFlagRepo = FeatureFlagRepositoryImpl(
featureFlagDiskSource = fakeFeatureFlagDiskSource,
dispatcherManager = FakeDispatcherManager(),
)
@Suppress("MaxLineLength")
@Test
fun `getFeatureFlagsConfiguration should init configuration with local flags when there is none in state`() =
runTest {
assertNull(fakeFeatureFlagDiskSource.featureFlagsConfiguration)
featureFlagRepo.getFeatureFlagsConfiguration()
assertEquals(
FEATURE_FLAGS_CONFIG,
fakeFeatureFlagDiskSource.featureFlagsConfiguration,
)
}
@Test
fun `featureFlagsConfigurationFlow should react to feature flag configuration changes`() =
runTest {
featureFlagRepo.getFeatureFlagsConfiguration()
featureFlagRepo.featureFlagConfigStateFlow.test {
assertEquals(fakeFeatureFlagDiskSource.featureFlagsConfiguration, awaitItem())
}
}
}
private val FEATURE_FLAGS_CONFIG =
FeatureFlagsConfiguration(
featureFlags = mapOf(
FlagKey.BitwardenAuthenticationEnabled.keyName to
JsonPrimitive(FlagKey.BitwardenAuthenticationEnabled.defaultValue),
),
)
@@ -1,38 +0,0 @@
package com.bitwarden.authenticator.data.platform.repository.util
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
import com.bitwarden.authenticator.data.platform.repository.FeatureFlagRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.serialization.json.JsonPrimitive
/**
* Faked implementation of [FeatureFlagRepository] for testing.
*/
class FakeFeatureFlagRepository : FeatureFlagRepository {
var featureFlagsConfiguration: FeatureFlagsConfiguration?
get() = mutableFeatureFlagsConfiguration.value
set(value) {
mutableFeatureFlagsConfiguration.value = value
}
private val mutableFeatureFlagsConfiguration =
MutableStateFlow<FeatureFlagsConfiguration?>(FEATURE_FLAGS_CONFIG)
override val featureFlagConfigStateFlow: StateFlow<FeatureFlagsConfiguration?> =
mutableFeatureFlagsConfiguration
override suspend fun getFeatureFlagsConfiguration(): FeatureFlagsConfiguration {
return featureFlagsConfiguration
?: FEATURE_FLAGS_CONFIG
}
}
private val FEATURE_FLAGS_CONFIG =
FeatureFlagsConfiguration(
featureFlags = mapOf(
FlagKey.BitwardenAuthenticationEnabled.keyName to
JsonPrimitive(FlagKey.BitwardenAuthenticationEnabled.defaultValue),
),
)