Hook up vault timeout action to repo (#530)

This commit is contained in:
Brian Yencho
2024-01-08 09:56:03 -06:00
committed by GitHub
parent de9e32f6aa
commit 9be101ecde
6 changed files with 191 additions and 100 deletions

View File

@@ -16,6 +16,7 @@ import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.core.net.toUri
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
@@ -340,34 +341,99 @@ class AccountSecurityScreenTest : BaseComposeTest() {
}
@Test
fun `on session timeout action click should send SessionTimeoutActionClick`() {
fun `on session timeout action click should show a selection dialog`() {
composeTestRule.assertNoDialogExists()
composeTestRule
.onNodeWithText("Session timeout action")
.performScrollTo()
.performClick()
verify { viewModel.trySendAction(AccountSecurityAction.SessionTimeoutActionClick) }
composeTestRule
.onAllNodesWithText("Vault timeout action")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
composeTestRule
.onAllNodesWithText("Lock")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
composeTestRule
.onAllNodesWithText("Log out")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
composeTestRule
.onAllNodesWithText("Cancel")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
}
@Suppress("MaxLineLength")
@Test
fun `on session timeout action dialog option click should close the dialog and send VaultTimeoutActionSelect`() {
composeTestRule.assertNoDialogExists()
composeTestRule
.onNodeWithText("Session timeout action")
.performScrollTo()
.performClick()
composeTestRule
.onAllNodesWithText("Vault timeout action")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
composeTestRule
.onAllNodesWithText("Log out")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
.performClick()
verify {
viewModel.trySendAction(
AccountSecurityAction.VaultTimeoutActionSelect(
VaultTimeoutAction.LOGOUT,
),
)
}
composeTestRule.assertNoDialogExists()
}
@Suppress("MaxLineLength")
@Test
fun `on session timeout action dialog cancel click should close the dialog`() {
composeTestRule.assertNoDialogExists()
composeTestRule
.onNodeWithText("Session timeout action")
.performScrollTo()
.performClick()
composeTestRule
.onAllNodesWithText("Vault timeout action")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
composeTestRule
.onAllNodesWithText("Cancel")
.filterToOne(hasAnyAncestor(isDialog()))
.assertIsDisplayed()
.performClick()
verify(exactly = 0) { viewModel.trySendAction(any()) }
composeTestRule.assertNoDialogExists()
}
@Test
fun `session timeout action should be updated on or off according to state`() {
fun `session timeout action should be updated according to state`() {
composeTestRule
.onNodeWithText("Session timeout action")
.performScrollTo()
.assertTextEquals("Session timeout action", "Lock")
mutableStateFlow.update { it.copy(sessionTimeoutAction = SessionTimeoutAction.LOG_OUT) }
mutableStateFlow.update { it.copy(vaultTimeoutAction = VaultTimeoutAction.LOGOUT) }
composeTestRule
.onNodeWithText("Session timeout action")
.performScrollTo()
.assertTextEquals("Session timeout action", "Log out")
}
@Test
fun `session timeout action dialog should be displayed to state`() {
composeTestRule.onNodeWithText("Vault timeout action").assertDoesNotExist()
mutableStateFlow.update { it.copy(dialog = AccountSecurityDialog.SessionTimeoutAction) }
composeTestRule.onNodeWithText("Vault timeout action").assertIsDisplayed()
}
@Suppress("MaxLineLength")
@Test
fun `on two-step login click should display confirmation dialog and confirm click should send TwoStepLoginClick`() {
@@ -528,7 +594,7 @@ class AccountSecurityScreenTest : BaseComposeTest() {
isUnlockWithBiometricsEnabled = false,
isUnlockWithPinEnabled = false,
vaultTimeoutType = VaultTimeout.Type.THIRTY_MINUTES,
sessionTimeoutAction = SessionTimeoutAction.LOCK,
vaultTimeoutAction = VaultTimeoutAction.LOCK,
)
}
}

View File

@@ -5,6 +5,7 @@ import app.cash.turbine.test
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeout
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
@@ -146,11 +147,14 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
}
@Test
fun `on SessionTimeoutActionSelect should update session timeout action`() = runTest {
val viewModel = createViewModel()
fun `on VaultTimeoutActionSelect should update vault timeout action`() = runTest {
val settingsRepository = mockk<SettingsRepository>() {
every { vaultTimeoutAction = any() } just runs
}
val viewModel = createViewModel(settingsRepository = settingsRepository)
viewModel.eventFlow.test {
viewModel.trySendAction(
AccountSecurityAction.SessionTimeoutActionSelect(SessionTimeoutAction.LOG_OUT),
AccountSecurityAction.VaultTimeoutActionSelect(VaultTimeoutAction.LOGOUT),
)
assertEquals(
AccountSecurityEvent.ShowToast("Not yet implemented.".asText()),
@@ -158,22 +162,14 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
)
}
assertEquals(
DEFAULT_STATE.copy(dialog = null, sessionTimeoutAction = SessionTimeoutAction.LOG_OUT),
DEFAULT_STATE.copy(
vaultTimeoutAction = VaultTimeoutAction.LOGOUT,
),
viewModel.stateFlow.value,
)
verify { settingsRepository.vaultTimeoutAction = VaultTimeoutAction.LOGOUT }
}
@Test
fun `on SessionTimeoutActionClick should update shouldShowSessionTimeoutActionDialog`() =
runTest {
val viewModel = createViewModel()
viewModel.trySendAction(AccountSecurityAction.SessionTimeoutActionClick)
assertEquals(
DEFAULT_STATE.copy(dialog = AccountSecurityDialog.SessionTimeoutAction),
viewModel.stateFlow.value,
)
}
@Test
fun `on TwoStepLoginClick should emit NavigateToTwoStepLogin`() = runTest {
val viewModel = createViewModel()
@@ -268,7 +264,7 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
isUnlockWithBiometricsEnabled = false,
isUnlockWithPinEnabled = false,
vaultTimeoutType = VaultTimeout.Type.THIRTY_MINUTES,
sessionTimeoutAction = SessionTimeoutAction.LOCK,
vaultTimeoutAction = VaultTimeoutAction.LOCK,
)
}
}

View File

@@ -0,0 +1,23 @@
package com.x8bit.bitwarden.ui.platform.util
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.platform.repository.model.VaultTimeoutAction
import com.x8bit.bitwarden.ui.platform.base.util.asText
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class VaultTimeoutActionExtensionsTest {
@Test
fun `displayLabel should return the correct value for each type`() {
mapOf(
VaultTimeoutAction.LOCK to R.string.lock.asText(),
VaultTimeoutAction.LOGOUT to R.string.log_out.asText(),
)
.forEach { (type, label) ->
assertEquals(
label,
type.displayLabel,
)
}
}
}