mirror of
https://github.com/bitwarden/android.git
synced 2026-06-01 18:26:31 -05:00
BIT-471 Show confirm log out dialog (#173)
This commit is contained in:
@@ -1,14 +1,22 @@
|
||||
package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity
|
||||
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity.AccountSecurityAction.ConfirmLogoutClick
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity.AccountSecurityAction.DismissDialog
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.update
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
@@ -17,6 +25,7 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
||||
@Test
|
||||
fun `on Log out click should send LogoutClick`() {
|
||||
val viewModel: AccountSecurityViewModel = mockk {
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(AccountSecurityAction.LogoutClick) } returns Unit
|
||||
}
|
||||
@@ -33,6 +42,7 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
||||
@Test
|
||||
fun `on back click should send BackClick`() {
|
||||
val viewModel: AccountSecurityViewModel = mockk {
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(AccountSecurityAction.BackClick) } returns Unit
|
||||
}
|
||||
@@ -50,6 +60,7 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
||||
fun `on NavigateAccountSecurity should call onNavigateToAccountSecurity`() {
|
||||
var haveCalledNavigateBack = false
|
||||
val viewModel = mockk<AccountSecurityViewModel> {
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
|
||||
every { eventFlow } returns flowOf(AccountSecurityEvent.NavigateBack)
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
@@ -60,4 +71,86 @@ class AccountSecurityScreenTest : BaseComposeTest() {
|
||||
}
|
||||
assertTrue(haveCalledNavigateBack)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `confirm dialog be shown or hidden according to the state`() {
|
||||
val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
|
||||
val viewModel = mockk<AccountSecurityViewModel> {
|
||||
every { stateFlow } returns mutableStateFlow
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(ConfirmLogoutClick) } returns Unit
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
AccountSecurityScreen(
|
||||
viewModel = viewModel,
|
||||
onNavigateBack = { },
|
||||
)
|
||||
}
|
||||
composeTestRule.onNode(isDialog()).assertDoesNotExist()
|
||||
|
||||
mutableStateFlow.update { it.copy(shouldShowConfirmLogoutDialog = true) }
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Yes")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule
|
||||
.onNodeWithText("Cancel")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule
|
||||
.onNodeWithText("Are you sure you want to log out?")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on confirm logout click should send ConfirmLogoutClick`() {
|
||||
val viewModel = mockk<AccountSecurityViewModel> {
|
||||
every { stateFlow } returns MutableStateFlow(
|
||||
DEFAULT_STATE.copy(shouldShowConfirmLogoutDialog = true),
|
||||
)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(ConfirmLogoutClick) } returns Unit
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
AccountSecurityScreen(
|
||||
viewModel = viewModel,
|
||||
onNavigateBack = { },
|
||||
)
|
||||
}
|
||||
composeTestRule
|
||||
.onNodeWithText("Yes")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
verify { viewModel.trySendAction(ConfirmLogoutClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on cancel click should send DismissDialog`() {
|
||||
val viewModel = mockk<AccountSecurityViewModel> {
|
||||
every { stateFlow } returns MutableStateFlow(
|
||||
DEFAULT_STATE.copy(shouldShowConfirmLogoutDialog = true),
|
||||
)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(DismissDialog) } returns Unit
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
AccountSecurityScreen(
|
||||
viewModel = viewModel,
|
||||
onNavigateBack = { },
|
||||
)
|
||||
}
|
||||
composeTestRule
|
||||
.onNodeWithText("Cancel")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
verify { viewModel.trySendAction(DismissDialog) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STATE = AccountSecurityState(
|
||||
shouldShowConfirmLogoutDialog = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
@@ -12,9 +13,19 @@ import org.junit.jupiter.api.Test
|
||||
|
||||
class AccountSecurityViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `initial state should be correct`() {
|
||||
val viewModel = AccountSecurityViewModel(
|
||||
savedStateHandle = SavedStateHandle(),
|
||||
authRepository = mockk(),
|
||||
)
|
||||
assertEquals(DEFAULT_STATE, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on BackClick should emit NavigateBack`() = runTest {
|
||||
val viewModel = AccountSecurityViewModel(
|
||||
savedStateHandle = SavedStateHandle(),
|
||||
authRepository = mockk(),
|
||||
)
|
||||
viewModel.eventFlow.test {
|
||||
@@ -24,14 +35,63 @@ class AccountSecurityViewModelTest : BaseViewModelTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on LogoutClick should call logout`() = runTest {
|
||||
fun `on LogoutClick should show confirm log out dialog`() = runTest {
|
||||
val viewModel = AccountSecurityViewModel(
|
||||
savedStateHandle = SavedStateHandle(),
|
||||
authRepository = mockk(),
|
||||
)
|
||||
viewModel.trySendAction(AccountSecurityAction.LogoutClick)
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(
|
||||
shouldShowConfirmLogoutDialog = true,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on ConfirmLogoutClick should call logout and hide confirm dialog`() = runTest {
|
||||
val authRepository: AuthRepository = mockk {
|
||||
every { logout() } returns Unit
|
||||
}
|
||||
val viewModel = AccountSecurityViewModel(
|
||||
savedStateHandle = SavedStateHandle(),
|
||||
authRepository = authRepository,
|
||||
)
|
||||
viewModel.trySendAction(AccountSecurityAction.LogoutClick)
|
||||
viewModel.trySendAction(AccountSecurityAction.ConfirmLogoutClick)
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(
|
||||
shouldShowConfirmLogoutDialog = false,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
verify { authRepository.logout() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `on DismissDialog should hide dialog`() = runTest {
|
||||
val viewModel = AccountSecurityViewModel(
|
||||
savedStateHandle = SavedStateHandle(),
|
||||
authRepository = mockk(),
|
||||
)
|
||||
viewModel.trySendAction(AccountSecurityAction.DismissDialog)
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(
|
||||
shouldShowConfirmLogoutDialog = false,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STATE = AccountSecurityState(
|
||||
shouldShowConfirmLogoutDialog = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user