diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSource.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSource.kt deleted file mode 100644 index 93b9e6273c..0000000000 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSource.kt +++ /dev/null @@ -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 -} diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceImpl.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceImpl.kt deleted file mode 100644 index 01891f5994..0000000000 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceImpl.kt +++ /dev/null @@ -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(replay = 1) - - override val featureFlagsConfigurationFlow: Flow - 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) - } -} diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/di/PlatformDiskModule.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/di/PlatformDiskModule.kt index 0b89e43d5f..eb6de53b21 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/di/PlatformDiskModule.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/datasource/disk/di/PlatformDiskModule.kt @@ -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( diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepository.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepository.kt deleted file mode 100644 index e840a7164d..0000000000 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepository.kt +++ /dev/null @@ -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 - - /** - * Gets the state [FeatureFlagsConfiguration]. - */ - suspend fun getFeatureFlagsConfiguration(): FeatureFlagsConfiguration -} diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryImpl.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryImpl.kt deleted file mode 100644 index 221b5ff54c..0000000000 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryImpl.kt +++ /dev/null @@ -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 - 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 - } -} diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/di/PlatformRepositoryModule.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/di/PlatformRepositoryModule.kt index 44d580ce7e..55c0f74249 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/di/PlatformRepositoryModule.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/platform/repository/di/PlatformRepositoryModule.kt @@ -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( diff --git a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceTest.kt b/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceTest.kt deleted file mode 100644 index 8d4c58a218..0000000000 --- a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/FeatureFlagDiskSourceTest.kt +++ /dev/null @@ -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), - ), -) diff --git a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/util/FakeFeatureFlagDiskSource.kt b/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/util/FakeFeatureFlagDiskSource.kt deleted file mode 100644 index f2240a36e5..0000000000 --- a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/datasource/disk/util/FakeFeatureFlagDiskSource.kt +++ /dev/null @@ -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(replay = 1) - - override var featureFlagsConfiguration: FeatureFlagsConfiguration? - get() = configuration - set(value) { - configuration = value - mutableConfigurationFlow.tryEmit(value) - } - override val featureFlagsConfigurationFlow: Flow - get() = mutableConfigurationFlow - .onSubscription { emit(configuration) } -} diff --git a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryTest.kt b/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryTest.kt deleted file mode 100644 index a77b0e2d58..0000000000 --- a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/FeatureFlagRepositoryTest.kt +++ /dev/null @@ -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), - ), - ) diff --git a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/util/FakeFeatureFlagRepository.kt b/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/util/FakeFeatureFlagRepository.kt deleted file mode 100644 index 936f52556f..0000000000 --- a/authenticator/src/test/java/com/bitwarden/authenticator/data/platform/repository/util/FakeFeatureFlagRepository.kt +++ /dev/null @@ -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(FEATURE_FLAGS_CONFIG) - - override val featureFlagConfigStateFlow: StateFlow = - 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), - ), - )