BIT-896 Allow user to log out (#129)

This commit is contained in:
Andrew Haisting
2023-10-18 13:55:46 -05:00
committed by GitHub
parent 36451a7bda
commit 89e980ac59
21 changed files with 581 additions and 41 deletions

View File

@@ -202,6 +202,31 @@ class AuthRepositoryTest {
}
}
@Test
fun `logout should change AuthState to be Unauthenticated`() = runTest {
// First login:
coEvery {
accountsService.preLogin(email = EMAIL)
} returns Result.success(PRE_LOGIN_SUCCESS)
coEvery {
identityService.getToken(
email = EMAIL,
passwordHash = PASSWORD_HASH,
captchaToken = null,
)
}
.returns(Result.success(GetTokenResponseJson.Success(accessToken = ACCESS_TOKEN)))
every { authInterceptor.authToken = ACCESS_TOKEN } returns Unit
repository.login(email = EMAIL, password = PASSWORD, captchaToken = null)
// Then call logout:
repository.authStateFlow.test {
assertEquals(AuthState.Authenticated(ACCESS_TOKEN), awaitItem())
repository.logout()
assertEquals(AuthState.Unauthenticated, awaitItem())
}
}
companion object {
private const val EMAIL = "test@test.com"
private const val PASSWORD = "password"

View File

@@ -19,10 +19,10 @@ class RootNavScreenTest : BaseComposeTest() {
// When changing root navigation state, pop everything else off the back stack:
popUpTo(fakeNavHostController.graphId) {
inclusive = false
saveState = true
saveState = false
}
launchSingleTop = true
restoreState = true
restoreState = false
}
@Test

View File

@@ -0,0 +1,62 @@
package com.x8bit.bitwarden.ui.platform.feature.settings
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 io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import org.junit.Test
class AccountSecurityScreenTest : BaseComposeTest() {
@Test
fun `on Log out click should send LogoutClick`() {
val viewModel: AccountSecurityViewModel = mockk {
every { eventFlow } returns emptyFlow()
every { trySendAction(AccountSecurityAction.LogoutClick) } returns Unit
}
composeTestRule.setContent {
AccountSecurityScreen(
viewModel = viewModel,
onNavigateBack = { },
)
}
composeTestRule.onNodeWithText("Log out").performClick()
verify { viewModel.trySendAction(AccountSecurityAction.LogoutClick) }
}
@Test
fun `on back click should send BackClick`() {
val viewModel: AccountSecurityViewModel = mockk {
every { eventFlow } returns emptyFlow()
every { trySendAction(AccountSecurityAction.BackClick) } returns Unit
}
composeTestRule.setContent {
AccountSecurityScreen(
viewModel = viewModel,
onNavigateBack = { },
)
}
composeTestRule.onNodeWithContentDescription("Back").performClick()
verify { viewModel.trySendAction(AccountSecurityAction.BackClick) }
}
@Test
fun `on NavigateAccountSecurity should call onNavigateToAccountSecurity`() {
var haveCalledNavigateBack = false
val viewModel = mockk<AccountSecurityViewModel> {
every { eventFlow } returns flowOf(AccountSecurityEvent.NavigateBack)
}
composeTestRule.setContent {
AccountSecurityScreen(
viewModel = viewModel,
onNavigateBack = { haveCalledNavigateBack = true },
)
}
assert(haveCalledNavigateBack)
}
}

View File

@@ -0,0 +1,37 @@
package com.x8bit.bitwarden.ui.platform.feature.settings
import app.cash.turbine.test
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class AccountSecurityViewModelTest : BaseViewModelTest() {
@Test
fun `on BackClick should emit NavigateBack`() = runTest {
val viewModel = AccountSecurityViewModel(
authRepository = mockk(),
)
viewModel.eventFlow.test {
viewModel.trySendAction(AccountSecurityAction.BackClick)
assertEquals(AccountSecurityEvent.NavigateBack, awaitItem())
}
}
@Test
fun `on LogoutClick should call logout`() = runTest {
val authRepository: AuthRepository = mockk {
every { logout() } returns Unit
}
val viewModel = AccountSecurityViewModel(
authRepository = authRepository,
)
viewModel.trySendAction(AccountSecurityAction.LogoutClick)
verify { authRepository.logout() }
}
}

View File

@@ -0,0 +1,47 @@
package com.x8bit.bitwarden.ui.platform.feature.settings
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import org.junit.Test
class SettingsScreenTest : BaseComposeTest() {
@Test
fun `on account row click should emit AccountSecurityClick`() {
val viewModel = mockk<SettingsViewModel> {
every { eventFlow } returns emptyFlow()
every { trySendAction(SettingsAction.AccountSecurityClick) } returns Unit
}
composeTestRule.setContent {
SettingsScreen(
viewModel = viewModel,
onNavigateToAccountSecurity = { },
)
}
composeTestRule.onNodeWithText("Account").performClick()
verify { viewModel.trySendAction(SettingsAction.AccountSecurityClick) }
}
@Test
fun `on NavigateAccountSecurity should call onNavigateToAccountSecurity`() {
var haveCalledNavigateToAccountSecurity = false
val viewModel = mockk<SettingsViewModel> {
every { eventFlow } returns flowOf(SettingsEvent.NavigateAccountSecurity)
}
composeTestRule.setContent {
SettingsScreen(
viewModel = viewModel,
onNavigateToAccountSecurity = {
haveCalledNavigateToAccountSecurity = true
},
)
}
assert(haveCalledNavigateToAccountSecurity)
}
}

View File

@@ -0,0 +1,19 @@
package com.x8bit.bitwarden.ui.platform.feature.settings
import app.cash.turbine.test
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class SettingsViewModelTest : BaseViewModelTest() {
@Test
fun `on AccountSecurityClick should emit NavigateAccountSecurity`() = runTest {
val viewModel = SettingsViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(SettingsAction.AccountSecurityClick)
assertEquals(SettingsEvent.NavigateAccountSecurity, awaitItem())
}
}
}

View File

@@ -32,6 +32,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
onNodeWithText("My vault").performClick()
@@ -52,6 +53,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
@@ -73,6 +75,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
onNodeWithText("Send").performClick()
@@ -93,6 +96,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
@@ -114,6 +118,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
onNodeWithText("Generator").performClick()
@@ -134,6 +139,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
@@ -155,6 +161,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
onNodeWithText("Settings").performClick()
@@ -175,6 +182,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
VaultUnlockedNavBarScreen(
viewModel = viewModel,
navController = fakeNavHostController,
onNavigateToAccountSecurity = {},
)
}
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }