diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditLoginItems.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditLoginItems.kt index eb16dd3dc..14b79016a 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditLoginItems.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditLoginItems.kt @@ -346,7 +346,13 @@ private fun UsernameRow( iconPainter = painterResource(id = R.drawable.ic_generator), contentDescription = stringResource(id = R.string.generate_username), ), - onClick = { shouldShowDialog = true }, + onClick = { + if (loginState.username.isEmpty()) { + loginItemTypeHandlers.onOpenUsernameGeneratorClick() + } else { + shouldShowDialog = true + } + }, ) }, modifier = Modifier.padding(horizontal = 16.dp), @@ -375,6 +381,7 @@ private fun UsernameRow( } } +@Suppress("LongMethod") @Composable private fun PasswordRow( loginState: VaultAddEditState.ViewState.Content.ItemType.Login, @@ -403,7 +410,13 @@ private fun PasswordRow( iconPainter = painterResource(id = R.drawable.ic_generator), contentDescription = stringResource(id = R.string.generate_password), ), - onClick = { shouldShowDialog = true }, + onClick = { + if (loginState.password.isEmpty()) { + loginItemTypeHandlers.onOpenPasswordGeneratorClick() + } else { + shouldShowDialog = true + } + }, ) if (shouldShowDialog) { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreenTest.kt index 50f529457..480e9620c 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreenTest.kt @@ -408,7 +408,11 @@ class VaultAddEditScreenTest : BaseComposeTest() { @Suppress("MaxLineLength") @Test - fun `in ItemType_Login state clicking Username generator action should open dialog that triggers OpenUsernameGeneratorClick`() { + fun `in ItemType_Login state clicking Username text field generator action with non empty username should open dialog that triggers OpenUsernameGeneratorClick`() { + mutableStateFlow.update { currentState -> + updateLoginType(currentState) { copy(username = "username") } + } + composeTestRule.assertNoDialogExists() composeTestRule @@ -429,6 +433,28 @@ class VaultAddEditScreenTest : BaseComposeTest() { } } + @Suppress("MaxLineLength") + @Test + fun `in ItemType_Login state clicking Username generator icon with empty username field should trigger OpenPasswordGeneratorClick`() { + mutableStateFlow.update { currentState -> + updateLoginType(currentState) { copy(username = "") } + } + + composeTestRule.assertNoDialogExists() + + composeTestRule + .onNodeWithContentDescriptionAfterScroll(label = "Generate username") + .performClick() + + composeTestRule.assertNoDialogExists() + + verify { + viewModel.trySendAction( + VaultAddEditAction.ItemType.LoginType.OpenUsernameGeneratorClick, + ) + } + } + @Suppress("MaxLineLength") @Test fun `in ItemType_Login state clicking Password checker action should trigger PasswordCheckerClick`() { @@ -449,7 +475,11 @@ class VaultAddEditScreenTest : BaseComposeTest() { @Suppress("MaxLineLength") @Test - fun `in ItemType_Login state click Password text field generator action should open dialog that triggers OpenPasswordGeneratorClick`() { + fun `in ItemType_Login state clicking Password text field generator action with non empty password field should open dialog that triggers OpenPasswordGeneratorClick`() { + mutableStateFlow.update { currentState -> + updateLoginType(currentState) { copy(password = "password") } + } + composeTestRule.assertNoDialogExists() composeTestRule @@ -472,6 +502,30 @@ class VaultAddEditScreenTest : BaseComposeTest() { } } + @Suppress("MaxLineLength") + @Test + fun `in ItemType_Login state clicking Password generator icon with empty password field should trigger OpenPasswordGeneratorClick`() { + mutableStateFlow.update { currentState -> + updateLoginType(currentState) { copy(password = "") } + } + + composeTestRule.assertNoDialogExists() + + composeTestRule + .onNodeWithTextAfterScroll(text = "Password") + .onSiblings() + .onLast() + .performClick() + + composeTestRule.assertNoDialogExists() + + verify { + viewModel.trySendAction( + VaultAddEditAction.ItemType.LoginType.OpenPasswordGeneratorClick, + ) + } + } + @Test fun `in ItemType_Login state changing Password text field should trigger PasswordTextChange`() { composeTestRule