mirror of
https://github.com/bitwarden/android.git
synced 2026-06-01 18:26:31 -05:00
BIT-732: Add account swither to login screen (#333)
This commit is contained in:
@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.auth.feature.login
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.compose.ui.test.assertCountEquals
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.filter
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
@@ -17,12 +18,14 @@ import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
|
||||
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@@ -51,6 +54,58 @@ class LoginScreenTest : BaseComposeTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `account menu icon is present according to the state`() {
|
||||
composeTestRule.onNodeWithContentDescription("Account").assertDoesNotExist()
|
||||
|
||||
mutableStateFlow.update {
|
||||
it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Account").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `account menu icon click should show the account switcher`() {
|
||||
mutableStateFlow.update {
|
||||
it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Account").performClick()
|
||||
|
||||
composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `account click in the account switcher should send SwitchAccountClick and close switcher`() {
|
||||
// Show the account switcher
|
||||
mutableStateFlow.update {
|
||||
it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
|
||||
}
|
||||
composeTestRule.onNodeWithContentDescription("Account").performClick()
|
||||
composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
|
||||
|
||||
composeTestRule.onNodeWithText("active@bitwarden.com").performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(LoginAction.SwitchAccountClick(ACTIVE_ACCOUNT_SUMMARY))
|
||||
}
|
||||
composeTestRule.onNodeWithText("active@bitwarden.com").assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add account button in the account switcher does not exist`() {
|
||||
// Show the account switcher
|
||||
mutableStateFlow.update {
|
||||
it.copy(accountSummaries = listOf(ACTIVE_ACCOUNT_SUMMARY))
|
||||
}
|
||||
composeTestRule.onNodeWithContentDescription("Account").performClick()
|
||||
composeTestRule.onNodeWithText("active@bitwarden.com").assertIsDisplayed()
|
||||
|
||||
composeTestRule.onNodeWithText("Add account").assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `close button click should send CloseButtonClick action`() {
|
||||
composeTestRule.onNodeWithContentDescription("Close").performClick()
|
||||
@@ -117,6 +172,14 @@ class LoginScreenTest : BaseComposeTest() {
|
||||
}
|
||||
}
|
||||
|
||||
private val ACTIVE_ACCOUNT_SUMMARY = AccountSummary(
|
||||
userId = "activeUserId",
|
||||
name = "Active User",
|
||||
email = "active@bitwarden.com",
|
||||
avatarColorHex = "#aa00aa",
|
||||
status = AccountSummary.Status.ACTIVE,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE =
|
||||
LoginState(
|
||||
emailAddress = "",
|
||||
@@ -126,4 +189,5 @@ private val DEFAULT_STATE =
|
||||
environmentLabel = "".asText(),
|
||||
loadingDialogState = LoadingDialogState.Hidden,
|
||||
errorDialogState = BasicDialogState.Hidden,
|
||||
accountSummaries = emptyList(),
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
|
||||
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
@@ -38,10 +39,10 @@ class LoginViewModelTest : BaseViewModelTest() {
|
||||
private val mutableCaptchaTokenResultFlow = MutableSharedFlow<CaptchaCallbackTokenResult>(
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
private val mutableStateFlow = MutableStateFlow<UserState?>(null)
|
||||
private val mutableUserStateFlow = MutableStateFlow<UserState?>(null)
|
||||
private val authRepository: AuthRepository = mockk(relaxed = true) {
|
||||
every { captchaTokenResultFlow } returns mutableCaptchaTokenResultFlow
|
||||
every { userStateFlow } returns mutableStateFlow
|
||||
every { userStateFlow } returns mutableUserStateFlow
|
||||
}
|
||||
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
|
||||
|
||||
@@ -100,6 +101,31 @@ class LoginViewModelTest : BaseViewModelTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state should set the account summaries based on the UserState`() {
|
||||
val userState = UserState(
|
||||
activeUserId = "activeUserId",
|
||||
accounts = listOf(
|
||||
UserState.Account(
|
||||
userId = "activeUserId",
|
||||
name = "name",
|
||||
email = "email",
|
||||
avatarColorHex = "avatarColorHex",
|
||||
isPremium = true,
|
||||
isVaultUnlocked = true,
|
||||
),
|
||||
),
|
||||
)
|
||||
mutableUserStateFlow.value = userState
|
||||
val viewModel = createViewModel()
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(
|
||||
accountSummaries = userState.toAccountSummaries(),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state should pull from handle when present`() = runTest {
|
||||
val expectedState = DEFAULT_STATE.copy(
|
||||
@@ -301,6 +327,7 @@ class LoginViewModelTest : BaseViewModelTest() {
|
||||
loadingDialogState = LoadingDialogState.Hidden,
|
||||
errorDialogState = BasicDialogState.Hidden,
|
||||
captchaToken = null,
|
||||
accountSummaries = emptyList(),
|
||||
)
|
||||
|
||||
private const val LOGIN_RESULT_PATH =
|
||||
|
||||
Reference in New Issue
Block a user