From eedf0b6f919a885747c82a6a366d6e995468e703 Mon Sep 17 00:00:00 2001 From: joshua-livefront <139182194+joshua-livefront@users.noreply.github.com> Date: Tue, 3 Oct 2023 17:37:36 -0400 Subject: [PATCH] BIT-202: Adding region selector composable to Landing Screen (#91) --- .../ui/auth/feature/auth/AuthNavigation.kt | 4 +- .../auth/feature/landing/LandingNavigation.kt | 2 +- .../ui/auth/feature/landing/LandingScreen.kt | 99 +++++++++++++++++-- .../auth/feature/landing/LandingViewModel.kt | 36 ++++++- .../ui/auth/feature/login/LoginNavigation.kt | 11 ++- .../ui/auth/feature/login/LoginScreen.kt | 2 +- .../ui/auth/feature/login/LoginViewModel.kt | 2 + .../drawable/ic_region_select_dropdown.xml | 13 +++ .../auth/feature/landing/LandingScreenTest.kt | 71 +++++++++++-- .../feature/landing/LandingViewModelTest.kt | 17 +++- .../ui/auth/feature/login/LoginScreenTest.kt | 7 ++ .../auth/feature/login/LoginViewModelTest.kt | 2 + 12 files changed, 238 insertions(+), 28 deletions(-) create mode 100644 app/src/main/res/drawable/ic_region_select_dropdown.xml diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/auth/AuthNavigation.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/auth/AuthNavigation.kt index 3f2de1ba3f..3a0bd91d7d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/auth/AuthNavigation.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/auth/AuthNavigation.kt @@ -25,7 +25,9 @@ fun NavGraphBuilder.authDestinations(navController: NavHostController) { createAccountDestinations() landingDestinations( onNavigateToCreateAccount = { navController.navigateToCreateAccount() }, - onNavigateToLogin = { emailAddress -> navController.navigateToLogin(emailAddress) }, + onNavigateToLogin = { emailAddress, regionLabel -> + navController.navigateToLogin(emailAddress, regionLabel) + }, ) loginDestinations( onNavigateBack = { navController.popBackStack() }, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingNavigation.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingNavigation.kt index 6666d3e1e9..d37b34f0dc 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingNavigation.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingNavigation.kt @@ -19,7 +19,7 @@ fun NavController.navigateToLanding(navOptions: NavOptions? = null) { */ fun NavGraphBuilder.landingDestinations( onNavigateToCreateAccount: () -> Unit, - onNavigateToLogin: (String) -> Unit, + onNavigateToLogin: (emailAddress: String, regionLabel: String) -> Unit, ) { composable(route = LANDING_ROUTE) { LandingScreen( diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt index 236a953185..4a36c1fc97 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreen.kt @@ -2,7 +2,9 @@ package com.x8bit.bitwarden.ui.auth.feature.landing import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -14,11 +16,16 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter @@ -36,6 +43,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledButton import com.x8bit.bitwarden.ui.platform.components.BitwardenSwitch import com.x8bit.bitwarden.ui.platform.components.BitwardenTextButton import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField +import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme /** * The top level composable for the Landing screen. @@ -44,14 +52,17 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField @Suppress("LongMethod") fun LandingScreen( onNavigateToCreateAccount: () -> Unit, - onNavigateToLogin: (emailAddress: String) -> Unit, + onNavigateToLogin: (emailAddress: String, regionLabel: String) -> Unit, viewModel: LandingViewModel = hiltViewModel(), ) { val state by viewModel.stateFlow.collectAsStateWithLifecycle() EventsEffect(viewModel = viewModel) { event -> when (event) { LandingEvent.NavigateToCreateAccount -> onNavigateToCreateAccount() - is LandingEvent.NavigateToLogin -> onNavigateToLogin(event.emailAddress) + is LandingEvent.NavigateToLogin -> onNavigateToLogin( + event.emailAddress, + event.regionLabel, + ) } } @@ -103,6 +114,14 @@ fun LandingScreen( label = stringResource(id = R.string.email_address), ) + RegionSelector( + selectedOption = state.selectedRegion, + options = LandingState.RegionOption.values().toList(), + onOptionSelected = remember(viewModel) { + { viewModel.trySendAction(LandingAction.RegionOptionSelect(it)) } + }, + ) + BitwardenSwitch( label = stringResource(id = R.string.remember_me), isChecked = state.isRememberMeEnabled, @@ -152,12 +171,78 @@ fun LandingScreen( } } +/** + * A dropdown selector UI component specific to region url selection on the Landing screen. + * + * This composable displays a dropdown menu allowing users to select a region + * from a list of options. When an option is selected, it invokes the provided callback + * and displays the currently selected region on the UI. + * + * @param selectedOption The currently selected region option. + * @param options A list of region options available for selection. + * @param onOptionSelected A callback that gets invoked when a region option is selected + * and passes the selected option as an argument. + * + */ +@Composable +private fun RegionSelector( + selectedOption: LandingState.RegionOption, + options: List, + onOptionSelected: (LandingState.RegionOption) -> Unit, +) { + var expanded by remember { mutableStateOf(false) } + + Box(modifier = Modifier.fillMaxWidth()) { + Row( + modifier = Modifier + .clickable { expanded = !expanded } + .fillMaxWidth() + .padding(start = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = stringResource(id = R.string.logging_in_on), + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(end = 12.dp), + ) + Text( + text = selectedOption.label, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(end = 8.dp), + ) + Icon( + painter = painterResource(id = R.drawable.ic_region_select_dropdown), + contentDescription = stringResource(id = R.string.region), + tint = MaterialTheme.colorScheme.primary, + ) + } + + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + ) { + options.forEach { optionString -> + DropdownMenuItem( + text = { Text(text = optionString.label) }, + onClick = { + expanded = false + onOptionSelected(optionString) + }, + ) + } + } + } +} + @Preview @Composable private fun LandingScreen_preview() { - LandingScreen( - onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, - viewModel = LandingViewModel(SavedStateHandle()), - ) + BitwardenTheme { + LandingScreen( + onNavigateToCreateAccount = {}, + onNavigateToLogin = { _, _ -> }, + viewModel = LandingViewModel(SavedStateHandle()), + ) + } } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt index 5ce2d1e884..13bf31e9ec 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModel.kt @@ -25,6 +25,7 @@ class LandingViewModel @Inject constructor( emailInput = "", isContinueButtonEnabled = false, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) { @@ -41,6 +42,7 @@ class LandingViewModel @Inject constructor( LandingAction.CreateAccountClick -> handleCreateAccountClicked() is LandingAction.RememberMeToggle -> handleRememberMeToggled(action) is LandingAction.EmailInputChanged -> handleEmailInputUpdated(action) + is LandingAction.RegionOptionSelect -> handleRegionSelect(action) } } @@ -59,7 +61,9 @@ class LandingViewModel @Inject constructor( if (mutableStateFlow.value.emailInput.isBlank()) { return } - sendEvent(LandingEvent.NavigateToLogin(mutableStateFlow.value.emailInput)) + val email = mutableStateFlow.value.emailInput + val selectedRegionLabel = mutableStateFlow.value.selectedRegion.label + sendEvent(LandingEvent.NavigateToLogin(email, selectedRegionLabel)) } private fun handleCreateAccountClicked() { @@ -69,6 +73,14 @@ class LandingViewModel @Inject constructor( private fun handleRememberMeToggled(action: LandingAction.RememberMeToggle) { mutableStateFlow.update { it.copy(isRememberMeEnabled = action.isChecked) } } + + private fun handleRegionSelect(action: LandingAction.RegionOptionSelect) { + mutableStateFlow.update { + it.copy( + selectedRegion = action.regionOption, + ) + } + } } /** @@ -79,7 +91,17 @@ data class LandingState( val emailInput: String, val isContinueButtonEnabled: Boolean, val isRememberMeEnabled: Boolean, -) : Parcelable + val selectedRegion: RegionOption, +) : Parcelable { + /** + * Enumerates the possible region options with their corresponding labels. + */ + enum class RegionOption(val label: String) { + BITWARDEN_US("bitwarden.com"), + BITWARDEN_EU("bitwarden.eu"), + SELF_HOSTED("Self-hosted"), + } +} /** * Models events for the landing screen. @@ -91,10 +113,11 @@ sealed class LandingEvent { data object NavigateToCreateAccount : LandingEvent() /** - * Navigates to the Login screen with the given email address. + * Navigates to the Login screen with the given email address and region label. */ data class NavigateToLogin( val emailAddress: String, + val regionLabel: String, ) : LandingEvent() } @@ -125,4 +148,11 @@ sealed class LandingAction { data class EmailInputChanged( val input: String, ) : LandingAction() + + /** + * Indicates that the selection from the region drop down has changed. + */ + data class RegionOptionSelect( + val regionOption: LandingState.RegionOption, + ) : LandingAction() } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginNavigation.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginNavigation.kt index 2c037b62d7..053b48fc0c 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginNavigation.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginNavigation.kt @@ -9,25 +9,28 @@ import androidx.navigation.compose.composable import androidx.navigation.navArgument private const val EMAIL_ADDRESS: String = "email_address" -private const val LOGIN_ROUTE: String = "login/{$EMAIL_ADDRESS}" +private const val REGION_LABEL: String = "region_label" +private const val LOGIN_ROUTE: String = "login/{$EMAIL_ADDRESS}/{$REGION_LABEL}" /** * Class to retrieve login arguments from the [SavedStateHandle]. */ -class LoginArgs(val emailAddress: String) { +class LoginArgs(val emailAddress: String, val regionLabel: String) { constructor(savedStateHandle: SavedStateHandle) : this( checkNotNull(savedStateHandle[EMAIL_ADDRESS]) as String, + checkNotNull(savedStateHandle[REGION_LABEL]) as String, ) } /** - * Navigate to the login screen with the given email address. + * Navigate to the login screen with the given email address and region label. */ fun NavController.navigateToLogin( emailAddress: String, + regionLabel: String, navOptions: NavOptions? = null, ) { - this.navigate("login/$emailAddress", navOptions) + this.navigate("login/$emailAddress/$regionLabel", navOptions) } /** diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreen.kt index aa418b4670..d5e44fe8d3 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreen.kt @@ -145,7 +145,7 @@ fun LoginScreen( text = stringResource( id = R.string.log_in_attempt_by_x_on_y, state.emailAddress, - "bitwarden.com", + state.region, ), textAlign = TextAlign.Start, style = MaterialTheme.typography.bodyMedium, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModel.kt index 8571fd1dc6..76899b967d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModel.kt @@ -34,6 +34,7 @@ class LoginViewModel @Inject constructor( emailAddress = LoginArgs(savedStateHandle).emailAddress, isLoginButtonEnabled = true, passwordInput = "", + region = LoginArgs(savedStateHandle).regionLabel, ), ) { @@ -135,6 +136,7 @@ class LoginViewModel @Inject constructor( data class LoginState( val passwordInput: String, val emailAddress: String, + val region: String, val isLoginButtonEnabled: Boolean, ) : Parcelable diff --git a/app/src/main/res/drawable/ic_region_select_dropdown.xml b/app/src/main/res/drawable/ic_region_select_dropdown.xml new file mode 100644 index 0000000000..311eb85c89 --- /dev/null +++ b/app/src/main/res/drawable/ic_region_select_dropdown.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt index b5eb2ca626..b72864b9da 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingScreenTest.kt @@ -28,6 +28,7 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) val viewModel = mockk(relaxed = true) { @@ -37,7 +38,7 @@ class LandingScreenTest : BaseComposeTest() { composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -57,13 +58,14 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -82,13 +84,14 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -111,13 +114,14 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -137,13 +141,14 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = {}, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -163,13 +168,14 @@ class LandingScreenTest : BaseComposeTest() { emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = { onNavigateToCreateAccountCalled = true }, - onNavigateToLogin = {}, + onNavigateToLogin = { _, _ -> }, viewModel = viewModel, ) } @@ -179,24 +185,69 @@ class LandingScreenTest : BaseComposeTest() { @Test fun `NavigateToLogin event should call onNavigateToLogin`() { val testEmail = "test@test.com" - var onNavigateToLoginEmail = "" + val testRegion = "bitwarden.com" + + var capturedEmail: String? = null + var capturedRegion: String? = null + val viewModel = mockk(relaxed = true) { - every { eventFlow } returns flowOf(LandingEvent.NavigateToLogin(testEmail)) + every { eventFlow } returns flowOf(LandingEvent.NavigateToLogin(testEmail, testRegion)) every { stateFlow } returns MutableStateFlow( LandingState( emailInput = "", isContinueButtonEnabled = true, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ), ) } + composeTestRule.setContent { LandingScreen( onNavigateToCreateAccount = { }, - onNavigateToLogin = { onNavigateToLoginEmail = it }, + onNavigateToLogin = { email, region -> + capturedEmail = email + capturedRegion = region + }, viewModel = viewModel, ) } - assertEquals(testEmail, onNavigateToLoginEmail) + + assertEquals(testEmail, capturedEmail) + assertEquals(testRegion, capturedRegion) + } + + @Test + fun `selecting region should send RegionOptionSelect action`() { + val selectedRegion = LandingState.RegionOption.BITWARDEN_EU + val viewModel = mockk(relaxed = true) { + every { eventFlow } returns emptyFlow() + every { stateFlow } returns MutableStateFlow( + LandingState( + emailInput = "", + isContinueButtonEnabled = true, + isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, + ), + ) + } + + composeTestRule.setContent { + LandingScreen( + onNavigateToCreateAccount = {}, + onNavigateToLogin = { _, _ -> }, + viewModel = viewModel, + ) + } + + // Clicking to open dropdown + composeTestRule.onNodeWithText(LandingState.RegionOption.BITWARDEN_US.label).performClick() + + // Clicking item from the dropdown menu + composeTestRule.onNodeWithText(selectedRegion.label).performClick() + + verify { + viewModel.trySendAction(LandingAction.RegionOptionSelect(selectedRegion)) + } } } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt index 8f44bad506..44f557c750 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/landing/LandingViewModelTest.kt @@ -38,7 +38,7 @@ class LandingViewModelTest : BaseViewModelTest() { viewModel.eventFlow.test { viewModel.actionChannel.trySend(LandingAction.ContinueButtonClick) assertEquals( - LandingEvent.NavigateToLogin("input"), + LandingEvent.NavigateToLogin("input", "bitwarden.com"), awaitItem(), ) } @@ -106,11 +106,26 @@ class LandingViewModelTest : BaseViewModelTest() { } } + @Test + fun `RegionOptionSelect should update value of selected region`() = runTest { + val inputRegion = LandingState.RegionOption.BITWARDEN_EU + val viewModel = LandingViewModel(SavedStateHandle()) + viewModel.stateFlow.test { + awaitItem() + viewModel.trySendAction(LandingAction.RegionOptionSelect(inputRegion)) + assertEquals( + DEFAULT_STATE.copy(selectedRegion = LandingState.RegionOption.BITWARDEN_EU), + awaitItem(), + ) + } + } + companion object { private val DEFAULT_STATE = LandingState( emailInput = "", isContinueButtonEnabled = false, isRememberMeEnabled = false, + selectedRegion = LandingState.RegionOption.BITWARDEN_US, ) } } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreenTest.kt index c9e7bd2d11..2a84682bfb 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginScreenTest.kt @@ -34,6 +34,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -58,6 +59,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -82,6 +84,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -106,6 +109,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -142,6 +146,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -167,6 +172,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } @@ -192,6 +198,7 @@ class LoginScreenTest : BaseComposeTest() { emailAddress = "", isLoginButtonEnabled = false, passwordInput = "", + region = "", ), ) } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModelTest.kt index 982c0c9949..004f0e4c1a 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/login/LoginViewModelTest.kt @@ -25,6 +25,7 @@ class LoginViewModelTest : BaseViewModelTest() { private val savedStateHandle = SavedStateHandle().also { it["email_address"] = "test@gmail.com" + it["region_label"] = "" } @BeforeEach @@ -262,6 +263,7 @@ class LoginViewModelTest : BaseViewModelTest() { emailAddress = "test@gmail.com", passwordInput = "", isLoginButtonEnabled = true, + region = "", ) private const val LOGIN_RESULT_PATH =