mirror of
https://github.com/bitwarden/android.git
synced 2024-11-25 02:46:00 +03:00
Add edit cipher org events (#3352)
This commit is contained in:
parent
949768ac95
commit
d1e8ed63a4
11 changed files with 383 additions and 17 deletions
|
@ -9,6 +9,10 @@ import androidx.compose.foundation.lazy.items
|
|||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.testTag
|
||||
|
@ -70,10 +74,16 @@ fun LazyListScope.vaultAddEditCardItems(
|
|||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
var showNumber by rememberSaveable { mutableStateOf(value = false) }
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.number),
|
||||
value = cardState.number,
|
||||
onValueChange = cardHandlers.onNumberTextChange,
|
||||
showPassword = showNumber,
|
||||
showPasswordChange = {
|
||||
showNumber = !showNumber
|
||||
cardHandlers.onNumberVisibilityChange(showNumber)
|
||||
},
|
||||
modifier = Modifier
|
||||
.testTag("CardNumberEntry")
|
||||
.fillMaxWidth()
|
||||
|
@ -140,10 +150,16 @@ fun LazyListScope.vaultAddEditCardItems(
|
|||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
var showSecurityCode by rememberSaveable { mutableStateOf(value = false) }
|
||||
BitwardenPasswordField(
|
||||
label = stringResource(id = R.string.security_code),
|
||||
value = cardState.securityCode,
|
||||
onValueChange = cardHandlers.onSecurityCodeTextChange,
|
||||
showPassword = showSecurityCode,
|
||||
showPasswordChange = {
|
||||
showSecurityCode = !showSecurityCode
|
||||
cardHandlers.onSecurityCodeVisibilityChange(showSecurityCode)
|
||||
},
|
||||
keyboardType = KeyboardType.NumberPassword,
|
||||
modifier = Modifier
|
||||
.testTag("CardSecurityCodeEntry")
|
||||
|
@ -259,7 +275,7 @@ fun LazyListScope.vaultAddEditCardItems(
|
|||
|
||||
items(commonState.customFieldData) { customItem ->
|
||||
VaultAddEditCustomField(
|
||||
customItem,
|
||||
customField = customItem,
|
||||
onCustomFieldValueChange = commonHandlers.onCustomFieldValueChange,
|
||||
onCustomFieldAction = commonHandlers.onCustomFieldActionSelect,
|
||||
modifier = Modifier
|
||||
|
@ -273,6 +289,7 @@ fun LazyListScope.vaultAddEditCardItems(
|
|||
VaultLinkedFieldType.BRAND,
|
||||
VaultLinkedFieldType.NUMBER,
|
||||
),
|
||||
onHiddenVisibilityChanged = commonHandlers.onHiddenFieldVisibilityChange,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
* @param onCustomFieldAction Invoked when the user chooses an action.
|
||||
* @param modifier Modifier for the UI elements.
|
||||
* @param supportedLinkedTypes The supported linked types for the vault item.
|
||||
* @param onHiddenVisibilityChanged Emits when the visibility of a hidden custom field changes.
|
||||
*/
|
||||
@Composable
|
||||
@Suppress("LongMethod")
|
||||
|
@ -46,6 +47,7 @@ fun VaultAddEditCustomField(
|
|||
onCustomFieldAction: (CustomFieldAction, VaultAddEditState.Custom) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
supportedLinkedTypes: ImmutableList<VaultLinkedFieldType> = persistentListOf(),
|
||||
onHiddenVisibilityChanged: (Boolean) -> Unit,
|
||||
) {
|
||||
var shouldShowChooserDialog by remember { mutableStateOf(false) }
|
||||
var shouldShowEditDialog by remember { mutableStateOf(false) }
|
||||
|
@ -91,11 +93,12 @@ fun VaultAddEditCustomField(
|
|||
|
||||
is VaultAddEditState.Custom.HiddenField -> {
|
||||
CustomFieldHiddenField(
|
||||
customField.name,
|
||||
customField.value,
|
||||
label = customField.name,
|
||||
value = customField.value,
|
||||
onValueChanged = {
|
||||
onCustomFieldValueChange(customField.copy(value = it))
|
||||
},
|
||||
onVisibilityChanged = onHiddenVisibilityChanged,
|
||||
onEditValue = { shouldShowChooserDialog = true },
|
||||
modifier = modifier,
|
||||
)
|
||||
|
@ -175,12 +178,19 @@ private fun CustomFieldHiddenField(
|
|||
value: String,
|
||||
onValueChanged: (String) -> Unit,
|
||||
onEditValue: () -> Unit,
|
||||
onVisibilityChanged: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var shouldShowPassword by remember { mutableStateOf(value = false) }
|
||||
BitwardenPasswordFieldWithActions(
|
||||
label = label,
|
||||
value = value,
|
||||
onValueChange = onValueChanged,
|
||||
showPassword = shouldShowPassword,
|
||||
showPasswordChange = {
|
||||
shouldShowPassword = !shouldShowPassword
|
||||
onVisibilityChanged(shouldShowPassword)
|
||||
},
|
||||
singleLine = true,
|
||||
modifier = modifier,
|
||||
actions = {
|
||||
|
|
|
@ -403,6 +403,7 @@ fun LazyListScope.vaultAddEditIdentityItems(
|
|||
VaultLinkedFieldType.LAST_NAME,
|
||||
VaultLinkedFieldType.FULL_NAME,
|
||||
),
|
||||
onHiddenVisibilityChanged = commonTypeHandlers.onHiddenFieldVisibilityChange,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -301,7 +302,7 @@ fun LazyListScope.vaultAddEditLoginItems(
|
|||
|
||||
items(commonState.customFieldData) { customItem ->
|
||||
VaultAddEditCustomField(
|
||||
customItem,
|
||||
customField = customItem,
|
||||
onCustomFieldValueChange = commonActionHandler.onCustomFieldValueChange,
|
||||
onCustomFieldAction = commonActionHandler.onCustomFieldActionSelect,
|
||||
modifier = Modifier
|
||||
|
@ -311,6 +312,7 @@ fun LazyListScope.vaultAddEditLoginItems(
|
|||
VaultLinkedFieldType.PASSWORD,
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
onHiddenVisibilityChanged = commonActionHandler.onHiddenFieldVisibilityChange,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -436,10 +438,16 @@ private fun PasswordRow(
|
|||
var shouldShowDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
if (canViewPassword) {
|
||||
var shouldShowPassword by remember { mutableStateOf(false) }
|
||||
BitwardenPasswordFieldWithActions(
|
||||
label = stringResource(id = R.string.password),
|
||||
value = password,
|
||||
onValueChange = loginItemTypeHandlers.onPasswordTextChange,
|
||||
showPassword = shouldShowPassword,
|
||||
showPasswordChange = {
|
||||
shouldShowPassword = !shouldShowPassword
|
||||
loginItemTypeHandlers.onPasswordVisibilityChange(shouldShowPassword)
|
||||
},
|
||||
showPasswordTestTag = "ViewPasswordButton",
|
||||
passwordFieldTestTag = "LoginPasswordEntry",
|
||||
modifier = Modifier
|
||||
|
|
|
@ -154,12 +154,13 @@ fun LazyListScope.vaultAddEditSecureNotesItems(
|
|||
}
|
||||
items(commonState.customFieldData) { customItem ->
|
||||
VaultAddEditCustomField(
|
||||
customItem,
|
||||
customField = customItem,
|
||||
onCustomFieldValueChange = commonTypeHandlers.onCustomFieldValueChange,
|
||||
onCustomFieldAction = commonTypeHandlers.onCustomFieldActionSelect,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
onHiddenVisibilityChanged = commonTypeHandlers.onHiddenFieldVisibilityChange,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -214,9 +214,9 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
|
||||
private fun handleCommonActions(action: VaultAddEditAction.Common) {
|
||||
when (action) {
|
||||
is VaultAddEditAction.Common.CustomFieldValueChange -> handleCustomFieldValueChange(
|
||||
action,
|
||||
)
|
||||
is VaultAddEditAction.Common.CustomFieldValueChange -> {
|
||||
handleCustomFieldValueChange(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.Common.FolderChange -> handleFolderTextInputChange(action)
|
||||
is VaultAddEditAction.Common.NameTextChange -> handleNameTextInputChange(action)
|
||||
|
@ -235,19 +235,23 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
is VaultAddEditAction.Common.DismissDialog -> handleDismissDialog()
|
||||
is VaultAddEditAction.Common.SaveClick -> handleSaveClick()
|
||||
is VaultAddEditAction.Common.TypeOptionSelect -> handleTypeOptionSelect(action)
|
||||
is VaultAddEditAction.Common.AddNewCustomFieldClick -> handleAddNewCustomFieldClick(
|
||||
action,
|
||||
)
|
||||
is VaultAddEditAction.Common.AddNewCustomFieldClick -> {
|
||||
handleAddNewCustomFieldClick(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.Common.TooltipClick -> handleTooltipClick()
|
||||
is VaultAddEditAction.Common.CustomFieldActionSelect -> handleCustomFieldActionSelected(
|
||||
action,
|
||||
)
|
||||
is VaultAddEditAction.Common.CustomFieldActionSelect -> {
|
||||
handleCustomFieldActionSelected(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.Common.CollectionSelect -> handleCollectionSelect(action)
|
||||
is VaultAddEditAction.Common.InitialAutofillDialogDismissed -> {
|
||||
handleInitialAutofillDialogDismissed()
|
||||
}
|
||||
|
||||
is VaultAddEditAction.Common.HiddenFieldVisibilityChange -> {
|
||||
handleHiddenFieldVisibilityChange(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,6 +426,20 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleHiddenFieldVisibilityChange(
|
||||
action: VaultAddEditAction.Common.HiddenFieldVisibilityChange,
|
||||
) {
|
||||
onEdit {
|
||||
if (action.isVisible) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledHiddenFieldVisible(
|
||||
cipherId = it.vaultItemId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAddNewCustomFieldClick(
|
||||
action: VaultAddEditAction.Common.AddNewCustomFieldClick,
|
||||
) {
|
||||
|
@ -636,6 +654,10 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
is VaultAddEditAction.ItemType.LoginType.ClearTotpKeyClick -> {
|
||||
handleLoginClearTotpKey()
|
||||
}
|
||||
|
||||
is VaultAddEditAction.ItemType.LoginType.PasswordVisibilityChange -> {
|
||||
handlePasswordVisibilityChange(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,6 +758,20 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handlePasswordVisibilityChange(
|
||||
action: VaultAddEditAction.ItemType.LoginType.PasswordVisibilityChange,
|
||||
) {
|
||||
onEdit {
|
||||
if (action.isVisible) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledPasswordVisible(
|
||||
cipherId = it.vaultItemId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLoginAddNewUriClick() {
|
||||
updateLoginContent { loginType ->
|
||||
loginType.copy(
|
||||
|
@ -961,9 +997,17 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
handleCardNumberTextChange(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.ItemType.CardType.NumberVisibilityChange -> {
|
||||
handleNumberVisibilityChange(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.ItemType.CardType.SecurityCodeTextChange -> {
|
||||
handleCardSecurityCodeTextChange(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.ItemType.CardType.SecurityCodeVisibilityChange -> {
|
||||
handleSecurityCodeVisibilityChange(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -997,12 +1041,40 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
updateCardContent { it.copy(number = action.number) }
|
||||
}
|
||||
|
||||
private fun handleNumberVisibilityChange(
|
||||
action: VaultAddEditAction.ItemType.CardType.NumberVisibilityChange,
|
||||
) {
|
||||
onEdit {
|
||||
if (action.isVisible) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledCardNumberVisible(
|
||||
cipherId = it.vaultItemId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCardSecurityCodeTextChange(
|
||||
action: VaultAddEditAction.ItemType.CardType.SecurityCodeTextChange,
|
||||
) {
|
||||
updateCardContent { it.copy(securityCode = action.securityCode) }
|
||||
}
|
||||
|
||||
private fun handleSecurityCodeVisibilityChange(
|
||||
action: VaultAddEditAction.ItemType.CardType.SecurityCodeVisibilityChange,
|
||||
) {
|
||||
onEdit {
|
||||
if (action.isVisible) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledCardCodeVisible(
|
||||
cipherId = it.vaultItemId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//endregion Card Type Handlers
|
||||
|
||||
//region Internal Type Handlers
|
||||
|
@ -1024,8 +1096,9 @@ class VaultAddEditViewModel @Inject constructor(
|
|||
handleGeneratorResultReceive(action)
|
||||
}
|
||||
|
||||
is VaultAddEditAction.Internal.PasswordBreachReceive ->
|
||||
is VaultAddEditAction.Internal.PasswordBreachReceive -> {
|
||||
handlePasswordBreachReceive(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2009,6 +2082,13 @@ sealed class VaultAddEditAction {
|
|||
data class CollectionSelect(
|
||||
val collection: VaultCollection,
|
||||
) : Common()
|
||||
|
||||
/**
|
||||
* The user has changed the visibility state of a hidden field.
|
||||
*
|
||||
* @property isVisible the new visibility state of the hidden field.
|
||||
*/
|
||||
data class HiddenFieldVisibilityChange(val isVisible: Boolean) : Common()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2085,6 +2165,13 @@ sealed class VaultAddEditAction {
|
|||
* Represents the action to add a new URI field.
|
||||
*/
|
||||
data object AddNewUriClick : LoginType()
|
||||
|
||||
/**
|
||||
* Fired when the password's visibility has changed.
|
||||
*
|
||||
* @property isVisible The new password visibility state.
|
||||
*/
|
||||
data class PasswordVisibilityChange(val isVisible: Boolean) : LoginType()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2240,6 +2327,13 @@ sealed class VaultAddEditAction {
|
|||
*/
|
||||
data class NumberTextChange(val number: String) : CardType()
|
||||
|
||||
/**
|
||||
* Fired when the number's visibility has changed.
|
||||
*
|
||||
* @property isVisible The new number visibility state.
|
||||
*/
|
||||
data class NumberVisibilityChange(val isVisible: Boolean) : CardType()
|
||||
|
||||
/**
|
||||
* Fired when the brand input is selected.
|
||||
*
|
||||
|
@ -2272,6 +2366,13 @@ sealed class VaultAddEditAction {
|
|||
* @property securityCode The new security code text.
|
||||
*/
|
||||
data class SecurityCodeTextChange(val securityCode: String) : CardType()
|
||||
|
||||
/**
|
||||
* Fired when the security code's visibility has changed.
|
||||
*
|
||||
* @property isVisible The new code visibility state.
|
||||
*/
|
||||
data class SecurityCodeVisibilityChange(val isVisible: Boolean) : CardType()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ import com.x8bit.bitwarden.ui.vault.model.VaultCardExpirationMonth
|
|||
* @property onExpirationMonthSelected Handles the action when an expiration month is selected.
|
||||
* @property onExpirationYearTextChange Handles the action when the expiration year text is changed.
|
||||
* @property onSecurityCodeTextChange Handles the action when the expiration year text is changed.
|
||||
* @property onSecurityCodeVisibilityChange Handles the action when the security code visibility
|
||||
* changes.
|
||||
* @property onNumberVisibilityChange Handles the action when the number visibility changes.
|
||||
*/
|
||||
@Suppress("MaxLineLength")
|
||||
data class VaultAddEditCardTypeHandlers(
|
||||
|
@ -24,8 +27,9 @@ data class VaultAddEditCardTypeHandlers(
|
|||
val onExpirationMonthSelected: (VaultCardExpirationMonth) -> Unit,
|
||||
val onExpirationYearTextChange: (String) -> Unit,
|
||||
val onSecurityCodeTextChange: (String) -> Unit,
|
||||
|
||||
) {
|
||||
val onSecurityCodeVisibilityChange: (Boolean) -> Unit,
|
||||
val onNumberVisibilityChange: (Boolean) -> Unit,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
/**
|
||||
|
@ -76,6 +80,18 @@ data class VaultAddEditCardTypeHandlers(
|
|||
),
|
||||
)
|
||||
},
|
||||
onSecurityCodeVisibilityChange = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.SecurityCodeVisibilityChange(
|
||||
isVisible = it,
|
||||
),
|
||||
)
|
||||
},
|
||||
onNumberVisibilityChange = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.NumberVisibilityChange(isVisible = it),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ data class VaultAddEditCommonHandlers(
|
|||
val onCustomFieldValueChange: (VaultAddEditState.Custom) -> Unit,
|
||||
val onCustomFieldActionSelect: (CustomFieldAction, VaultAddEditState.Custom) -> Unit,
|
||||
val onCollectionSelect: (VaultCollection) -> Unit,
|
||||
val onHiddenFieldVisibilityChange: (Boolean) -> Unit,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
|
@ -116,6 +117,11 @@ data class VaultAddEditCommonHandlers(
|
|||
),
|
||||
)
|
||||
},
|
||||
onHiddenFieldVisibilityChange = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.Common.HiddenFieldVisibilityChange(isVisible = it),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import com.x8bit.bitwarden.ui.vault.feature.addedit.model.UriItem
|
|||
* @property onCopyTotpKeyClick Handles the action when the copy TOTP text button is clicked.
|
||||
* @property onClearTotpKeyClick Handles the action when the clear TOTP text button is clicked.
|
||||
* @property onAddNewUriClick Handles the action when the add new URI button is clicked.
|
||||
* @property onPasswordVisibilityChange Handles the action when the password visibility button is
|
||||
* clicked.
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
data class VaultAddEditLoginTypeHandlers(
|
||||
|
@ -36,6 +38,7 @@ data class VaultAddEditLoginTypeHandlers(
|
|||
val onCopyTotpKeyClick: (String) -> Unit,
|
||||
val onClearTotpKeyClick: () -> Unit,
|
||||
val onAddNewUriClick: () -> Unit,
|
||||
val onPasswordVisibilityChange: (Boolean) -> Unit,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
|
@ -106,6 +109,11 @@ data class VaultAddEditLoginTypeHandlers(
|
|||
VaultAddEditAction.ItemType.LoginType.ClearTotpKeyClick,
|
||||
)
|
||||
},
|
||||
onPasswordVisibilityChange = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.LoginType.PasswordVisibilityChange(it),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.compose.ui.test.isDialog
|
|||
import androidx.compose.ui.test.isPopup
|
||||
import androidx.compose.ui.test.onAllNodesWithContentDescription
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onChildren
|
||||
import androidx.compose.ui.test.onFirst
|
||||
import androidx.compose.ui.test.onLast
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
|
@ -466,6 +467,24 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
|||
.assertDoesNotExist()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state changing password visibility state should send PasswordVisibilityChange`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Password")
|
||||
.assertExists()
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Show")
|
||||
.assertExists()
|
||||
.performClick()
|
||||
|
||||
verify(exactly = 1) {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.LoginType.PasswordVisibilityChange(isVisible = true),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state changing Username text field should trigger UsernameTextChange`() {
|
||||
composeTestRule
|
||||
|
@ -1671,6 +1690,30 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Card changing number visibility should trigger NumberVisibilityChange`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_CARD.copy(
|
||||
viewState = VaultAddEditState.ViewState.Content(
|
||||
common = VaultAddEditState.ViewState.Content.Common(),
|
||||
type = VaultAddEditState.ViewState.Content.ItemType.Card(number = "12345"),
|
||||
isIndividualVaultDisabled = false,
|
||||
),
|
||||
)
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Number")
|
||||
.assertExists()
|
||||
.onChildren()
|
||||
.filterToOne(hasContentDescription(value = "Show"))
|
||||
.assertExists()
|
||||
.performClick()
|
||||
|
||||
verify(exactly = 1) {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.NumberVisibilityChange(isVisible = true),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Card the number text field should display the text provided by the state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_CARD
|
||||
|
@ -1831,6 +1874,30 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Card changing code visibility should trigger SecurityCodeVisibilityChange`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_CARD.copy(
|
||||
viewState = VaultAddEditState.ViewState.Content(
|
||||
common = VaultAddEditState.ViewState.Content.Common(),
|
||||
type = VaultAddEditState.ViewState.Content.ItemType.Card(number = "12345"),
|
||||
isIndividualVaultDisabled = false,
|
||||
),
|
||||
)
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Security code")
|
||||
.assertExists()
|
||||
.onChildren()
|
||||
.filterToOne(hasContentDescription(value = "Show"))
|
||||
.assertExists()
|
||||
.performClick()
|
||||
|
||||
verify(exactly = 1) {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.SecurityCodeVisibilityChange(isVisible = true),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Card the security code text field should display the text provided by the state`() {
|
||||
|
@ -2373,6 +2440,40 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `changing hidden field visibility state should send HiddenFieldVisibilityChange`() {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
viewState = VaultAddEditState.ViewState.Content(
|
||||
common = VaultAddEditState.ViewState.Content.Common(
|
||||
customFieldData = listOf(
|
||||
VaultAddEditState.Custom.HiddenField(
|
||||
itemId = "itemId",
|
||||
name = "Hidden item",
|
||||
value = "I am hiding",
|
||||
),
|
||||
),
|
||||
),
|
||||
type = VaultAddEditState.ViewState.Content.ItemType.Login(),
|
||||
isIndividualVaultDisabled = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Hidden item")
|
||||
.assertExists()
|
||||
composeTestRule
|
||||
.onAllNodesWithContentDescriptionAfterScroll(label = "Show")
|
||||
.onLast()
|
||||
.performClick()
|
||||
|
||||
verify(exactly = 1) {
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.Common.HiddenFieldVisibilityChange(isVisible = true),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
|
|
@ -1205,6 +1205,32 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
|||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `PasswordVisibilityChange should log an event when in edit mode and password is visible`() =
|
||||
runTest {
|
||||
val vaultAddEditType = VaultAddEditType.EditItem(vaultItemId = "vault_item_id")
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = loginInitialSavedStateHandle.apply {
|
||||
set("state", loginInitialState.copy(vaultAddEditType = vaultAddEditType))
|
||||
set("vault_add_edit_type", vaultAddEditType)
|
||||
},
|
||||
)
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.LoginType.PasswordVisibilityChange(
|
||||
isVisible = true,
|
||||
),
|
||||
)
|
||||
|
||||
verify(exactly = 1) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledPasswordVisible(
|
||||
cipherId = "vault_item_id",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `OpenUsernameGeneratorClick should emit NavigateToGeneratorModal with username GeneratorMode`() =
|
||||
|
@ -1920,6 +1946,53 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NumberVisibilityChange should log an event when in edit mode and password is visible`() =
|
||||
runTest {
|
||||
val vaultAddEditType = VaultAddEditType.EditItem(vaultItemId = "vault_item_id")
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = loginInitialSavedStateHandle.apply {
|
||||
set("state", loginInitialState.copy(vaultAddEditType = vaultAddEditType))
|
||||
set("vault_add_edit_type", vaultAddEditType)
|
||||
},
|
||||
)
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.NumberVisibilityChange(isVisible = true),
|
||||
)
|
||||
|
||||
verify(exactly = 1) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledCardNumberVisible(
|
||||
cipherId = "vault_item_id",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `SecurityCodeVisibilityChange should log an event when in edit mode and password is visible`() =
|
||||
runTest {
|
||||
val vaultAddEditType = VaultAddEditType.EditItem(vaultItemId = "vault_item_id")
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = loginInitialSavedStateHandle.apply {
|
||||
set("state", loginInitialState.copy(vaultAddEditType = vaultAddEditType))
|
||||
set("vault_add_edit_type", vaultAddEditType)
|
||||
},
|
||||
)
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.ItemType.CardType.SecurityCodeVisibilityChange(isVisible = true),
|
||||
)
|
||||
|
||||
verify(exactly = 1) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledCardCodeVisible(
|
||||
cipherId = "vault_item_id",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class VaultAddEditCommonActions {
|
||||
private lateinit var viewModel: VaultAddEditViewModel
|
||||
|
@ -2371,6 +2444,30 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `HiddenFieldVisibilityChange should log an event when in edit mode and password is visible`() =
|
||||
runTest {
|
||||
val vaultAddEditType = VaultAddEditType.EditItem(vaultItemId = "vault_item_id")
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = loginInitialSavedStateHandle.apply {
|
||||
set("state", loginInitialState.copy(vaultAddEditType = vaultAddEditType))
|
||||
set("vault_add_edit_type", vaultAddEditType)
|
||||
},
|
||||
)
|
||||
viewModel.trySendAction(
|
||||
VaultAddEditAction.Common.HiddenFieldVisibilityChange(isVisible = true),
|
||||
)
|
||||
|
||||
verify(exactly = 1) {
|
||||
organizationEventManager.trackEvent(
|
||||
event = OrganizationEvent.CipherClientToggledHiddenFieldVisible(
|
||||
cipherId = "vault_item_id",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `TooltipClick should emit NavigateToToolTipUri`() = runTest {
|
||||
viewModel.eventFlow.test {
|
||||
|
|
Loading…
Reference in a new issue