mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 10:48:47 +03:00
Refactored VaultAddItem UI State (#417)
This commit is contained in:
parent
acdce7a07b
commit
772d6693a6
13 changed files with 1007 additions and 1855 deletions
|
@ -20,11 +20,11 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
*/
|
||||
@Composable
|
||||
fun AddEditItemContent(
|
||||
viewState: VaultAddItemState.ViewState.Content,
|
||||
state: VaultAddItemState.ViewState.Content,
|
||||
isAddItemMode: Boolean,
|
||||
onTypeOptionClicked: (VaultAddItemState.ItemTypeOption) -> Unit,
|
||||
commonTypeHandlers: VaultAddItemCommonTypeHandlers,
|
||||
loginItemTypeHandlers: VaultAddLoginItemTypeHandlers,
|
||||
secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LazyColumn(
|
||||
|
@ -42,35 +42,37 @@ fun AddEditItemContent(
|
|||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
TypeOptionsItem(
|
||||
content = viewState,
|
||||
itemType = state.type,
|
||||
onTypeOptionClicked = onTypeOptionClicked,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
when (viewState) {
|
||||
is VaultAddItemState.ViewState.Content.Login -> {
|
||||
when (state.type) {
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Login -> {
|
||||
addEditLoginItems(
|
||||
state = viewState,
|
||||
commonState = state.common,
|
||||
loginState = state.type,
|
||||
isAddItemMode = isAddItemMode,
|
||||
commonActionHandler = commonTypeHandlers,
|
||||
loginItemTypeHandlers = loginItemTypeHandlers,
|
||||
)
|
||||
}
|
||||
|
||||
is VaultAddItemState.ViewState.Content.Card -> {
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Card -> {
|
||||
// TODO(BIT-507): Create UI for card-type item creation
|
||||
}
|
||||
|
||||
is VaultAddItemState.ViewState.Content.Identity -> {
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Identity -> {
|
||||
// TODO(BIT-667): Create UI for identity-type item creation
|
||||
}
|
||||
|
||||
is VaultAddItemState.ViewState.Content.SecureNotes -> {
|
||||
is VaultAddItemState.ViewState.Content.ItemType.SecureNotes -> {
|
||||
addEditSecureNotesItems(
|
||||
state = viewState,
|
||||
commonState = state.common,
|
||||
isAddItemMode = isAddItemMode,
|
||||
secureNotesTypeHandlers = secureNotesTypeHandlers,
|
||||
commonTypeHandlers = commonTypeHandlers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +85,7 @@ fun AddEditItemContent(
|
|||
|
||||
@Composable
|
||||
private fun TypeOptionsItem(
|
||||
content: VaultAddItemState.ViewState.Content,
|
||||
itemType: VaultAddItemState.ViewState.Content.ItemType,
|
||||
onTypeOptionClicked: (VaultAddItemState.ItemTypeOption) -> Unit,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
|
@ -93,7 +95,7 @@ private fun TypeOptionsItem(
|
|||
BitwardenMultiSelectButton(
|
||||
label = stringResource(id = R.string.type),
|
||||
options = optionsWithStrings.values.toImmutableList(),
|
||||
selectedOption = stringResource(id = content.displayStringResId),
|
||||
selectedOption = stringResource(id = itemType.displayStringResId),
|
||||
onOptionSelected = { selectedOption ->
|
||||
val selectedOptionId = optionsWithStrings
|
||||
.entries
|
||||
|
|
|
@ -34,16 +34,18 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
*/
|
||||
@Suppress("LongMethod")
|
||||
fun LazyListScope.addEditLoginItems(
|
||||
state: VaultAddItemState.ViewState.Content.Login,
|
||||
commonState: VaultAddItemState.ViewState.Content.Common,
|
||||
loginState: VaultAddItemState.ViewState.Content.ItemType.Login,
|
||||
isAddItemMode: Boolean,
|
||||
commonActionHandler: VaultAddItemCommonTypeHandlers,
|
||||
loginItemTypeHandlers: VaultAddLoginItemTypeHandlers,
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.name),
|
||||
value = state.name,
|
||||
onValueChange = loginItemTypeHandlers.onNameTextChange,
|
||||
value = commonState.name,
|
||||
onValueChange = commonActionHandler.onNameTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -54,7 +56,7 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextFieldWithActions(
|
||||
label = stringResource(id = R.string.username),
|
||||
value = state.username,
|
||||
value = loginState.username,
|
||||
onValueChange = loginItemTypeHandlers.onUsernameTextChange,
|
||||
actions = {
|
||||
BitwardenIconButtonWithResource(
|
||||
|
@ -73,7 +75,7 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenPasswordFieldWithActions(
|
||||
label = stringResource(id = R.string.password),
|
||||
value = state.password,
|
||||
value = loginState.password,
|
||||
onValueChange = loginItemTypeHandlers.onPasswordTextChange,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -131,7 +133,7 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextFieldWithActions(
|
||||
label = stringResource(id = R.string.uri),
|
||||
value = state.uri,
|
||||
value = loginState.uri,
|
||||
onValueChange = loginItemTypeHandlers.onUriTextChange,
|
||||
actions = {
|
||||
BitwardenIconButtonWithResource(
|
||||
|
@ -171,9 +173,9 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenMultiSelectButton(
|
||||
label = stringResource(id = R.string.folder),
|
||||
options = state.availableFolders.map { it.invoke() }.toImmutableList(),
|
||||
selectedOption = state.folderName.invoke(),
|
||||
onOptionSelected = loginItemTypeHandlers.onFolderTextChange,
|
||||
options = commonState.availableFolders.map { it.invoke() }.toImmutableList(),
|
||||
selectedOption = commonState.folderName.invoke(),
|
||||
onOptionSelected = commonActionHandler.onFolderTextChange,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
|
@ -184,8 +186,8 @@ fun LazyListScope.addEditLoginItems(
|
|||
label = stringResource(
|
||||
id = R.string.favorite,
|
||||
),
|
||||
isChecked = state.favorite,
|
||||
onCheckedChange = loginItemTypeHandlers.onToggleFavorite,
|
||||
isChecked = commonState.favorite,
|
||||
onCheckedChange = commonActionHandler.onToggleFavorite,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -196,13 +198,13 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenSwitchWithActions(
|
||||
label = stringResource(id = R.string.password_prompt),
|
||||
isChecked = state.masterPasswordReprompt,
|
||||
onCheckedChange = loginItemTypeHandlers.onToggleMasterPasswordReprompt,
|
||||
isChecked = commonState.masterPasswordReprompt,
|
||||
onCheckedChange = commonActionHandler.onToggleMasterPasswordReprompt,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
actions = {
|
||||
IconButton(onClick = loginItemTypeHandlers.onTooltipClick) {
|
||||
IconButton(onClick = commonActionHandler.onTooltipClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_tooltip),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
|
@ -230,8 +232,8 @@ fun LazyListScope.addEditLoginItems(
|
|||
BitwardenTextField(
|
||||
singleLine = false,
|
||||
label = stringResource(id = R.string.notes),
|
||||
value = state.notes,
|
||||
onValueChange = loginItemTypeHandlers.onNotesTextChange,
|
||||
value = commonState.notes,
|
||||
onValueChange = commonActionHandler.onNotesTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -248,10 +250,10 @@ fun LazyListScope.addEditLoginItems(
|
|||
)
|
||||
}
|
||||
|
||||
items(state.customFieldData) { customItem ->
|
||||
items(commonState.customFieldData) { customItem ->
|
||||
AddEditCustomField(
|
||||
customItem,
|
||||
onCustomFieldValueChange = loginItemTypeHandlers.onCustomFieldValueChange,
|
||||
onCustomFieldValueChange = commonActionHandler.onCustomFieldValueChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -265,7 +267,7 @@ fun LazyListScope.addEditLoginItems(
|
|||
item {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
AddEditCustomFieldsButton(
|
||||
onFinishNamingClick = loginItemTypeHandlers.onAddNewCustomFieldClick,
|
||||
onFinishNamingClick = commonActionHandler.onAddNewCustomFieldClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -287,9 +289,9 @@ fun LazyListScope.addEditLoginItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenMultiSelectButton(
|
||||
label = stringResource(id = R.string.who_owns_this_item),
|
||||
options = state.availableOwners.toImmutableList(),
|
||||
selectedOption = state.ownership,
|
||||
onOptionSelected = loginItemTypeHandlers.onOwnershipTextChange,
|
||||
options = commonState.availableOwners.toImmutableList(),
|
||||
selectedOption = commonState.ownership,
|
||||
onOptionSelected = commonActionHandler.onOwnershipTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
|
|
@ -28,16 +28,16 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
*/
|
||||
@Suppress("LongMethod")
|
||||
fun LazyListScope.addEditSecureNotesItems(
|
||||
state: VaultAddItemState.ViewState.Content.SecureNotes,
|
||||
commonState: VaultAddItemState.ViewState.Content.Common,
|
||||
isAddItemMode: Boolean,
|
||||
secureNotesTypeHandlers: VaultAddSecureNotesItemTypeHandlers,
|
||||
commonTypeHandlers: VaultAddItemCommonTypeHandlers,
|
||||
) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.name),
|
||||
value = state.name,
|
||||
onValueChange = secureNotesTypeHandlers.onNameTextChange,
|
||||
value = commonState.name,
|
||||
onValueChange = commonTypeHandlers.onNameTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -58,9 +58,9 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenMultiSelectButton(
|
||||
label = stringResource(id = R.string.folder),
|
||||
options = state.availableFolders.map { it.invoke() }.toImmutableList(),
|
||||
selectedOption = state.folderName.invoke(),
|
||||
onOptionSelected = secureNotesTypeHandlers.onFolderTextChange,
|
||||
options = commonState.availableFolders.map { it.invoke() }.toImmutableList(),
|
||||
selectedOption = commonState.folderName.invoke(),
|
||||
onOptionSelected = commonTypeHandlers.onFolderTextChange,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
|
@ -70,8 +70,8 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenSwitch(
|
||||
label = stringResource(id = R.string.favorite),
|
||||
isChecked = state.favorite,
|
||||
onCheckedChange = secureNotesTypeHandlers.onToggleFavorite,
|
||||
isChecked = commonState.favorite,
|
||||
onCheckedChange = commonTypeHandlers.onToggleFavorite,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -82,13 +82,13 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
Spacer(modifier = Modifier.height(16.dp))
|
||||
BitwardenSwitchWithActions(
|
||||
label = stringResource(id = R.string.password_prompt),
|
||||
isChecked = state.masterPasswordReprompt,
|
||||
onCheckedChange = secureNotesTypeHandlers.onToggleMasterPasswordReprompt,
|
||||
isChecked = commonState.masterPasswordReprompt,
|
||||
onCheckedChange = commonTypeHandlers.onToggleMasterPasswordReprompt,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
actions = {
|
||||
IconButton(onClick = secureNotesTypeHandlers.onTooltipClick) {
|
||||
IconButton(onClick = commonTypeHandlers.onTooltipClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_tooltip),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
|
@ -116,8 +116,8 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
BitwardenTextField(
|
||||
singleLine = false,
|
||||
label = stringResource(id = R.string.notes),
|
||||
value = state.notes,
|
||||
onValueChange = secureNotesTypeHandlers.onNotesTextChange,
|
||||
value = commonState.notes,
|
||||
onValueChange = commonTypeHandlers.onNotesTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -133,11 +133,10 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
|
||||
items(state.customFieldData) { customItem ->
|
||||
items(commonState.customFieldData) { customItem ->
|
||||
AddEditCustomField(
|
||||
customItem,
|
||||
onCustomFieldValueChange = secureNotesTypeHandlers.onCustomFieldValueChange,
|
||||
onCustomFieldValueChange = commonTypeHandlers.onCustomFieldValueChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
@ -147,7 +146,7 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
item {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
AddEditCustomFieldsButton(
|
||||
onFinishNamingClick = secureNotesTypeHandlers.onAddNewCustomFieldClick,
|
||||
onFinishNamingClick = commonTypeHandlers.onAddNewCustomFieldClick,
|
||||
options = persistentListOf(
|
||||
CustomFieldType.TEXT,
|
||||
CustomFieldType.HIDDEN,
|
||||
|
@ -174,9 +173,9 @@ fun LazyListScope.addEditSecureNotesItems(
|
|||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BitwardenMultiSelectButton(
|
||||
label = stringResource(id = R.string.who_owns_this_item),
|
||||
options = state.availableOwners.toImmutableList(),
|
||||
selectedOption = state.ownership,
|
||||
onOptionSelected = secureNotesTypeHandlers.onOwnershipTextChange,
|
||||
options = commonState.availableOwners.toImmutableList(),
|
||||
selectedOption = commonState.ownership,
|
||||
onOptionSelected = commonTypeHandlers.onOwnershipTextChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
|
|
|
@ -4,8 +4,8 @@ import com.x8bit.bitwarden.ui.platform.base.util.asText
|
|||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
|
||||
/**
|
||||
* A collection of handler functions specifically tailored for managing actions
|
||||
* within the context of adding secure note items to a vault.
|
||||
* A collection of handler functions for managing actions common
|
||||
* within the context of adding items to a vault.
|
||||
*
|
||||
* @property onNameTextChange Handles the action when the name text is changed.
|
||||
* @property onFolderTextChange Handles the action when the folder text is changed.
|
||||
|
@ -20,7 +20,7 @@ import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
|||
* @property onCustomFieldValueChange Handles the action when the field's value changes
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
class VaultAddSecureNotesItemTypeHandlers(
|
||||
class VaultAddItemCommonTypeHandlers(
|
||||
val onNameTextChange: (String) -> Unit,
|
||||
val onFolderTextChange: (String) -> Unit,
|
||||
val onToggleFavorite: (Boolean) -> Unit,
|
||||
|
@ -34,54 +34,54 @@ class VaultAddSecureNotesItemTypeHandlers(
|
|||
companion object {
|
||||
|
||||
/**
|
||||
* Creates an instance of [VaultAddSecureNotesItemTypeHandlers] by binding actions
|
||||
* Creates an instance of [VaultAddItemCommonTypeHandlers] by binding actions
|
||||
* to the provided [VaultAddItemViewModel].
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
fun create(viewModel: VaultAddItemViewModel): VaultAddSecureNotesItemTypeHandlers {
|
||||
return VaultAddSecureNotesItemTypeHandlers(
|
||||
fun create(viewModel: VaultAddItemViewModel): VaultAddItemCommonTypeHandlers {
|
||||
return VaultAddItemCommonTypeHandlers(
|
||||
onNameTextChange = { newName ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.NameTextChange(newName),
|
||||
VaultAddItemAction.Common.NameTextChange(newName),
|
||||
)
|
||||
},
|
||||
onFolderTextChange = { newFolder ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.FolderChange(
|
||||
VaultAddItemAction.Common.FolderChange(
|
||||
newFolder.asText(),
|
||||
),
|
||||
)
|
||||
},
|
||||
onToggleFavorite = { isFavorite ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.ToggleFavorite(isFavorite),
|
||||
VaultAddItemAction.Common.ToggleFavorite(isFavorite),
|
||||
)
|
||||
},
|
||||
onToggleMasterPasswordReprompt = { isMasterPasswordReprompt ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.ToggleMasterPasswordReprompt(
|
||||
VaultAddItemAction.Common.ToggleMasterPasswordReprompt(
|
||||
isMasterPasswordReprompt,
|
||||
),
|
||||
)
|
||||
},
|
||||
onNotesTextChange = { newNotes ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.NotesTextChange(newNotes),
|
||||
VaultAddItemAction.Common.NotesTextChange(newNotes),
|
||||
)
|
||||
},
|
||||
onOwnershipTextChange = { newOwnership ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.OwnershipChange(newOwnership),
|
||||
VaultAddItemAction.Common.OwnershipChange(newOwnership),
|
||||
)
|
||||
},
|
||||
onTooltipClick = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.TooltipClick,
|
||||
VaultAddItemAction.Common.TooltipClick,
|
||||
)
|
||||
},
|
||||
onAddNewCustomFieldClick = { newCustomFieldType, name ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
VaultAddItemAction.Common.AddNewCustomFieldClick(
|
||||
newCustomFieldType,
|
||||
name,
|
||||
),
|
||||
|
@ -89,7 +89,7 @@ class VaultAddSecureNotesItemTypeHandlers(
|
|||
},
|
||||
onCustomFieldValueChange = { newValue ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemAction.Common.CustomFieldValueChange(
|
||||
newValue,
|
||||
),
|
||||
)
|
|
@ -55,14 +55,14 @@ fun VaultAddItemScreen(
|
|||
VaultAddLoginItemTypeHandlers.create(viewModel = viewModel)
|
||||
}
|
||||
|
||||
val secureNotesTypeHandlers = remember(viewModel) {
|
||||
VaultAddSecureNotesItemTypeHandlers.create(viewModel = viewModel)
|
||||
val commonTypeHandlers = remember(viewModel) {
|
||||
VaultAddItemCommonTypeHandlers.create(viewModel = viewModel)
|
||||
}
|
||||
|
||||
VaultAddEditItemDialogs(
|
||||
dialogState = state.dialog,
|
||||
onDismissRequest = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAddItemAction.DismissDialog) }
|
||||
{ viewModel.trySendAction(VaultAddItemAction.Common.DismissDialog) }
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -77,14 +77,14 @@ fun VaultAddItemScreen(
|
|||
navigationIcon = painterResource(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAddItemAction.CloseClick) }
|
||||
{ viewModel.trySendAction(VaultAddItemAction.Common.CloseClick) }
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
actions = {
|
||||
BitwardenTextButton(
|
||||
label = stringResource(id = R.string.save),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAddItemAction.SaveClick) }
|
||||
{ viewModel.trySendAction(VaultAddItemAction.Common.SaveClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -94,13 +94,13 @@ fun VaultAddItemScreen(
|
|||
when (val viewState = state.viewState) {
|
||||
is VaultAddItemState.ViewState.Content -> {
|
||||
AddEditItemContent(
|
||||
viewState = viewState,
|
||||
state = viewState,
|
||||
isAddItemMode = state.isAddItemMode,
|
||||
onTypeOptionClicked = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAddItemAction.TypeOptionSelect(it)) }
|
||||
{ viewModel.trySendAction(VaultAddItemAction.Common.TypeOptionSelect(it)) }
|
||||
},
|
||||
loginItemTypeHandlers = loginItemTypeHandlers,
|
||||
secureNotesTypeHandlers = secureNotesTypeHandlers,
|
||||
commonTypeHandlers = commonTypeHandlers,
|
||||
modifier = Modifier
|
||||
.imePadding()
|
||||
.padding(innerPadding)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,22 +1,13 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.additem
|
||||
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
|
||||
/**
|
||||
* A collection of handler functions specifically tailored for managing actions
|
||||
* within the context of adding login items to a vault.
|
||||
*
|
||||
* @property onNameTextChange Handles the action when the name text is changed.
|
||||
* @property onUsernameTextChange Handles the action when the username text is changed.
|
||||
* @property onPasswordTextChange Handles the action when the password text is changed.
|
||||
* @property onUriTextChange Handles the action when the URI text is changed.
|
||||
* @property onFolderTextChange Handles the action when the folder text is changed.
|
||||
* @property onToggleFavorite Handles the action when the favorite toggle is changed.
|
||||
* @property onToggleMasterPasswordReprompt Handles the action when the master password
|
||||
* reprompt toggle is changed.
|
||||
* @property onNotesTextChange Handles the action when the notes text is changed.
|
||||
* @property onOwnershipTextChange Handles the action when the ownership text is changed.
|
||||
* @property onOpenUsernameGeneratorClick Handles the action when the username generator
|
||||
* button is clicked.
|
||||
* @property onPasswordCheckerClick Handles the action when the password checker
|
||||
|
@ -26,31 +17,18 @@ import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
|||
* @property onSetupTotpClick Handles the action when the setup TOTP button is clicked.
|
||||
* @property onUriSettingsClick Handles the action when the URI settings button is clicked.
|
||||
* @property onAddNewUriClick Handles the action when the add new URI button is clicked.
|
||||
* @property onTooltipClick Handles the action when the tooltip button is clicked.
|
||||
* @property onAddNewCustomFieldClick Handles the action when the add new custom field
|
||||
* button is clicked.
|
||||
* @property onCustomFieldValueChange Handles the action when the field's value changes
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
class VaultAddLoginItemTypeHandlers(
|
||||
val onNameTextChange: (String) -> Unit,
|
||||
val onUsernameTextChange: (String) -> Unit,
|
||||
val onPasswordTextChange: (String) -> Unit,
|
||||
val onUriTextChange: (String) -> Unit,
|
||||
val onFolderTextChange: (String) -> Unit,
|
||||
val onToggleFavorite: (Boolean) -> Unit,
|
||||
val onToggleMasterPasswordReprompt: (Boolean) -> Unit,
|
||||
val onNotesTextChange: (String) -> Unit,
|
||||
val onOwnershipTextChange: (String) -> Unit,
|
||||
val onOpenUsernameGeneratorClick: () -> Unit,
|
||||
val onPasswordCheckerClick: () -> Unit,
|
||||
val onOpenPasswordGeneratorClick: () -> Unit,
|
||||
val onSetupTotpClick: () -> Unit,
|
||||
val onUriSettingsClick: () -> Unit,
|
||||
val onAddNewUriClick: () -> Unit,
|
||||
val onTooltipClick: () -> Unit,
|
||||
val onAddNewCustomFieldClick: (CustomFieldType, String) -> Unit,
|
||||
val onCustomFieldValueChange: (VaultAddItemState.Custom) -> Unit,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
|
@ -64,11 +42,6 @@ class VaultAddLoginItemTypeHandlers(
|
|||
@Suppress("LongMethod")
|
||||
fun create(viewModel: VaultAddItemViewModel): VaultAddLoginItemTypeHandlers {
|
||||
return VaultAddLoginItemTypeHandlers(
|
||||
onNameTextChange = { newName ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.NameTextChange(newName),
|
||||
)
|
||||
},
|
||||
onUsernameTextChange = { newUsername ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.UsernameTextChange(newUsername),
|
||||
|
@ -84,33 +57,6 @@ class VaultAddLoginItemTypeHandlers(
|
|||
VaultAddItemAction.ItemType.LoginType.UriTextChange(newUri),
|
||||
)
|
||||
},
|
||||
onFolderTextChange = { newFolder ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.FolderChange(newFolder.asText()),
|
||||
)
|
||||
},
|
||||
onToggleFavorite = { isFavorite ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.ToggleFavorite(isFavorite),
|
||||
)
|
||||
},
|
||||
onToggleMasterPasswordReprompt = { isMasterPasswordReprompt ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.ToggleMasterPasswordReprompt(
|
||||
isMasterPasswordReprompt,
|
||||
),
|
||||
)
|
||||
},
|
||||
onNotesTextChange = { newNotes ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.NotesTextChange(newNotes),
|
||||
)
|
||||
},
|
||||
onOwnershipTextChange = { newOwnership ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.OwnershipChange(newOwnership),
|
||||
)
|
||||
},
|
||||
onOpenUsernameGeneratorClick = {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.OpenUsernameGeneratorClick,
|
||||
|
@ -135,24 +81,6 @@ class VaultAddLoginItemTypeHandlers(
|
|||
onAddNewUriClick = {
|
||||
viewModel.trySendAction(VaultAddItemAction.ItemType.LoginType.AddNewUriClick)
|
||||
},
|
||||
onTooltipClick = {
|
||||
viewModel.trySendAction(VaultAddItemAction.ItemType.LoginType.TooltipClick)
|
||||
},
|
||||
onAddNewCustomFieldClick = { customFieldType, name ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = customFieldType,
|
||||
name = name,
|
||||
),
|
||||
)
|
||||
},
|
||||
onCustomFieldValueChange = { customField ->
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
customField = customField,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,55 +15,36 @@ import java.util.UUID
|
|||
* Transforms [CipherView] into [VaultAddItemState.ViewState].
|
||||
*/
|
||||
fun CipherView.toViewState(): VaultAddItemState.ViewState =
|
||||
when (type) {
|
||||
CipherType.LOGIN -> {
|
||||
val loginView = requireNotNull(this.login)
|
||||
VaultAddItemState.ViewState.Content.Login(
|
||||
originalCipher = this,
|
||||
name = this.name,
|
||||
username = loginView.username.orEmpty(),
|
||||
password = loginView.password.orEmpty(),
|
||||
uri = loginView.uris?.firstOrNull()?.uri.orEmpty(),
|
||||
favorite = this.favorite,
|
||||
masterPasswordReprompt = this.reprompt == CipherRepromptType.PASSWORD,
|
||||
notes = this.notes.orEmpty(),
|
||||
// TODO: Update these properties to pull folder from data layer (BIT-501)
|
||||
folderName = this.folderId?.asText() ?: R.string.folder_none.asText(),
|
||||
availableFolders = emptyList(),
|
||||
// TODO: Update this property to pull owner from data layer (BIT-501)
|
||||
ownership = "",
|
||||
// TODO: Update this property to pull available owners from data layer (BIT-501)
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = this.fields.orEmpty().map { it.toCustomField() },
|
||||
)
|
||||
}
|
||||
VaultAddItemState.ViewState.Content(
|
||||
type = when (type) {
|
||||
CipherType.LOGIN -> {
|
||||
VaultAddItemState.ViewState.Content.ItemType.Login(
|
||||
username = login?.username.orEmpty(),
|
||||
password = login?.password.orEmpty(),
|
||||
uri = login?.uris?.firstOrNull()?.uri.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
CipherType.SECURE_NOTE -> {
|
||||
VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
originalCipher = this,
|
||||
name = this.name,
|
||||
favorite = this.favorite,
|
||||
masterPasswordReprompt = this.reprompt == CipherRepromptType.PASSWORD,
|
||||
notes = this.notes.orEmpty(),
|
||||
// TODO: Update these properties to pull folder from data layer (BIT-501)
|
||||
folderName = this.folderId?.asText() ?: R.string.folder_none.asText(),
|
||||
availableFolders = emptyList(),
|
||||
// TODO: Update this property to pull owner from data layer (BIT-501)
|
||||
ownership = "",
|
||||
// TODO: Update this property to pull available owners from data layer (BIT-501)
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = this.fields.orEmpty().map { it.toCustomField() },
|
||||
)
|
||||
}
|
||||
|
||||
CipherType.CARD -> VaultAddItemState.ViewState.Error(
|
||||
message = "Not yet implemented.".asText(),
|
||||
)
|
||||
|
||||
CipherType.IDENTITY -> VaultAddItemState.ViewState.Error(
|
||||
message = "Not yet implemented.".asText(),
|
||||
)
|
||||
}
|
||||
CipherType.SECURE_NOTE -> VaultAddItemState.ViewState.Content.ItemType.SecureNotes
|
||||
CipherType.CARD -> VaultAddItemState.ViewState.Content.ItemType.Card
|
||||
CipherType.IDENTITY -> VaultAddItemState.ViewState.Content.ItemType.Identity
|
||||
},
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = this,
|
||||
name = this.name,
|
||||
favorite = this.favorite,
|
||||
masterPasswordReprompt = this.reprompt == CipherRepromptType.PASSWORD,
|
||||
notes = this.notes.orEmpty(),
|
||||
// TODO: Update these properties to pull folder from data layer (BIT-501)
|
||||
folderName = this.folderId?.asText() ?: R.string.folder_none.asText(),
|
||||
availableFolders = emptyList(),
|
||||
// TODO: Update this property to pull owner from data layer (BIT-501)
|
||||
ownership = "",
|
||||
// TODO: Update this property to pull available owners from data layer (BIT-501)
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = this.fields.orEmpty().map { it.toCustomField() },
|
||||
),
|
||||
)
|
||||
|
||||
private fun FieldView.toCustomField() =
|
||||
when (this.type) {
|
||||
|
|
|
@ -100,53 +100,53 @@ fun VaultData.toViewState(): VaultState.ViewState =
|
|||
}
|
||||
|
||||
/**
|
||||
* Transforms a [VaultAddItemState.ViewState.Content] into [CipherView].
|
||||
* Transforms a [VaultAddItemState.ViewState.ItemType] into [CipherView].
|
||||
*/
|
||||
fun VaultAddItemState.ViewState.Content.toCipherView(): CipherView =
|
||||
CipherView(
|
||||
// Pulled from original cipher when editing, otherwise uses defaults
|
||||
id = this.originalCipher?.id,
|
||||
collectionIds = this.originalCipher?.collectionIds.orEmpty(),
|
||||
key = this.originalCipher?.key,
|
||||
edit = this.originalCipher?.edit ?: true,
|
||||
viewPassword = this.originalCipher?.viewPassword ?: true,
|
||||
localData = this.originalCipher?.localData,
|
||||
attachments = this.originalCipher?.attachments,
|
||||
organizationUseTotp = this.originalCipher?.organizationUseTotp ?: false,
|
||||
passwordHistory = this.originalCipher?.passwordHistory,
|
||||
creationDate = this.originalCipher?.creationDate ?: Instant.now(),
|
||||
deletedDate = this.originalCipher?.deletedDate,
|
||||
revisionDate = this.originalCipher?.revisionDate ?: Instant.now(),
|
||||
id = common.originalCipher?.id,
|
||||
collectionIds = common.originalCipher?.collectionIds.orEmpty(),
|
||||
key = common.originalCipher?.key,
|
||||
edit = common.originalCipher?.edit ?: true,
|
||||
viewPassword = common.originalCipher?.viewPassword ?: true,
|
||||
localData = common.originalCipher?.localData,
|
||||
attachments = common.originalCipher?.attachments,
|
||||
organizationUseTotp = common.originalCipher?.organizationUseTotp ?: false,
|
||||
passwordHistory = common.originalCipher?.passwordHistory,
|
||||
creationDate = common.originalCipher?.creationDate ?: Instant.now(),
|
||||
deletedDate = common.originalCipher?.deletedDate,
|
||||
revisionDate = common.originalCipher?.revisionDate ?: Instant.now(),
|
||||
|
||||
// Type specific section
|
||||
type = this.toCipherType(),
|
||||
identity = this.toIdentityView(),
|
||||
secureNote = this.toSecureNotesView(),
|
||||
login = this.toLoginView(),
|
||||
card = this.toCardView(),
|
||||
type = type.toCipherType(),
|
||||
identity = type.toIdentityView(),
|
||||
secureNote = type.toSecureNotesView(),
|
||||
login = type.toLoginView(common = common),
|
||||
card = type.toCardView(),
|
||||
|
||||
// Fields we always grab from the UI
|
||||
name = this.name,
|
||||
notes = this.notes,
|
||||
favorite = this.favorite,
|
||||
name = common.name,
|
||||
notes = common.notes,
|
||||
favorite = common.favorite,
|
||||
// TODO Use real folder ID (BIT-528)
|
||||
folderId = this.originalCipher?.folderId,
|
||||
folderId = common.originalCipher?.folderId,
|
||||
// TODO Use real organization ID (BIT-780)
|
||||
organizationId = this.originalCipher?.organizationId,
|
||||
reprompt = this.toCipherRepromptType(),
|
||||
fields = this.customFieldData.map { it.toFieldView() },
|
||||
organizationId = common.originalCipher?.organizationId,
|
||||
reprompt = common.toCipherRepromptType(),
|
||||
fields = common.customFieldData.map { it.toFieldView() },
|
||||
)
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toCipherType(): CipherType =
|
||||
private fun VaultAddItemState.ViewState.Content.ItemType.toCipherType(): CipherType =
|
||||
when (this) {
|
||||
is VaultAddItemState.ViewState.Content.Card -> CipherType.CARD
|
||||
is VaultAddItemState.ViewState.Content.Identity -> CipherType.IDENTITY
|
||||
is VaultAddItemState.ViewState.Content.Login -> CipherType.LOGIN
|
||||
is VaultAddItemState.ViewState.Content.SecureNotes -> CipherType.SECURE_NOTE
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Card -> CipherType.CARD
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Identity -> CipherType.IDENTITY
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Login -> CipherType.LOGIN
|
||||
is VaultAddItemState.ViewState.Content.ItemType.SecureNotes -> CipherType.SECURE_NOTE
|
||||
}
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toCardView(): CardView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.Card)?.let {
|
||||
private fun VaultAddItemState.ViewState.Content.ItemType.toCardView(): CardView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.ItemType.Card)?.let {
|
||||
// TODO Create real CardView from Content (BIT-668)
|
||||
CardView(
|
||||
cardholderName = null,
|
||||
|
@ -158,8 +158,8 @@ private fun VaultAddItemState.ViewState.Content.toCardView(): CardView? =
|
|||
)
|
||||
}
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toIdentityView(): IdentityView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.Identity)?.let {
|
||||
private fun VaultAddItemState.ViewState.Content.ItemType.toIdentityView(): IdentityView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.ItemType.Identity)?.let {
|
||||
// TODO Create real IdentityView from Content (BIT-508)
|
||||
IdentityView(
|
||||
title = null,
|
||||
|
@ -183,12 +183,14 @@ private fun VaultAddItemState.ViewState.Content.toIdentityView(): IdentityView?
|
|||
)
|
||||
}
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toLoginView(): LoginView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.Login)?.let {
|
||||
private fun VaultAddItemState.ViewState.Content.ItemType.toLoginView(
|
||||
common: VaultAddItemState.ViewState.Content.Common,
|
||||
): LoginView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.ItemType.Login)?.let {
|
||||
LoginView(
|
||||
username = it.username,
|
||||
password = it.password,
|
||||
passwordRevisionDate = it.originalCipher?.login?.passwordRevisionDate,
|
||||
passwordRevisionDate = common.originalCipher?.login?.passwordRevisionDate,
|
||||
uris = listOf(
|
||||
// TODO Implement URI list (BIT-1094)
|
||||
LoginUriView(
|
||||
|
@ -198,18 +200,18 @@ private fun VaultAddItemState.ViewState.Content.toLoginView(): LoginView? =
|
|||
),
|
||||
),
|
||||
// TODO Implement TOTP (BIT-1066)
|
||||
totp = it.originalCipher?.login?.totp,
|
||||
autofillOnPageLoad = it.originalCipher?.login?.autofillOnPageLoad,
|
||||
totp = common.originalCipher?.login?.totp,
|
||||
autofillOnPageLoad = common.originalCipher?.login?.autofillOnPageLoad,
|
||||
)
|
||||
}
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toSecureNotesView(): SecureNoteView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.SecureNotes)?.let {
|
||||
private fun VaultAddItemState.ViewState.Content.ItemType.toSecureNotesView(): SecureNoteView? =
|
||||
(this as? VaultAddItemState.ViewState.Content.ItemType.SecureNotes)?.let {
|
||||
SecureNoteView(type = SecureNoteType.GENERIC)
|
||||
}
|
||||
|
||||
private fun VaultAddItemState.ViewState.Content.toCipherRepromptType(): CipherRepromptType =
|
||||
if (this.masterPasswordReprompt) {
|
||||
private fun VaultAddItemState.ViewState.Content.Common.toCipherRepromptType(): CipherRepromptType =
|
||||
if (masterPasswordReprompt) {
|
||||
CipherRepromptType.PASSWORD
|
||||
} else {
|
||||
CipherRepromptType.NONE
|
||||
|
|
|
@ -31,7 +31,6 @@ import com.x8bit.bitwarden.ui.util.onNodeWithContentDescriptionAfterScroll
|
|||
import com.x8bit.bitwarden.ui.util.onNodeWithTextAfterScroll
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
|
@ -79,7 +78,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.CloseClick,
|
||||
VaultAddItemAction.Common.CloseClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +91,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.SaveClick,
|
||||
VaultAddItemAction.Common.SaveClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +107,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.DismissDialog,
|
||||
VaultAddItemAction.Common.DismissDialog,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +138,12 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
composeTestRule.onNodeWithText(message).assertIsNotDisplayed()
|
||||
|
||||
mutableStateFlow.update {
|
||||
it.copy(viewState = VaultAddItemState.ViewState.Content.Login())
|
||||
it.copy(
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(),
|
||||
),
|
||||
)
|
||||
}
|
||||
composeTestRule.onNodeWithText(message).assertIsNotDisplayed()
|
||||
|
||||
|
@ -162,7 +166,12 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
composeTestRule.onNode(isProgressBar).assertDoesNotExist()
|
||||
|
||||
mutableStateFlow.update {
|
||||
it.copy(viewState = VaultAddItemState.ViewState.Content.Login())
|
||||
it.copy(
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(),
|
||||
),
|
||||
)
|
||||
}
|
||||
composeTestRule.onNode(isProgressBar).assertDoesNotExist()
|
||||
}
|
||||
|
@ -183,7 +192,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.TypeOptionSelect(VaultAddItemState.ItemTypeOption.LOGIN),
|
||||
VaultAddItemAction.Common.TypeOptionSelect(VaultAddItemState.ItemTypeOption.LOGIN),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -194,41 +203,18 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.onNodeWithContentDescriptionAfterScroll(label = "Type, Login")
|
||||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { it.copy(viewState = VaultAddItemState.ViewState.Content.Card()) }
|
||||
mutableStateFlow.update { it.copy(
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Card,
|
||||
),
|
||||
) }
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Type, Card")
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state changing Name text field should trigger NameTextChange`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Name")
|
||||
.performTextInput(text = "TestName")
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.NameTextChange(name = "TestName"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login the name control should display the text provided by the state`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Name")
|
||||
.assertTextContains("")
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(name = "NewName") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "Name")
|
||||
.assertTextContains("NewName")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state changing Username text field should trigger UsernameTextChange`() {
|
||||
composeTestRule
|
||||
|
@ -399,191 +385,9 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking a Folder Option should send FolderChange action`() {
|
||||
// Opens the menu
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Folder, No Folder")
|
||||
.performClick()
|
||||
|
||||
// Choose the option from the menu
|
||||
composeTestRule
|
||||
.onAllNodesWithText(text = "Folder 1")
|
||||
.onLast()
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.FolderChange("Folder 1".asText()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login the folder control should display the text provided by the state`() {
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Folder, No Folder")
|
||||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(folderName = "Folder 2".asText()) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Folder, Folder 2")
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state, toggling the favorite toggle should send ToggleFavorite action`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Favorite")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.ToggleFavorite(
|
||||
isFavorite = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login the favorite toggle should be enabled or disabled according to state`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Favorite")
|
||||
.assertIsOff()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(favorite = true) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Favorite")
|
||||
.assertIsOn()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state, toggling the Master password re-prompt toggle should send ToggleMasterPasswordReprompt action`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Master password re-prompt")
|
||||
.performTouchInput {
|
||||
click(position = Offset(x = 1f, y = center.y))
|
||||
}
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.ToggleMasterPasswordReprompt(
|
||||
isMasterPasswordReprompt = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login the master password re-prompt toggle should be enabled or disabled according to state`() {
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Master password re-prompt")
|
||||
.assertIsOff()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(masterPasswordReprompt = true) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("Master password re-prompt")
|
||||
.assertIsOn()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state, toggling the Master password re-prompt tooltip button should send TooltipClick action`() {
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(label = "Master password re-prompt help")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.TooltipClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state changing Notes text field should trigger NotesTextChange`() {
|
||||
composeTestRule
|
||||
.onAllNodesWithTextAfterScroll("Notes")
|
||||
.filterToOne(hasSetTextAction())
|
||||
.performTextInput("TestNotes")
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.NotesTextChange("TestNotes"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login the Notes control should display the text provided by the state`() {
|
||||
composeTestRule
|
||||
.onAllNodesWithTextAfterScroll("Notes")
|
||||
.filterToOne(hasSetTextAction())
|
||||
.performTextInput("")
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(notes = "NewNote") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithTextAfterScroll("Notes")
|
||||
.filterToOne(hasSetTextAction())
|
||||
.assertTextContains("NewNote")
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Text type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Text")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestText")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.TEXT,
|
||||
name = "TestText",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Linked type`() {
|
||||
fun `clicking New Custom Field button should allow creation of Linked type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
|
@ -609,7 +413,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
VaultAddItemAction.Common.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.LINKED,
|
||||
name = "TestLinked",
|
||||
),
|
||||
|
@ -617,134 +421,8 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Boolean type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Boolean")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestBoolean")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.BOOLEAN,
|
||||
name = "TestBoolean",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Hidden type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Hidden")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestHidden")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.HIDDEN,
|
||||
name = "TestHidden",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestText")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom hidden field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestHidden")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom boolean field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestBoolean")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", true),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking a Ownership option should send OwnershipChange action`() {
|
||||
fun `clicking a Ownership option should send OwnershipChange action`() {
|
||||
// Opens the menu
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(
|
||||
|
@ -761,13 +439,13 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.OwnershipChange("a@b.com"),
|
||||
VaultAddItemAction.Common.OwnershipChange("a@b.com"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login the Ownership control should display the text provided by the state`() {
|
||||
fun `the Ownership control should display the text provided by the state`() {
|
||||
composeTestRule
|
||||
.onNodeWithContentDescriptionAfterScroll(
|
||||
label = "Who owns this item?, placeholder@email.com",
|
||||
|
@ -775,7 +453,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateLoginType(currentState) { copy(ownership = "Owner 2") }
|
||||
updateCommonContent(currentState) { copy(ownership = "Owner 2") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -784,7 +462,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state changing Name text field should trigger NameTextChange`() {
|
||||
fun `changing Name text field should trigger NameTextChange`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -793,13 +471,13 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.NameTextChange(name = "TestName"),
|
||||
VaultAddItemAction.Common.NameTextChange(name = "TestName"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the name control should display the text provided by the state`() {
|
||||
fun `the name control should display the text provided by the state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -807,7 +485,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertTextContains("")
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(name = "NewName") }
|
||||
updateCommonContent(currentState) { copy(name = "NewName") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -816,7 +494,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking a Folder Option should send FolderChange action`() {
|
||||
fun `clicking a Folder Option should send FolderChange action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
// Opens the menu
|
||||
|
@ -833,14 +511,14 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.FolderChange("Folder 1".asText()),
|
||||
VaultAddItemAction.Common.FolderChange("Folder 1".asText()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the folder control should display the text provided by the state`() {
|
||||
fun `the folder control should display the text provided by the state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -848,7 +526,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(folderName = "Folder 2".asText()) }
|
||||
updateCommonContent(currentState) { copy(folderName = "Folder 2".asText()) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -858,7 +536,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the favorite toggle should send ToggleFavorite action`() {
|
||||
fun `toggling the favorite toggle should send ToggleFavorite action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -867,16 +545,15 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.ToggleFavorite(
|
||||
VaultAddItemAction.Common.ToggleFavorite(
|
||||
isFavorite = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the favorite toggle should be enabled or disabled according to state`() {
|
||||
fun `the favorite toggle should be enabled or disabled according to state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -884,7 +561,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsOff()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(favorite = true) }
|
||||
updateCommonContent(currentState) { copy(favorite = true) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -894,7 +571,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the Master password re-prompt toggle should send ToggleMasterPasswordReprompt action`() {
|
||||
fun `toggling the Master password re-prompt toggle should send ToggleMasterPasswordReprompt action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -905,7 +582,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.ToggleMasterPasswordReprompt(
|
||||
VaultAddItemAction.Common.ToggleMasterPasswordReprompt(
|
||||
isMasterPasswordReprompt = true,
|
||||
),
|
||||
)
|
||||
|
@ -914,7 +591,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the master password re-prompt toggle should be enabled or disabled according to state`() {
|
||||
fun `the master password re-prompt toggle should be enabled or disabled according to state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -922,7 +599,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsOff()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(masterPasswordReprompt = true) }
|
||||
updateCommonContent(currentState) { copy(masterPasswordReprompt = true) }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -930,9 +607,8 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsOn()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the Master password re-prompt tooltip button should send TooltipClick action`() {
|
||||
fun `toggling the Master password re-prompt tooltip button should send TooltipClick action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -941,13 +617,13 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.TooltipClick,
|
||||
VaultAddItemAction.Common.TooltipClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state changing Notes text field should trigger NotesTextChange`() {
|
||||
fun `changing Notes text field should trigger NotesTextChange`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -957,14 +633,13 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.NotesTextChange("TestNotes"),
|
||||
VaultAddItemAction.Common.NotesTextChange("TestNotes"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the Notes control should display the text provided by the state`() {
|
||||
fun `the Notes control should display the text provided by the state`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -973,7 +648,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertTextContains("")
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(notes = "NewNote") }
|
||||
updateCommonContent(currentState) { copy(notes = "NewNote") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -984,7 +659,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking a Ownership option should send OwnershipChange action`() {
|
||||
fun `Ownership option should send OwnershipChange action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
// Opens the menu
|
||||
|
@ -1001,7 +676,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.OwnershipChange("a@b.com"),
|
||||
VaultAddItemAction.Common.OwnershipChange("a@b.com"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1016,7 +691,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { currentState ->
|
||||
updateSecureNotesType(currentState) { copy(ownership = "Owner 2") }
|
||||
updateCommonContent(currentState) { copy(ownership = "Owner 2") }
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
|
@ -1026,7 +701,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Text type`() {
|
||||
fun `clicking New Custom Field button should allow creation of Text type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -1052,7 +727,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
VaultAddItemAction.Common.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.TEXT,
|
||||
name = "TestText",
|
||||
),
|
||||
|
@ -1062,7 +737,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should not display linked type`() {
|
||||
fun `clicking New Custom Field button should not display linked type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -1081,7 +756,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Boolean type`() {
|
||||
fun `clicking New Custom Field button should allow creation of Boolean type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -1107,7 +782,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
VaultAddItemAction.Common.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.BOOLEAN,
|
||||
name = "TestBoolean",
|
||||
),
|
||||
|
@ -1115,9 +790,8 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Hidden type`() {
|
||||
fun `clicking New Custom Field button should allow creation of Hidden type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
|
@ -1144,7 +818,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
VaultAddItemAction.Common.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.HIDDEN,
|
||||
name = "TestHidden",
|
||||
),
|
||||
|
@ -1154,7 +828,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
fun `clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
|
@ -1163,7 +837,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemAction.Common.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", ""),
|
||||
),
|
||||
)
|
||||
|
@ -1172,7 +846,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom hidden field will send a CustomFieldValueChange event`() {
|
||||
fun `clicking and changing the custom hidden field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
|
@ -1181,7 +855,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemAction.Common.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", ""),
|
||||
),
|
||||
)
|
||||
|
@ -1190,7 +864,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom boolean field will send a CustomFieldValueChange event`() {
|
||||
fun `clicking and changing the custom boolean field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
|
@ -1199,7 +873,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemAction.Common.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", true),
|
||||
),
|
||||
)
|
||||
|
@ -1211,22 +885,34 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
@Suppress("MaxLineLength")
|
||||
private fun updateLoginType(
|
||||
currentState: VaultAddItemState,
|
||||
transform: VaultAddItemState.ViewState.Content.Login.() -> VaultAddItemState.ViewState.Content.Login,
|
||||
transform: VaultAddItemState.ViewState.Content.ItemType.Login.() ->
|
||||
VaultAddItemState.ViewState.Content.ItemType.Login,
|
||||
): VaultAddItemState {
|
||||
val updatedType = when (val viewState = currentState.viewState) {
|
||||
is VaultAddItemState.ViewState.Content.Login -> viewState.transform()
|
||||
is VaultAddItemState.ViewState.Content -> {
|
||||
when (val type = viewState.type) {
|
||||
is VaultAddItemState.ViewState.Content.ItemType.Login -> {
|
||||
viewState.copy(
|
||||
type = type.transform(),
|
||||
)
|
||||
}
|
||||
else -> viewState
|
||||
}
|
||||
}
|
||||
else -> viewState
|
||||
}
|
||||
return currentState.copy(viewState = updatedType)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
private fun updateSecureNotesType(
|
||||
private fun updateCommonContent(
|
||||
currentState: VaultAddItemState,
|
||||
transform: VaultAddItemState.ViewState.Content.SecureNotes.() -> VaultAddItemState.ViewState.Content.SecureNotes,
|
||||
transform: VaultAddItemState.ViewState.Content.Common.()
|
||||
-> VaultAddItemState.ViewState.Content.Common,
|
||||
): VaultAddItemState {
|
||||
val updatedType = when (val viewState = currentState.viewState) {
|
||||
is VaultAddItemState.ViewState.Content.SecureNotes -> viewState.transform()
|
||||
is VaultAddItemState.ViewState.Content ->
|
||||
viewState.copy(common = viewState.common.transform())
|
||||
else -> viewState
|
||||
}
|
||||
return currentState.copy(viewState = updatedType)
|
||||
|
@ -1235,42 +921,35 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
//endregion Helper functions
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STATE_LOGIN_CUSTOM_FIELDS = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", "TestTextVal"),
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", "TestHiddenVal"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"LinkedID",
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
),
|
||||
dialog = null,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_LOGIN_DIALOG = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(),
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(),
|
||||
),
|
||||
dialog = VaultAddItemState.DialogState.Error("test".asText()),
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_LOGIN = VaultAddItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(),
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(),
|
||||
),
|
||||
dialog = null,
|
||||
)
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
private val DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", "TestTextVal"),
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", "TestHiddenVal"),
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", "TestTextVal"),
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", "TestHiddenVal"),
|
||||
),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.SecureNotes,
|
||||
),
|
||||
dialog = null,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
|
@ -1278,7 +957,10 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
|
||||
private val DEFAULT_STATE_SECURE_NOTES = VaultAddItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
viewState = VaultAddItemState.ViewState.Content.SecureNotes(),
|
||||
viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.SecureNotes,
|
||||
),
|
||||
dialog = null,
|
||||
)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,30 @@ class CipherViewExtensionsTest {
|
|||
val result = cipherView.toViewState()
|
||||
|
||||
assertEquals(
|
||||
VaultAddItemState.ViewState.Error(message = "Not yet implemented.".asText()),
|
||||
VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
TEST_ID,
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Card,
|
||||
),
|
||||
result,
|
||||
)
|
||||
}
|
||||
|
@ -58,7 +81,30 @@ class CipherViewExtensionsTest {
|
|||
val result = cipherView.toViewState()
|
||||
|
||||
assertEquals(
|
||||
VaultAddItemState.ViewState.Error(message = "Not yet implemented.".asText()),
|
||||
VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
TEST_ID,
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Identity,
|
||||
),
|
||||
result,
|
||||
)
|
||||
}
|
||||
|
@ -70,29 +116,33 @@ class CipherViewExtensionsTest {
|
|||
val result = cipherView.toViewState()
|
||||
|
||||
assertEquals(
|
||||
VaultAddItemState.ViewState.Content.Login(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
username = "username",
|
||||
password = "password",
|
||||
uri = "www.example.com",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
TEST_ID,
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
TEST_ID,
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(
|
||||
username = "username",
|
||||
password = "password",
|
||||
uri = "www.example.com",
|
||||
),
|
||||
),
|
||||
result,
|
||||
)
|
||||
|
@ -105,21 +155,24 @@ class CipherViewExtensionsTest {
|
|||
val result = cipherView.toViewState()
|
||||
|
||||
assertEquals(
|
||||
VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "cipher",
|
||||
folderName = R.string.folder_none.asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
),
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
),
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.SecureNotes,
|
||||
),
|
||||
result,
|
||||
)
|
||||
|
|
|
@ -131,16 +131,20 @@ class VaultDataExtensionsTest {
|
|||
fun `toCipherView should transform Login ItemType to CipherView`() {
|
||||
mockkStatic(Instant::class)
|
||||
every { Instant.now() } returns Instant.MIN
|
||||
val loginItemType = VaultAddItemState.ViewState.Content.Login(
|
||||
name = "mockName-1",
|
||||
username = "mockUsername-1",
|
||||
password = "mockPassword-1",
|
||||
uri = "mockUri-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
val loginItemType = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(
|
||||
username = "mockUsername-1",
|
||||
password = "mockPassword-1",
|
||||
uri = "mockUri-1",
|
||||
),
|
||||
)
|
||||
|
||||
val result = loginItemType.toCipherView()
|
||||
|
@ -191,30 +195,34 @@ class VaultDataExtensionsTest {
|
|||
@Test
|
||||
fun `toCipherView should transform Login ItemType to CipherView with original cipher`() {
|
||||
val cipherView = DEFAULT_LOGIN_CIPHER_VIEW
|
||||
val loginItemType = VaultAddItemState.ViewState.Content.Login(
|
||||
originalCipher = cipherView,
|
||||
name = "mockName-1",
|
||||
username = "mockUsername-1",
|
||||
password = "mockPassword-1",
|
||||
uri = "mockUri-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = true,
|
||||
masterPasswordReprompt = false,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"testId",
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
val viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = true,
|
||||
masterPasswordReprompt = false,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"testId",
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.Login(
|
||||
username = "mockUsername-1",
|
||||
password = "mockPassword-1",
|
||||
uri = "mockUri-1",
|
||||
),
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
)
|
||||
|
||||
val result = loginItemType.toCipherView()
|
||||
val result = viewState.toCipherView()
|
||||
|
||||
assertEquals(
|
||||
@Suppress("MaxLineLength")
|
||||
|
@ -278,21 +286,24 @@ class VaultDataExtensionsTest {
|
|||
fun `toCipherView should transform SecureNotes ItemType to CipherView`() {
|
||||
mockkStatic(Instant::class)
|
||||
every { Instant.now() } returns Instant.MIN
|
||||
val secureNotesItemType = VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
val viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.SecureNotes,
|
||||
)
|
||||
|
||||
val result = secureNotesItemType.toCipherView()
|
||||
val result = viewState.toCipherView()
|
||||
|
||||
assertEquals(
|
||||
CipherView(
|
||||
|
@ -347,18 +358,21 @@ class VaultDataExtensionsTest {
|
|||
@Test
|
||||
fun `toCipherView should transform SecureNotes ItemType to CipherView with original cipher`() {
|
||||
val cipherView = DEFAULT_SECURE_NOTES_CIPHER_VIEW
|
||||
val secureNotesItemType = VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
originalCipher = cipherView,
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = emptyList(),
|
||||
val viewState = VaultAddItemState.ViewState.Content(
|
||||
common = VaultAddItemState.ViewState.Content.Common(
|
||||
originalCipher = cipherView,
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = true,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = emptyList(),
|
||||
),
|
||||
type = VaultAddItemState.ViewState.Content.ItemType.SecureNotes,
|
||||
)
|
||||
|
||||
val result = secureNotesItemType.toCipherView()
|
||||
val result = viewState.toCipherView()
|
||||
|
||||
assertEquals(
|
||||
cipherView.copy(
|
||||
|
|
Loading…
Add table
Reference in a new issue