Add SettingsRepository helpers for the current user (#525)

This commit is contained in:
Brian Yencho 2024-01-07 16:46:12 -06:00 committed by Álison Fernandes
parent 87568287af
commit 1e8d603b61
3 changed files with 122 additions and 4 deletions

View file

@ -8,6 +8,16 @@ import kotlinx.coroutines.flow.StateFlow
* Provides an API for observing and modifying settings state.
*/
interface SettingsRepository {
/**
* The [VaultTimeout] for the current user.
*/
var vaultTimeout: VaultTimeout
/**
* The [VaultTimeoutAction] for the current user.
*/
var vaultTimeoutAction: VaultTimeoutAction
/**
* Gets updates for the [VaultTimeout] associated with the given [userId].
*/

View file

@ -1,5 +1,6 @@
package com.x8bit.bitwarden.data.platform.repository
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
@ -14,11 +15,42 @@ import kotlinx.coroutines.flow.stateIn
* Primary implementation of [SettingsRepository].
*/
class SettingsRepositoryImpl(
private val authDiskSource: AuthDiskSource,
private val settingsDiskSource: SettingsDiskSource,
private val dispatcherManager: DispatcherManager,
) : SettingsRepository {
private val activeUserId: String? get() = authDiskSource.userState?.activeUserId
private val unconfinedScope = CoroutineScope(dispatcherManager.unconfined)
override var vaultTimeout: VaultTimeout
get() = activeUserId
?.let {
getVaultTimeoutStateFlow(userId = it).value
}
?: VaultTimeout.Never
set(value) {
val userId = activeUserId ?: return
storeVaultTimeout(
userId = userId,
vaultTimeout = value,
)
}
override var vaultTimeoutAction: VaultTimeoutAction
get() = activeUserId
?.let {
getVaultTimeoutActionStateFlow(userId = it).value
}
.orDefault()
set(value) {
val userId = activeUserId ?: return
storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = value,
)
}
override fun getVaultTimeoutStateFlow(userId: String): StateFlow<VaultTimeout> =
settingsDiskSource
.getVaultTimeoutInMinutesFlow(userId = userId)

View file

@ -1,10 +1,13 @@
package com.x8bit.bitwarden.data.platform.repository
import app.cash.turbine.test
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
import com.x8bit.bitwarden.data.platform.datasource.disk.util.FakeSettingsDiskSource
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
@ -12,13 +15,81 @@ import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
class SettingsRepositoryTest {
private val authDiskSource: AuthDiskSource = mockk()
private val fakeSettingsDiskSource = FakeSettingsDiskSource()
private val settingsRepository = SettingsRepositoryImpl(
authDiskSource = authDiskSource,
settingsDiskSource = fakeSettingsDiskSource,
dispatcherManager = FakeDispatcherManager(),
)
@Test
fun `vaultTimeout should pull from and update SettingsDiskSource for the current user`() {
every { authDiskSource.userState?.activeUserId } returns null
assertEquals(
VaultTimeout.Never,
settingsRepository.vaultTimeout,
)
val userId = "userId"
every { authDiskSource.userState?.activeUserId } returns userId
// Updates to the disk source change the repository value
VAULT_TIMEOUT_MAP.forEach { (vaultTimeout, vaultTimeoutInMinutes) ->
fakeSettingsDiskSource.storeVaultTimeoutInMinutes(
userId = userId,
vaultTimeoutInMinutes = vaultTimeoutInMinutes,
)
assertEquals(
vaultTimeout,
settingsRepository.vaultTimeout,
)
}
// Updates to the repository value change the disk source
VAULT_TIMEOUT_MAP.forEach { (vaultTimeout, vaultTimeoutInMinutes) ->
settingsRepository.vaultTimeout = vaultTimeout
assertEquals(
vaultTimeoutInMinutes,
fakeSettingsDiskSource.getVaultTimeoutInMinutes(userId = userId),
)
}
}
@Test
fun `vaultTimeoutAction should pull from and update SettingsDiskSource`() {
every { authDiskSource.userState?.activeUserId } returns null
assertEquals(
VaultTimeoutAction.LOCK,
settingsRepository.vaultTimeoutAction,
)
val userId = "userId"
every { authDiskSource.userState?.activeUserId } returns userId
// Updates to the disk source change the repository value
VAULT_TIMEOUT_ACTIONS.forEach { vaultTimeoutAction ->
fakeSettingsDiskSource.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
)
assertEquals(
vaultTimeoutAction,
settingsRepository.vaultTimeoutAction,
)
}
// Updates to the repository value change the disk source
VAULT_TIMEOUT_ACTIONS.forEach { vaultTimeoutAction ->
settingsRepository.vaultTimeoutAction = vaultTimeoutAction
assertEquals(
vaultTimeoutAction,
fakeSettingsDiskSource.getVaultTimeoutAction(userId = userId),
)
}
}
@Test
fun `getVaultTimeoutStateFlow should react to changes in SettingsDiskSource`() = runTest {
val userId = "userId"
@ -67,9 +138,7 @@ class SettingsRepositoryTest {
VaultTimeoutAction.LOCK,
awaitItem(),
)
// Reverse the order of the entries to ensure the first value differs from the
// default.
VaultTimeoutAction.entries.reversed().forEach { vaultTimeoutAction ->
VAULT_TIMEOUT_ACTIONS.forEach { vaultTimeoutAction ->
fakeSettingsDiskSource.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
@ -105,7 +174,7 @@ class SettingsRepositoryTest {
@Test
fun `storeVaultTimeoutAction should properly update SettingsDiskSource`() {
val userId = "userId"
VaultTimeoutAction.entries.forEach { vaultTimeoutAction ->
VAULT_TIMEOUT_ACTIONS.forEach { vaultTimeoutAction ->
settingsRepository.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
@ -118,6 +187,13 @@ class SettingsRepositoryTest {
}
}
/**
* A list of all [VaultTimeoutAction].
*
* The order is reversed here in order to ensure that the first value differs from the default.
*/
private val VAULT_TIMEOUT_ACTIONS = VaultTimeoutAction.entries.reversed()
/**
* Maps a VaultTimeout to its expected vaultTimeoutInMinutes value.
*/