Add VaultTimeoutAction handling to SettingsRepository (#521)

This commit is contained in:
Brian Yencho 2024-01-07 13:31:04 -06:00 committed by Álison Fernandes
parent e2c35fc373
commit 6470959085
3 changed files with 118 additions and 0 deletions

View file

@ -1,6 +1,7 @@
package com.x8bit.bitwarden.data.platform.repository
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import kotlinx.coroutines.flow.StateFlow
/**
@ -16,4 +17,23 @@ interface SettingsRepository {
* Stores the given [vaultTimeout] for the given [userId].
*/
fun storeVaultTimeout(userId: String, vaultTimeout: VaultTimeout)
/**
* Gets updates for the [VaultTimeoutAction] associated with the given [userId].
*
* Note that in cases where no value has been set, a default will be returned. Use
* [isVaultTimeoutActionSet] to see if there is an actual value set.
*/
fun getVaultTimeoutActionStateFlow(userId: String): StateFlow<VaultTimeoutAction>
/**
* Returns `true` if a [VaultTimeoutAction] is set for the given [userId], and `false`
* otherwise.
*/
fun isVaultTimeoutActionSet(userId: String): Boolean
/**
* Stores the given [VaultTimeoutAction] for the given [userId].
*/
fun storeVaultTimeoutAction(userId: String, vaultTimeoutAction: VaultTimeoutAction?)
}

View file

@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.platform.repository
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
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@ -36,6 +37,34 @@ class SettingsRepositoryImpl(
vaultTimeoutInMinutes = vaultTimeout.vaultTimeoutInMinutes,
)
}
override fun getVaultTimeoutActionStateFlow(
userId: String,
): StateFlow<VaultTimeoutAction> =
settingsDiskSource
.getVaultTimeoutActionFlow(userId = userId)
.map { it.orDefault() }
.stateIn(
scope = unconfinedScope,
started = SharingStarted.Eagerly,
initialValue = settingsDiskSource
.getVaultTimeoutAction(userId = userId)
.orDefault(),
)
override fun isVaultTimeoutActionSet(
userId: String,
): Boolean = settingsDiskSource.getVaultTimeoutAction(userId = userId) != null
override fun storeVaultTimeoutAction(
userId: String,
vaultTimeoutAction: VaultTimeoutAction?,
) {
settingsDiskSource.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
)
}
}
/**
@ -53,3 +82,9 @@ private fun Int?.toVaultTimeout(): VaultTimeout =
null -> VaultTimeout.Never
else -> VaultTimeout.Custom(vaultTimeoutInMinutes = this)
}
/**
* Returns the given [VaultTimeoutAction] or a default value if `null`.
*/
private fun VaultTimeoutAction?.orDefault(): VaultTimeoutAction =
this ?: VaultTimeoutAction.LOCK

View file

@ -4,8 +4,11 @@ import app.cash.turbine.test
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 kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
class SettingsRepositoryTest {
@ -53,6 +56,66 @@ class SettingsRepositoryTest {
)
}
}
@Test
fun `getVaultTimeoutActionStateFlow should react to changes in SettingsDiskSource`() = runTest {
val userId = "userId"
settingsRepository
.getVaultTimeoutActionStateFlow(userId = userId)
.test {
assertEquals(
VaultTimeoutAction.LOCK,
awaitItem(),
)
// Reverse the order of the entries to ensure the first value differs from the
// default.
VaultTimeoutAction.entries.reversed().forEach { vaultTimeoutAction ->
fakeSettingsDiskSource.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
)
assertEquals(
vaultTimeoutAction,
awaitItem(),
)
}
}
}
@Test
fun `isVaultTimeoutActionSet when no value is persisted should return false`() {
val userId = "userId"
assertFalse(
settingsRepository.isVaultTimeoutActionSet(userId = userId),
)
}
@Test
fun `isVaultTimeoutActionSet when a value is persisted should return true`() {
val userId = "userId"
fakeSettingsDiskSource.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = VaultTimeoutAction.LOGOUT,
)
assertTrue(
settingsRepository.isVaultTimeoutActionSet(userId = userId),
)
}
@Test
fun `storeVaultTimeoutAction should properly update SettingsDiskSource`() {
val userId = "userId"
VaultTimeoutAction.entries.forEach { vaultTimeoutAction ->
settingsRepository.storeVaultTimeoutAction(
userId = userId,
vaultTimeoutAction = vaultTimeoutAction,
)
assertEquals(
vaultTimeoutAction,
fakeSettingsDiskSource.getVaultTimeoutAction(userId = userId),
)
}
}
}
/**