mirror of
https://github.com/bitwarden/android.git
synced 2026-06-02 02:36:58 -05:00
BIT-193 Implement password length validation on create account (#96)
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package com.x8bit.bitwarden.ui.auth.feature.createaccount
|
||||
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
@@ -12,6 +16,8 @@ import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.Pas
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.PasswordInputChange
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.SubmitClick
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
@@ -25,7 +31,7 @@ class CreateAccountScreenTest : BaseComposeTest() {
|
||||
@Test
|
||||
fun `app bar submit click should send SubmitClick action`() {
|
||||
val viewModel = mockk<CreateAccountViewModel>(relaxed = true) {
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE.copy(isSubmitEnabled = true))
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(SubmitClick) } returns Unit
|
||||
}
|
||||
@@ -39,7 +45,7 @@ class CreateAccountScreenTest : BaseComposeTest() {
|
||||
@Test
|
||||
fun `bottom button submit click should send SubmitClick action`() {
|
||||
val viewModel = mockk<CreateAccountViewModel>(relaxed = true) {
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE.copy(isSubmitEnabled = true))
|
||||
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(SubmitClick) } returns Unit
|
||||
}
|
||||
@@ -136,6 +142,50 @@ class CreateAccountScreenTest : BaseComposeTest() {
|
||||
verify { viewModel.trySendAction(PasswordHintChange(TEST_INPUT)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking OK on the error dialog should send ErrorDialogDismiss action`() {
|
||||
val viewModel = mockk<CreateAccountViewModel>(relaxed = true) {
|
||||
every { stateFlow } returns MutableStateFlow(
|
||||
DEFAULT_STATE.copy(
|
||||
errorDialogState = BasicDialogState.Shown(
|
||||
title = "title".asText(),
|
||||
message = "message".asText(),
|
||||
),
|
||||
),
|
||||
)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(CreateAccountAction.ErrorDialogDismiss) } returns Unit
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
CreateAccountScreen(onNavigateBack = {}, viewModel = viewModel)
|
||||
}
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Ok")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
verify { viewModel.trySendAction(CreateAccountAction.ErrorDialogDismiss) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when BasicDialogState is Shown should show dialog`() {
|
||||
val viewModel = mockk<CreateAccountViewModel>(relaxed = true) {
|
||||
every { stateFlow } returns MutableStateFlow(
|
||||
DEFAULT_STATE.copy(
|
||||
errorDialogState = BasicDialogState.Shown(
|
||||
title = "title".asText(),
|
||||
message = "message".asText(),
|
||||
),
|
||||
),
|
||||
)
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { trySendAction(CreateAccountAction.ErrorDialogDismiss) } returns Unit
|
||||
}
|
||||
composeTestRule.setContent {
|
||||
CreateAccountScreen(onNavigateBack = {}, viewModel = viewModel)
|
||||
}
|
||||
composeTestRule.onNode(isDialog()).assertIsDisplayed()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TEST_INPUT = "input"
|
||||
private val DEFAULT_STATE = CreateAccountState(
|
||||
@@ -143,7 +193,7 @@ class CreateAccountScreenTest : BaseComposeTest() {
|
||||
passwordInput = "",
|
||||
confirmPasswordInput = "",
|
||||
passwordHintInput = "",
|
||||
isSubmitEnabled = false,
|
||||
errorDialogState = BasicDialogState.Hidden,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ package com.x8bit.bitwarden.ui.auth.feature.createaccount
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.CloseClick
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.ConfirmPasswordInputChange
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.EmailInputChange
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.PasswordHintChange
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.PasswordInputChange
|
||||
import com.x8bit.bitwarden.ui.auth.feature.createaccount.CreateAccountAction.SubmitClick
|
||||
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 kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -28,7 +30,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() {
|
||||
passwordInput = "password",
|
||||
confirmPasswordInput = "confirmPassword",
|
||||
passwordHintInput = "hint",
|
||||
isSubmitEnabled = false,
|
||||
errorDialogState = BasicDialogState.Hidden,
|
||||
)
|
||||
val handle = SavedStateHandle(mapOf("state" to savedState))
|
||||
val viewModel = CreateAccountViewModel(handle)
|
||||
@@ -36,10 +38,29 @@ class CreateAccountViewModelTest : BaseViewModelTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SubmitClick should emit ShowToast`() = runTest {
|
||||
fun `SubmitClick with password below 12 chars should show password length dialog`() = runTest {
|
||||
val viewModel = CreateAccountViewModel(SavedStateHandle())
|
||||
val input = "abcdefghikl"
|
||||
viewModel.trySendAction(PasswordInputChange("abcdefghikl"))
|
||||
val expectedState = DEFAULT_STATE.copy(
|
||||
passwordInput = input,
|
||||
errorDialogState = BasicDialogState.Shown(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.master_password_length_val_message_x.asText(12),
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(CreateAccountAction.SubmitClick)
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(expectedState, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SubmitClick with long enough password emit ShowToast`() = runTest {
|
||||
val viewModel = CreateAccountViewModel(SavedStateHandle())
|
||||
viewModel.trySendAction(PasswordInputChange("longenoughpassword"))
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.actionChannel.trySend(SubmitClick)
|
||||
viewModel.actionChannel.trySend(CreateAccountAction.SubmitClick)
|
||||
assert(awaitItem() is CreateAccountEvent.ShowToast)
|
||||
}
|
||||
}
|
||||
@@ -95,7 +116,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() {
|
||||
emailInput = "",
|
||||
confirmPasswordInput = "",
|
||||
passwordHintInput = "",
|
||||
isSubmitEnabled = false,
|
||||
errorDialogState = BasicDialogState.Hidden,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user