From 92981cefd6948fa209bbb54eb35ae831010eaa31 Mon Sep 17 00:00:00 2001 From: Brian Yencho Date: Tue, 3 Oct 2023 14:38:02 -0500 Subject: [PATCH] Disable LandingScreen Continue button until data is entered (#89) --- .../auth/feature/landing/LandingViewModel.kt | 10 ++++- .../auth/feature/landing/LandingScreenTest.kt | 29 ++++++++++++++ .../feature/landing/LandingViewModelTest.kt | 40 +++++++++++++------ 3 files changed, 65 insertions(+), 14 deletions(-) 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 a9ca61bffa..5ce2d1e884 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 @@ -23,7 +23,7 @@ class LandingViewModel @Inject constructor( initialState = savedStateHandle[KEY_STATE] ?: LandingState( emailInput = "", - isContinueButtonEnabled = true, + isContinueButtonEnabled = false, isRememberMeEnabled = false, ), ) { @@ -45,7 +45,13 @@ class LandingViewModel @Inject constructor( } private fun handleEmailInputUpdated(action: LandingAction.EmailInputChanged) { - mutableStateFlow.update { it.copy(emailInput = action.input) } + val email = action.input + mutableStateFlow.update { + it.copy( + emailInput = email, + isContinueButtonEnabled = email.isNotBlank(), + ) + } } private fun handleContinueButtonClicked() { 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 33a524e7d4..b5eb2ca626 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 @@ -1,5 +1,7 @@ package com.x8bit.bitwarden.ui.auth.feature.landing +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.filterToOne import androidx.compose.ui.test.hasClickAction import androidx.compose.ui.test.onChildren @@ -14,10 +16,37 @@ 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.Test import org.junit.jupiter.api.Assertions.assertEquals class LandingScreenTest : BaseComposeTest() { + @Test + fun `continue button should be enabled or disabled according to the state`() { + val mutableStateFlow = MutableStateFlow( + LandingState( + emailInput = "", + isContinueButtonEnabled = true, + isRememberMeEnabled = false, + ), + ) + val viewModel = mockk(relaxed = true) { + every { eventFlow } returns emptyFlow() + every { stateFlow } returns mutableStateFlow + } + composeTestRule.setContent { + LandingScreen( + onNavigateToCreateAccount = {}, + onNavigateToLogin = {}, + viewModel = viewModel, + ) + } + composeTestRule.onNodeWithText("Continue").assertIsEnabled() + + mutableStateFlow.update { it.copy(isContinueButtonEnabled = false) } + + composeTestRule.onNodeWithText("Continue").assertIsNotEnabled() + } @Test fun `continue button click should send ContinueButtonClick action`() { 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 9b58e254f3..8f44bad506 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 @@ -77,23 +77,39 @@ class LandingViewModelTest : BaseViewModelTest() { } @Test - fun `EmailInputUpdated should update value of email input`() = runTest { - val input = "input" - val viewModel = LandingViewModel(SavedStateHandle()) - viewModel.stateFlow.test { - awaitItem() - viewModel.trySendAction(LandingAction.EmailInputChanged(input)) - assertEquals( - DEFAULT_STATE.copy(emailInput = input), - awaitItem(), - ) + fun `EmailInputUpdated should update value of email input and continue button state`() = + runTest { + val viewModel = LandingViewModel(SavedStateHandle()) + viewModel.stateFlow.test { + // Ignore initial state + awaitItem() + + val nonEmptyInput = "input" + viewModel.trySendAction(LandingAction.EmailInputChanged(nonEmptyInput)) + assertEquals( + DEFAULT_STATE.copy( + emailInput = nonEmptyInput, + isContinueButtonEnabled = true, + ), + awaitItem(), + ) + + val emptyInput = "" + viewModel.trySendAction(LandingAction.EmailInputChanged(emptyInput)) + assertEquals( + DEFAULT_STATE.copy( + emailInput = emptyInput, + isContinueButtonEnabled = false, + ), + awaitItem(), + ) + } } - } companion object { private val DEFAULT_STATE = LandingState( emailInput = "", - isContinueButtonEnabled = true, + isContinueButtonEnabled = false, isRememberMeEnabled = false, ) }