PM-9937 an existing email should be able to add account from a different hosted instance. (#3613)
Some checks failed
Crowdin Push / Crowdin Push (push) Waiting to run
Scan / Check PR run (push) Failing after 0s
Scan / SAST scan (push) Has been skipped
Scan / Quality scan (push) Has been skipped
Test / Check PR run (push) Failing after 0s
Test / Test (push) Has been skipped

This commit is contained in:
Dave Severns 2024-07-23 15:45:56 -04:00 committed by GitHub
parent d2432f7cf7
commit b44a320dc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 74 additions and 5 deletions

View file

@ -42,21 +42,26 @@ class LandingViewModel @Inject constructor(
isContinueButtonEnabled = authRepository.rememberedEmailAddress != null,
isRememberMeEnabled = authRepository.rememberedEmailAddress != null,
selectedEnvironmentType = environmentRepository.environment.type,
selectedEnvironmentLabel = environmentRepository.environment.label,
dialog = null,
accountSummaries = authRepository.userStateFlow.value?.toAccountSummaries().orEmpty(),
),
) {
/**
* Returns the [AccountSummary] from the current state that matches the current email input,
* of `null` if there is no match.
* Returns the [AccountSummary] from the current state that matches the current email input and
* the the current environment, or `null` if there is no match.
*/
private val matchingAccountSummary: AccountSummary?
get() {
val currentEmail = state.emailInput
val currentEnvironmentLabel = state.selectedEnvironmentLabel
val accountSummaries = state.accountSummaries
return accountSummaries
.find { it.email == currentEmail }
.find {
it.email == currentEmail &&
it.environmentLabel == currentEnvironmentLabel
}
?.takeUnless { !it.isLoggedIn }
}
@ -221,6 +226,7 @@ class LandingViewModel @Inject constructor(
mutableStateFlow.update {
it.copy(
selectedEnvironmentType = action.environment.type,
selectedEnvironmentLabel = action.environment.label,
)
}
}
@ -248,6 +254,7 @@ data class LandingState(
val isContinueButtonEnabled: Boolean,
val isRememberMeEnabled: Boolean,
val selectedEnvironmentType: Environment.Type,
val selectedEnvironmentLabel: String,
val dialog: DialogState?,
val accountSummaries: List<AccountSummary>,
) : Parcelable {

View file

@ -473,6 +473,7 @@ private val DEFAULT_STATE = LandingState(
isContinueButtonEnabled = true,
isRememberMeEnabled = false,
selectedEnvironmentType = Environment.Type.US,
selectedEnvironmentLabel = Environment.Us.label,
dialog = null,
accountSummaries = emptyList(),
)

View file

@ -196,7 +196,7 @@ class LandingViewModelTest : BaseViewModelTest() {
@Suppress("MaxLineLength")
@Test
fun `ContinueButtonClick with an email input matching an existing account that is logged in should show the account already added dialog`() {
fun `ContinueButtonClick with an email input matching an existing account on same environment that is logged in should show the account already added dialog`() {
val rememberedEmail = "active@bitwarden.com"
val activeAccount = UserState.Account(
userId = "activeUserId",
@ -246,6 +246,63 @@ class LandingViewModelTest : BaseViewModelTest() {
)
}
@Suppress("MaxLineLength")
@Test
fun `ContinueButtonClick with an email input matching an existing account on different environment that is logged in should emit NavigateToLogin`() =
runTest {
val rememberedEmail = "active@bitwarden.com"
val activeAccount = UserState.Account(
userId = "activeUserId",
name = "name",
email = rememberedEmail,
avatarColorHex = "avatarColorHex",
environment = Environment.Us,
isPremium = true,
isLoggedIn = true,
isVaultUnlocked = true,
needsPasswordReset = false,
isBiometricsEnabled = false,
organizations = emptyList(),
needsMasterPassword = false,
trustedDevice = null,
)
val userState = UserState(
activeUserId = "activeUserId",
accounts = listOf(activeAccount),
)
val viewModel = createViewModel(
rememberedEmail = rememberedEmail,
userState = userState,
)
val accountSummaries = userState.toAccountSummaries()
val initialState = DEFAULT_STATE.copy(
emailInput = rememberedEmail,
isContinueButtonEnabled = true,
isRememberMeEnabled = true,
accountSummaries = accountSummaries,
)
assertEquals(
initialState,
viewModel.stateFlow.value,
)
viewModel.eventFlow.test {
viewModel.trySendAction(LandingAction.EnvironmentTypeSelect(Environment.Eu.type))
assertEquals(
initialState.copy(
selectedEnvironmentLabel = Environment.Eu.label,
selectedEnvironmentType = Environment.Eu.type,
),
viewModel.stateFlow.value,
)
viewModel.trySendAction(LandingAction.ContinueButtonClick)
assertEquals(
LandingEvent.NavigateToLogin(rememberedEmail),
awaitItem(),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `ContinueButtonClick with an email input matching an existing account that is logged out should emit NavigateToLogin`() =
@ -382,7 +439,10 @@ class LandingViewModelTest : BaseViewModelTest() {
awaitItem()
viewModel.trySendAction(LandingAction.EnvironmentTypeSelect(inputEnvironmentType))
assertEquals(
DEFAULT_STATE.copy(selectedEnvironmentType = Environment.Type.EU),
DEFAULT_STATE.copy(
selectedEnvironmentType = Environment.Type.EU,
selectedEnvironmentLabel = Environment.Eu.label,
),
awaitItem(),
)
}
@ -494,6 +554,7 @@ class LandingViewModelTest : BaseViewModelTest() {
isContinueButtonEnabled = false,
isRememberMeEnabled = false,
selectedEnvironmentType = Environment.Type.US,
selectedEnvironmentLabel = Environment.Us.label,
dialog = null,
accountSummaries = emptyList(),
)