Store information when switching vault add edit types. (#554)

This commit is contained in:
Ramsey Smith 2024-01-09 14:51:01 -07:00 committed by Álison Fernandes
parent aba5de32fb
commit 27ddac59b9
3 changed files with 144 additions and 18 deletions

View file

@ -137,7 +137,7 @@ private fun TypeOptionsItem(
BitwardenMultiSelectButton(
label = stringResource(id = R.string.type),
options = optionsWithStrings.values.toImmutableList(),
selectedOption = stringResource(id = itemType.displayStringResId),
selectedOption = stringResource(id = itemType.itemTypeOption.labelRes),
onOptionSelected = { selectedOption ->
val selectedOptionId = optionsWithStrings
.entries

View file

@ -148,8 +148,11 @@ class VaultAddEditViewModel @Inject constructor(
private fun handleSwitchToAddLoginItem() {
updateContent { currentContent ->
currentContent.copy(
common = currentContent.common.clearNonSharedData(),
type = VaultAddEditState.ViewState.Content.ItemType.Login(),
common = currentContent.clearNonSharedData(),
type = currentContent.previousItemTypeOrDefault(
itemType = VaultAddEditState.ItemTypeOption.LOGIN,
),
previousItemTypes = currentContent.toUpdatedPreviousItemTypes(),
)
}
}
@ -157,8 +160,11 @@ class VaultAddEditViewModel @Inject constructor(
private fun handleSwitchToAddSecureNotesItem() {
updateContent { currentContent ->
currentContent.copy(
common = currentContent.common.clearNonSharedData(),
type = VaultAddEditState.ViewState.Content.ItemType.SecureNotes,
common = currentContent.clearNonSharedData(),
type = currentContent.previousItemTypeOrDefault(
itemType = VaultAddEditState.ItemTypeOption.SECURE_NOTES,
),
previousItemTypes = currentContent.toUpdatedPreviousItemTypes(),
)
}
}
@ -166,8 +172,11 @@ class VaultAddEditViewModel @Inject constructor(
private fun handleSwitchToAddCardItem() {
updateContent { currentContent ->
currentContent.copy(
common = currentContent.common.clearNonSharedData(),
type = VaultAddEditState.ViewState.Content.ItemType.Card(),
common = currentContent.clearNonSharedData(),
type = currentContent.previousItemTypeOrDefault(
itemType = VaultAddEditState.ItemTypeOption.CARD,
),
previousItemTypes = currentContent.toUpdatedPreviousItemTypes(),
)
}
}
@ -175,8 +184,11 @@ class VaultAddEditViewModel @Inject constructor(
private fun handleSwitchToAddIdentityItem() {
updateContent { currentContent ->
currentContent.copy(
common = currentContent.common.clearNonSharedData(),
type = VaultAddEditState.ViewState.Content.ItemType.Identity(),
common = currentContent.clearNonSharedData(),
type = currentContent.previousItemTypeOrDefault(
itemType = VaultAddEditState.ItemTypeOption.IDENTITY,
),
previousItemTypes = currentContent.toUpdatedPreviousItemTypes(),
)
}
}
@ -933,13 +945,43 @@ class VaultAddEditViewModel @Inject constructor(
}
}
private fun VaultAddEditState.ViewState.Content.Common.clearNonSharedData():
private fun VaultAddEditState.ViewState.Content.clearNonSharedData():
VaultAddEditState.ViewState.Content.Common =
copy(
customFieldData = customFieldData
common.copy(
customFieldData = common.customFieldData
.filterNot { it is VaultAddEditState.Custom.LinkedField },
)
private fun VaultAddEditState.ViewState.Content.toUpdatedPreviousItemTypes():
Map<VaultAddEditState.ItemTypeOption, VaultAddEditState.ViewState.Content.ItemType> =
previousItemTypes
.toMutableMap()
.apply { set(type.itemTypeOption, type) }
private fun VaultAddEditState.ViewState.Content.previousItemTypeOrDefault(
itemType: VaultAddEditState.ItemTypeOption,
): VaultAddEditState.ViewState.Content.ItemType =
previousItemTypes.getOrDefault(
key = itemType,
defaultValue = when (itemType) {
VaultAddEditState.ItemTypeOption.LOGIN -> {
VaultAddEditState.ViewState.Content.ItemType.Login()
}
VaultAddEditState.ItemTypeOption.CARD -> {
VaultAddEditState.ViewState.Content.ItemType.Card()
}
VaultAddEditState.ItemTypeOption.IDENTITY -> {
VaultAddEditState.ViewState.Content.ItemType.Identity()
}
VaultAddEditState.ItemTypeOption.SECURE_NOTES -> {
VaultAddEditState.ViewState.Content.ItemType.SecureNotes
}
},
)
//endregion Utility Functions
}
@ -1009,6 +1051,7 @@ data class VaultAddEditState(
data class Content(
val common: Common,
val type: ItemType,
val previousItemTypes: Map<ItemTypeOption, ItemType> = emptyMap(),
) : ViewState() {
/**
@ -1064,7 +1107,7 @@ data class VaultAddEditState(
* that must be overridden by each subclass to provide the appropriate string
* resource for display purposes.
*/
abstract val displayStringResId: Int
abstract val itemTypeOption: ItemTypeOption
/**
* Represents the login item information.
@ -1084,7 +1127,7 @@ data class VaultAddEditState(
val totp: String? = null,
val canViewPassword: Boolean = true,
) : ItemType() {
override val displayStringResId: Int get() = ItemTypeOption.LOGIN.labelRes
override val itemTypeOption: ItemTypeOption get() = ItemTypeOption.LOGIN
}
/**
@ -1106,7 +1149,7 @@ data class VaultAddEditState(
val expirationYear: String = "",
val securityCode: String = "",
) : ItemType() {
override val displayStringResId: Int get() = ItemTypeOption.CARD.labelRes
override val itemTypeOption: ItemTypeOption get() = ItemTypeOption.CARD
}
/**
@ -1153,7 +1196,7 @@ data class VaultAddEditState(
val country: String = "",
) : ItemType() {
override val displayStringResId: Int get() = ItemTypeOption.IDENTITY.labelRes
override val itemTypeOption: ItemTypeOption get() = ItemTypeOption.IDENTITY
}
/**
@ -1161,8 +1204,7 @@ data class VaultAddEditState(
*/
@Parcelize
data object SecureNotes : ItemType() {
override val displayStringResId: Int
get() = ItemTypeOption.SECURE_NOTES.labelRes
override val itemTypeOption: ItemTypeOption get() = ItemTypeOption.SECURE_NOTES
}
}
}
@ -1223,6 +1265,7 @@ data class VaultAddEditState(
/**
* Displays a dialog.
*/
@Parcelize
sealed class DialogState : Parcelable {
/**

View file

@ -41,6 +41,7 @@ import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import java.util.UUID
@Suppress("LargeClass")
class VaultAddEditViewModelTest : BaseViewModelTest() {
private val loginInitialState = createVaultAddItemState(
@ -424,6 +425,88 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
viewState = VaultAddEditState.ViewState.Content(
common = createCommonContentViewState(),
type = createLoginTypeContentViewState(),
previousItemTypes = mapOf(
VaultAddEditState.ItemTypeOption.LOGIN
to VaultAddEditState.ViewState.Content.ItemType.Login(),
),
),
)
assertEquals(
expectedState,
viewModel.stateFlow.value,
)
}
@Test
fun `TypeOptionSelect CARD should switch to CardItem`() = runTest {
val viewModel = createAddVaultItemViewModel()
val action = VaultAddEditAction.Common.TypeOptionSelect(
VaultAddEditState.ItemTypeOption.CARD,
)
viewModel.actionChannel.trySend(action)
val expectedState = loginInitialState.copy(
viewState = VaultAddEditState.ViewState.Content(
common = createCommonContentViewState(),
type = VaultAddEditState.ViewState.Content.ItemType.Card(),
previousItemTypes = mapOf(
VaultAddEditState.ItemTypeOption.LOGIN
to VaultAddEditState.ViewState.Content.ItemType.Login(),
),
),
)
assertEquals(
expectedState,
viewModel.stateFlow.value,
)
}
@Test
fun `TypeOptionSelect IDENTITY should switch to IdentityItem`() = runTest {
val viewModel = createAddVaultItemViewModel()
val action = VaultAddEditAction.Common.TypeOptionSelect(
VaultAddEditState.ItemTypeOption.IDENTITY,
)
viewModel.actionChannel.trySend(action)
val expectedState = loginInitialState.copy(
viewState = VaultAddEditState.ViewState.Content(
common = createCommonContentViewState(),
type = VaultAddEditState.ViewState.Content.ItemType.Identity(),
previousItemTypes = mapOf(
VaultAddEditState.ItemTypeOption.LOGIN
to VaultAddEditState.ViewState.Content.ItemType.Login(),
),
),
)
assertEquals(
expectedState,
viewModel.stateFlow.value,
)
}
@Test
fun `TypeOptionSelect SECURE_NOTES should switch to SecureNotesItem`() = runTest {
val viewModel = createAddVaultItemViewModel()
val action = VaultAddEditAction.Common.TypeOptionSelect(
VaultAddEditState.ItemTypeOption.SECURE_NOTES,
)
viewModel.actionChannel.trySend(action)
val expectedState = loginInitialState.copy(
viewState = VaultAddEditState.ViewState.Content(
common = createCommonContentViewState(),
type = VaultAddEditState.ViewState.Content.ItemType.SecureNotes,
previousItemTypes = mapOf(
VaultAddEditState.ItemTypeOption.LOGIN
to VaultAddEditState.ViewState.Content.ItemType.Login(),
),
),
)