diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensions.kt new file mode 100644 index 000000000..69674e843 --- /dev/null +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensions.kt @@ -0,0 +1,176 @@ +package com.x8bit.bitwarden.ui.vault.feature.vault.util + +import com.bitwarden.core.CardView +import com.bitwarden.core.CipherRepromptType +import com.bitwarden.core.CipherType +import com.bitwarden.core.CipherView +import com.bitwarden.core.FieldType +import com.bitwarden.core.FieldView +import com.bitwarden.core.IdentityView +import com.bitwarden.core.LoginUriView +import com.bitwarden.core.LoginView +import com.bitwarden.core.SecureNoteType +import com.bitwarden.core.SecureNoteView +import com.bitwarden.core.UriMatchType +import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank +import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState +import java.time.Instant + +/** + * Transforms a [VaultAddItemState.ViewState.ItemType] into [CipherView]. + */ +fun VaultAddItemState.ViewState.Content.toCipherView(): CipherView = + CipherView( + // Pulled from original cipher when editing, otherwise uses defaults + 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 = type.toCipherType(), + identity = type.toIdentityView(), + secureNote = type.toSecureNotesView(), + login = type.toLoginView(common = common), + card = type.toCardView(), + + // Fields we always grab from the UI + name = common.name, + notes = common.notes, + favorite = common.favorite, + // TODO Use real folder ID (BIT-528) + folderId = common.originalCipher?.folderId, + // TODO Use real organization ID (BIT-780) + organizationId = common.originalCipher?.organizationId, + reprompt = common.toCipherRepromptType(), + fields = common.customFieldData.map { it.toFieldView() }, + ) + +private fun VaultAddItemState.ViewState.Content.ItemType.toCipherType(): CipherType = + when (this) { + 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.ItemType.toCardView(): CardView? = + (this as? VaultAddItemState.ViewState.Content.ItemType.Card)?.let { + // TODO Create real CardView from Content (BIT-668) + CardView( + cardholderName = null, + expMonth = null, + expYear = null, + code = null, + brand = null, + number = null, + ) + } + +private fun VaultAddItemState.ViewState.Content.ItemType.toIdentityView(): IdentityView? = + (this as? VaultAddItemState.ViewState.Content.ItemType.Identity)?.let { + IdentityView( + title = it.selectedTitle.name, + firstName = it.firstName.orNullIfBlank(), + lastName = it.lastName.orNullIfBlank(), + middleName = it.middleName.orNullIfBlank(), + address1 = it.address1.orNullIfBlank(), + address2 = it.address2.orNullIfBlank(), + address3 = it.address3.orNullIfBlank(), + city = it.city.orNullIfBlank(), + state = it.state.orNullIfBlank(), + postalCode = it.zip.orNullIfBlank(), + country = it.country.orNullIfBlank(), + company = it.company.orNullIfBlank(), + email = it.email.orNullIfBlank(), + phone = it.phone.orNullIfBlank(), + ssn = it.ssn.orNullIfBlank(), + username = it.username.orNullIfBlank(), + passportNumber = it.passportNumber.orNullIfBlank(), + licenseNumber = it.licenseNumber.orNullIfBlank(), + ) + } + +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 = common.originalCipher?.login?.passwordRevisionDate, + uris = listOf( + // TODO Implement URI list (BIT-1094) + LoginUriView( + uri = it.uri, + // TODO Implement URI settings in (BIT-1094) + match = UriMatchType.DOMAIN, + ), + ), + // TODO Implement TOTP (BIT-1066) + totp = common.originalCipher?.login?.totp, + autofillOnPageLoad = common.originalCipher?.login?.autofillOnPageLoad, + ) + } + +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.Common.toCipherRepromptType(): CipherRepromptType = + if (masterPasswordReprompt) { + CipherRepromptType.PASSWORD + } else { + CipherRepromptType.NONE + } + +/** + * Transforms [VaultAddItemState.Custom into [FieldView]. + */ +private fun VaultAddItemState.Custom.toFieldView(): FieldView = + when (val item = this) { + is VaultAddItemState.Custom.BooleanField -> { + FieldView( + name = item.name, + value = item.value.toString(), + type = FieldType.BOOLEAN, + linkedId = null, + ) + } + + is VaultAddItemState.Custom.HiddenField -> { + FieldView( + name = item.name, + value = item.value, + type = FieldType.HIDDEN, + linkedId = null, + ) + } + + is VaultAddItemState.Custom.LinkedField -> { + FieldView( + name = item.name, + value = null, + type = FieldType.LINKED, + linkedId = item.vaultLinkedFieldType.id, + ) + } + + is VaultAddItemState.Custom.TextField -> { + FieldView( + name = item.name, + value = item.value, + type = FieldType.TEXT, + linkedId = null, + ) + } + } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt index 2d4948cf0..fddc66ed4 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt @@ -1,63 +1,13 @@ -@file:Suppress("TooManyFunctions") - package com.x8bit.bitwarden.ui.vault.feature.vault.util -import com.bitwarden.core.CardView -import com.bitwarden.core.CipherRepromptType import com.bitwarden.core.CipherType import com.bitwarden.core.CipherView import com.bitwarden.core.CollectionView -import com.bitwarden.core.FieldType -import com.bitwarden.core.FieldView import com.bitwarden.core.FolderView -import com.bitwarden.core.IdentityView -import com.bitwarden.core.LoginUriView -import com.bitwarden.core.LoginView -import com.bitwarden.core.SecureNoteType -import com.bitwarden.core.SecureNoteView -import com.bitwarden.core.UriMatchType import com.x8bit.bitwarden.data.vault.repository.model.VaultData import com.x8bit.bitwarden.ui.platform.base.util.asText -import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank -import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType -import java.time.Instant - -/** - * Transforms a [CipherView] into a [VaultState.ViewState.VaultItem]. - */ -@Suppress("MagicNumber") -private fun CipherView.toVaultItemOrNull(): VaultState.ViewState.VaultItem? { - val id = this.id ?: return null - return when (type) { - CipherType.LOGIN -> VaultState.ViewState.VaultItem.Login( - id = id, - name = name.asText(), - username = login?.username?.asText(), - ) - - CipherType.SECURE_NOTE -> VaultState.ViewState.VaultItem.SecureNote( - id = id, - name = name.asText(), - ) - - CipherType.CARD -> VaultState.ViewState.VaultItem.Card( - id = id, - name = name.asText(), - brand = card?.brand?.asText(), - lastFourDigits = card?.number - ?.takeLast(4) - ?.asText(), - ) - - CipherType.IDENTITY -> VaultState.ViewState.VaultItem.Identity( - id = id, - name = name.asText(), - firstName = identity?.firstName?.asText(), - ) - } -} /** * Transforms [VaultData] into [VaultState.ViewState] using the given [vaultFilterType]. @@ -111,6 +61,41 @@ fun VaultData.toViewState( } } +/** + * Transforms a [CipherView] into a [VaultState.ViewState.VaultItem]. + */ +@Suppress("MagicNumber") +private fun CipherView.toVaultItemOrNull(): VaultState.ViewState.VaultItem? { + val id = this.id ?: return null + return when (type) { + CipherType.LOGIN -> VaultState.ViewState.VaultItem.Login( + id = id, + name = name.asText(), + username = login?.username?.asText(), + ) + + CipherType.SECURE_NOTE -> VaultState.ViewState.VaultItem.SecureNote( + id = id, + name = name.asText(), + ) + + CipherType.CARD -> VaultState.ViewState.VaultItem.Card( + id = id, + name = name.asText(), + brand = card?.brand?.asText(), + lastFourDigits = card?.number + ?.takeLast(4) + ?.asText(), + ) + + CipherType.IDENTITY -> VaultState.ViewState.VaultItem.Identity( + id = id, + name = name.asText(), + firstName = identity?.firstName?.asText(), + ) + } +} + @JvmName("toFilteredCipherList") private fun List.toFilteredList( vaultFilterType: VaultFilterType, @@ -158,162 +143,3 @@ private fun List.toFilteredList( } } } - -/** - * Transforms a [VaultAddItemState.ViewState.ItemType] into [CipherView]. - */ -fun VaultAddItemState.ViewState.Content.toCipherView(): CipherView = - CipherView( - // Pulled from original cipher when editing, otherwise uses defaults - 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 = type.toCipherType(), - identity = type.toIdentityView(), - secureNote = type.toSecureNotesView(), - login = type.toLoginView(common = common), - card = type.toCardView(), - - // Fields we always grab from the UI - name = common.name, - notes = common.notes, - favorite = common.favorite, - // TODO Use real folder ID (BIT-528) - folderId = common.originalCipher?.folderId, - // TODO Use real organization ID (BIT-780) - organizationId = common.originalCipher?.organizationId, - reprompt = common.toCipherRepromptType(), - fields = common.customFieldData.map { it.toFieldView() }, - ) - -private fun VaultAddItemState.ViewState.Content.ItemType.toCipherType(): CipherType = - when (this) { - 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.ItemType.toCardView(): CardView? = - (this as? VaultAddItemState.ViewState.Content.ItemType.Card)?.let { - // TODO Create real CardView from Content (BIT-668) - CardView( - cardholderName = null, - expMonth = null, - expYear = null, - code = null, - brand = null, - number = null, - ) - } - -private fun VaultAddItemState.ViewState.Content.ItemType.toIdentityView(): IdentityView? = - (this as? VaultAddItemState.ViewState.Content.ItemType.Identity)?.let { - IdentityView( - title = it.selectedTitle.name, - firstName = it.firstName.orNullIfBlank(), - lastName = it.lastName.orNullIfBlank(), - middleName = it.middleName.orNullIfBlank(), - address1 = it.address1.orNullIfBlank(), - address2 = it.address2.orNullIfBlank(), - address3 = it.address3.orNullIfBlank(), - city = it.city.orNullIfBlank(), - state = it.state.orNullIfBlank(), - postalCode = it.zip.orNullIfBlank(), - country = it.country.orNullIfBlank(), - company = it.company.orNullIfBlank(), - email = it.email.orNullIfBlank(), - phone = it.phone.orNullIfBlank(), - ssn = it.ssn.orNullIfBlank(), - username = it.username.orNullIfBlank(), - passportNumber = it.passportNumber.orNullIfBlank(), - licenseNumber = it.licenseNumber.orNullIfBlank(), - ) - } - -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 = common.originalCipher?.login?.passwordRevisionDate, - uris = listOf( - // TODO Implement URI list (BIT-1094) - LoginUriView( - uri = it.uri, - // TODO Implement URI settings in (BIT-1094) - match = UriMatchType.DOMAIN, - ), - ), - // TODO Implement TOTP (BIT-1066) - totp = common.originalCipher?.login?.totp, - autofillOnPageLoad = common.originalCipher?.login?.autofillOnPageLoad, - ) - } - -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.Common.toCipherRepromptType(): CipherRepromptType = - if (masterPasswordReprompt) { - CipherRepromptType.PASSWORD - } else { - CipherRepromptType.NONE - } - -/** - * Transforms [VaultAddItemState.Custom into [FieldView]. - */ -private fun VaultAddItemState.Custom.toFieldView(): FieldView = - when (val item = this) { - is VaultAddItemState.Custom.BooleanField -> { - FieldView( - name = item.name, - value = item.value.toString(), - type = FieldType.BOOLEAN, - linkedId = null, - ) - } - - is VaultAddItemState.Custom.HiddenField -> { - FieldView( - name = item.name, - value = item.value, - type = FieldType.HIDDEN, - linkedId = null, - ) - } - - is VaultAddItemState.Custom.LinkedField -> { - FieldView( - name = item.name, - value = null, - type = FieldType.LINKED, - linkedId = item.vaultLinkedFieldType.id, - ) - } - - is VaultAddItemState.Custom.TextField -> { - FieldView( - name = item.name, - value = item.value, - type = FieldType.TEXT, - linkedId = null, - ) - } - } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensionsTest.kt new file mode 100644 index 000000000..8826fd6ec --- /dev/null +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultAddItemStateExtensionsTest.kt @@ -0,0 +1,621 @@ +package com.x8bit.bitwarden.ui.vault.feature.vault.util + +import com.bitwarden.core.CipherRepromptType +import com.bitwarden.core.CipherType +import com.bitwarden.core.CipherView +import com.bitwarden.core.FieldType +import com.bitwarden.core.FieldView +import com.bitwarden.core.IdentityView +import com.bitwarden.core.LoginUriView +import com.bitwarden.core.LoginView +import com.bitwarden.core.PasswordHistoryView +import com.bitwarden.core.SecureNoteType +import com.bitwarden.core.SecureNoteView +import com.bitwarden.core.UriMatchType +import com.x8bit.bitwarden.ui.platform.base.util.asText +import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState +import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.unmockkStatic +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.time.Instant + +class VaultAddItemStateExtensionsTest { + + @AfterEach + fun tearDown() { + // Some individual tests call mockkStatic so we will make sure this is always undone. + unmockkStatic(Instant::class) + } + + @Test + fun `toCipherView should transform Login ItemType to CipherView`() { + mockkStatic(Instant::class) + every { Instant.now() } returns Instant.MIN + 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() + + assertEquals( + CipherView( + id = null, + organizationId = null, + folderId = null, + collectionIds = emptyList(), + key = null, + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.LOGIN, + login = LoginView( + username = "mockUsername-1", + password = "mockPassword-1", + passwordRevisionDate = null, + uris = listOf( + LoginUriView( + uri = "mockUri-1", + match = UriMatchType.DOMAIN, + ), + ), + totp = null, + autofillOnPageLoad = null, + ), + identity = null, + card = null, + secureNote = null, + favorite = false, + reprompt = CipherRepromptType.NONE, + organizationUseTotp = false, + edit = true, + viewPassword = true, + localData = null, + attachments = null, + fields = emptyList(), + passwordHistory = null, + creationDate = Instant.MIN, + deletedDate = null, + revisionDate = Instant.MIN, + ), + result, + ) + } + + @Test + fun `toCipherView should transform Login ItemType to CipherView with original cipher`() { + val cipherView = DEFAULT_LOGIN_CIPHER_VIEW + 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", + ), + ) + + val result = viewState.toCipherView() + + assertEquals( + @Suppress("MaxLineLength") + cipherView.copy( + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.LOGIN, + login = LoginView( + username = "mockUsername-1", + password = "mockPassword-1", + passwordRevisionDate = Instant.ofEpochSecond(1_000L), + uris = listOf( + LoginUriView( + uri = "mockUri-1", + match = UriMatchType.DOMAIN, + ), + ), + totp = "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example", + autofillOnPageLoad = false, + ), + favorite = true, + reprompt = CipherRepromptType.NONE, + fields = listOf( + FieldView( + name = "TestBoolean", + value = "false", + type = FieldType.BOOLEAN, + linkedId = null, + ), + FieldView( + name = "TestText", + value = "TestText", + type = FieldType.TEXT, + linkedId = null, + ), + FieldView( + name = "TestHidden", + value = "TestHidden", + type = FieldType.HIDDEN, + linkedId = null, + ), + FieldView( + name = "TestLinked", + value = null, + type = FieldType.LINKED, + linkedId = VaultLinkedFieldType.USERNAME.id, + ), + ), + passwordHistory = listOf( + PasswordHistoryView( + password = "old_password", + lastUsedDate = Instant.ofEpochSecond(1_000L), + ), + ), + ), + result, + ) + } + + @Test + fun `toCipherView should transform SecureNotes ItemType to CipherView`() { + mockkStatic(Instant::class) + every { Instant.now() } returns Instant.MIN + 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 = viewState.toCipherView() + + assertEquals( + CipherView( + id = null, + organizationId = null, + folderId = null, + collectionIds = emptyList(), + key = null, + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.SECURE_NOTE, + login = null, + identity = null, + card = null, + secureNote = SecureNoteView(SecureNoteType.GENERIC), + favorite = false, + reprompt = CipherRepromptType.NONE, + organizationUseTotp = false, + edit = true, + viewPassword = true, + localData = null, + attachments = null, + fields = listOf( + FieldView( + name = "TestBoolean", + value = "false", + type = FieldType.BOOLEAN, + linkedId = null, + ), + FieldView( + name = "TestText", + value = "TestText", + type = FieldType.TEXT, + linkedId = null, + ), + FieldView( + name = "TestHidden", + value = "TestHidden", + type = FieldType.HIDDEN, + linkedId = null, + ), + ), + passwordHistory = null, + creationDate = Instant.MIN, + deletedDate = null, + revisionDate = Instant.MIN, + ), + result, + ) + } + + @Test + fun `toCipherView should transform SecureNotes ItemType to CipherView with original cipher`() { + val cipherView = DEFAULT_SECURE_NOTES_CIPHER_VIEW + 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 = viewState.toCipherView() + + assertEquals( + cipherView.copy( + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.SECURE_NOTE, + secureNote = SecureNoteView(SecureNoteType.GENERIC), + reprompt = CipherRepromptType.PASSWORD, + fields = emptyList(), + ), + result, + ) + } + + @Test + fun `toCipherView should transform Identity ItemType to CipherView`() { + mockkStatic(Instant::class) + every { Instant.now() } returns Instant.MIN + 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", + ), + type = VaultAddItemState.ViewState.Content.ItemType.Identity( + selectedTitle = VaultAddItemState.ViewState.Content.ItemType.Identity.Title.MR, + firstName = "mockFirstName", + lastName = "mockLastName", + middleName = "mockMiddleName", + address1 = "mockAddress1", + address2 = "mockAddress2", + address3 = "mockAddress3", + city = "mockCity", + state = "mockState", + zip = "mockPostalCode", + country = "mockCountry", + company = "mockCompany", + email = "mockEmail", + phone = "mockPhone", + ssn = "mockSsn", + username = "MockUsername", + passportNumber = "mockPassportNumber", + licenseNumber = "mockLicenseNumber", + ), + ) + + val result = viewState.toCipherView() + + assertEquals( + CipherView( + id = null, + organizationId = null, + folderId = null, + collectionIds = emptyList(), + key = null, + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.IDENTITY, + login = null, + identity = IdentityView( + title = "MR", + firstName = "mockFirstName", + lastName = "mockLastName", + middleName = "mockMiddleName", + address1 = "mockAddress1", + address2 = "mockAddress2", + address3 = "mockAddress3", + city = "mockCity", + state = "mockState", + postalCode = "mockPostalCode", + country = "mockCountry", + company = "mockCompany", + email = "mockEmail", + phone = "mockPhone", + ssn = "mockSsn", + username = "MockUsername", + passportNumber = "mockPassportNumber", + licenseNumber = "mockLicenseNumber", + ), + card = null, + secureNote = null, + favorite = false, + reprompt = CipherRepromptType.NONE, + organizationUseTotp = false, + edit = true, + viewPassword = true, + localData = null, + attachments = null, + fields = emptyList(), + passwordHistory = null, + creationDate = Instant.MIN, + deletedDate = null, + revisionDate = Instant.MIN, + ), + result, + ) + } + + @Test + fun `toCipherView should transform Identity ItemType to CipherView with original cipher`() { + val cipherView = DEFAULT_IDENTITY_CIPHER_VIEW + 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.Identity( + selectedTitle = VaultAddItemState.ViewState.Content.ItemType.Identity.Title.MR, + firstName = "mockFirstName", + lastName = "mockLastName", + middleName = "mockMiddleName", + address1 = "mockAddress1", + address2 = "mockAddress2", + address3 = "mockAddress3", + city = "mockCity", + state = "mockState", + zip = "mockPostalCode", + country = "mockCountry", + company = "mockCompany", + email = "mockEmail", + phone = "mockPhone", + ssn = "mockSsn", + username = "MockUsername", + passportNumber = "mockPassportNumber", + licenseNumber = "mockLicenseNumber", + ), + ) + + val result = viewState.toCipherView() + + assertEquals( + @Suppress("MaxLineLength") + cipherView.copy( + name = "mockName-1", + notes = "mockNotes-1", + type = CipherType.IDENTITY, + identity = IdentityView( + title = "MR", + firstName = "mockFirstName", + lastName = "mockLastName", + middleName = "mockMiddleName", + address1 = "mockAddress1", + address2 = "mockAddress2", + address3 = "mockAddress3", + city = "mockCity", + state = "mockState", + postalCode = "mockPostalCode", + country = "mockCountry", + company = "mockCompany", + email = "mockEmail", + phone = "mockPhone", + ssn = "mockSsn", + username = "MockUsername", + passportNumber = "mockPassportNumber", + licenseNumber = "mockLicenseNumber", + ), + favorite = true, + reprompt = CipherRepromptType.NONE, + fields = listOf( + FieldView( + name = "TestBoolean", + value = "false", + type = FieldType.BOOLEAN, + linkedId = null, + ), + FieldView( + name = "TestText", + value = "TestText", + type = FieldType.TEXT, + linkedId = null, + ), + FieldView( + name = "TestHidden", + value = "TestHidden", + type = FieldType.HIDDEN, + linkedId = null, + ), + FieldView( + name = "TestLinked", + value = null, + type = FieldType.LINKED, + linkedId = VaultLinkedFieldType.USERNAME.id, + ), + ), + passwordHistory = listOf( + PasswordHistoryView( + password = "old_password", + lastUsedDate = Instant.ofEpochSecond(1_000L), + ), + ), + ), + result, + ) + } +} + +private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView( + id = "id1234", + organizationId = null, + folderId = null, + collectionIds = emptyList(), + key = null, + name = "cipher", + notes = "Lots of notes", + type = CipherType.LOGIN, + login = null, + identity = null, + card = null, + secureNote = null, + favorite = false, + reprompt = CipherRepromptType.PASSWORD, + organizationUseTotp = false, + edit = false, + viewPassword = false, + localData = null, + attachments = null, + fields = listOf( + FieldView( + name = "text", + value = "value", + type = FieldType.TEXT, + linkedId = null, + ), + FieldView( + name = "hidden", + value = "value", + type = FieldType.HIDDEN, + linkedId = null, + ), + FieldView( + name = "boolean", + value = "true", + type = FieldType.BOOLEAN, + linkedId = null, + ), + FieldView( + name = "linked username", + value = null, + type = FieldType.LINKED, + linkedId = 100U, + ), + FieldView( + name = "linked password", + value = null, + type = FieldType.LINKED, + linkedId = 101U, + ), + ), + passwordHistory = listOf( + PasswordHistoryView( + password = "old_password", + lastUsedDate = Instant.ofEpochSecond(1_000L), + ), + ), + creationDate = Instant.ofEpochSecond(1_000L), + deletedDate = null, + revisionDate = Instant.ofEpochSecond(1_000L), +) + +private val DEFAULT_LOGIN_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( + type = CipherType.LOGIN, + login = LoginView( + username = "username", + password = "password", + passwordRevisionDate = Instant.ofEpochSecond(1_000L), + uris = listOf( + LoginUriView( + uri = "www.example.com", + match = null, + ), + ), + totp = "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example", + autofillOnPageLoad = false, + ), +) + +private val DEFAULT_SECURE_NOTES_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( + type = CipherType.SECURE_NOTE, + fields = listOf( + FieldView( + name = "text", + value = "value", + type = FieldType.TEXT, + linkedId = null, + ), + FieldView( + name = "hidden", + value = "value", + type = FieldType.HIDDEN, + linkedId = null, + ), + FieldView( + name = "boolean", + value = "true", + type = FieldType.BOOLEAN, + linkedId = null, + ), + ), + secureNote = SecureNoteView(type = SecureNoteType.GENERIC), +) + +private val DEFAULT_IDENTITY_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( + type = CipherType.IDENTITY, + identity = IdentityView( + title = "MR", + firstName = "mockFirstName", + lastName = "mockLastName", + middleName = "mockMiddleName", + address1 = "mockAddress1", + address2 = "mockAddress2", + address3 = "mockAddress3", + city = "mockCity", + state = "mockState", + postalCode = "mockPostalCode", + country = "mockCountry", + company = "mockCompany", + email = "mockEmail", + phone = "mockPhone", + ssn = "mockSsn", + username = "MockUsername", + passportNumber = "mockPassportNumber", + licenseNumber = "mockLicenseNumber", + ), +) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt index a56b5f869..6a5ac1c09 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt @@ -1,42 +1,17 @@ package com.x8bit.bitwarden.ui.vault.feature.vault.util -import com.bitwarden.core.CipherRepromptType -import com.bitwarden.core.CipherType -import com.bitwarden.core.CipherView -import com.bitwarden.core.FieldType -import com.bitwarden.core.FieldView -import com.bitwarden.core.IdentityView -import com.bitwarden.core.LoginUriView -import com.bitwarden.core.LoginView -import com.bitwarden.core.PasswordHistoryView -import com.bitwarden.core.SecureNoteType -import com.bitwarden.core.SecureNoteView -import com.bitwarden.core.UriMatchType import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCollectionView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView import com.x8bit.bitwarden.data.vault.repository.model.VaultData import com.x8bit.bitwarden.ui.platform.base.util.asText -import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType -import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType -import io.mockk.every -import io.mockk.mockkStatic -import io.mockk.unmockkStatic -import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test -import java.time.Instant class VaultDataExtensionsTest { - @AfterEach - fun tearDown() { - // Some individual tests call mockkStatic so we will make sure this is always undone. - unmockkStatic(Instant::class) - } - @Suppress("MaxLineLength") @Test fun `toViewState for AllVaults should transform full VaultData into ViewState Content without filtering`() { @@ -187,592 +162,4 @@ class VaultDataExtensionsTest { actual, ) } - - @Test - fun `toCipherView should transform Login ItemType to CipherView`() { - mockkStatic(Instant::class) - every { Instant.now() } returns Instant.MIN - 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() - - assertEquals( - CipherView( - id = null, - organizationId = null, - folderId = null, - collectionIds = emptyList(), - key = null, - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.LOGIN, - login = LoginView( - username = "mockUsername-1", - password = "mockPassword-1", - passwordRevisionDate = null, - uris = listOf( - LoginUriView( - uri = "mockUri-1", - match = UriMatchType.DOMAIN, - ), - ), - totp = null, - autofillOnPageLoad = null, - ), - identity = null, - card = null, - secureNote = null, - favorite = false, - reprompt = CipherRepromptType.NONE, - organizationUseTotp = false, - edit = true, - viewPassword = true, - localData = null, - attachments = null, - fields = emptyList(), - passwordHistory = null, - creationDate = Instant.MIN, - deletedDate = null, - revisionDate = Instant.MIN, - ), - result, - ) - } - - @Test - fun `toCipherView should transform Login ItemType to CipherView with original cipher`() { - val cipherView = DEFAULT_LOGIN_CIPHER_VIEW - 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", - ), - ) - - val result = viewState.toCipherView() - - assertEquals( - @Suppress("MaxLineLength") - cipherView.copy( - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.LOGIN, - login = LoginView( - username = "mockUsername-1", - password = "mockPassword-1", - passwordRevisionDate = Instant.ofEpochSecond(1_000L), - uris = listOf( - LoginUriView( - uri = "mockUri-1", - match = UriMatchType.DOMAIN, - ), - ), - totp = "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example", - autofillOnPageLoad = false, - ), - favorite = true, - reprompt = CipherRepromptType.NONE, - fields = listOf( - FieldView( - name = "TestBoolean", - value = "false", - type = FieldType.BOOLEAN, - linkedId = null, - ), - FieldView( - name = "TestText", - value = "TestText", - type = FieldType.TEXT, - linkedId = null, - ), - FieldView( - name = "TestHidden", - value = "TestHidden", - type = FieldType.HIDDEN, - linkedId = null, - ), - FieldView( - name = "TestLinked", - value = null, - type = FieldType.LINKED, - linkedId = VaultLinkedFieldType.USERNAME.id, - ), - ), - passwordHistory = listOf( - PasswordHistoryView( - password = "old_password", - lastUsedDate = Instant.ofEpochSecond(1_000L), - ), - ), - ), - result, - ) - } - - @Test - fun `toCipherView should transform SecureNotes ItemType to CipherView`() { - mockkStatic(Instant::class) - every { Instant.now() } returns Instant.MIN - 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 = viewState.toCipherView() - - assertEquals( - CipherView( - id = null, - organizationId = null, - folderId = null, - collectionIds = emptyList(), - key = null, - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.SECURE_NOTE, - login = null, - identity = null, - card = null, - secureNote = SecureNoteView(SecureNoteType.GENERIC), - favorite = false, - reprompt = CipherRepromptType.NONE, - organizationUseTotp = false, - edit = true, - viewPassword = true, - localData = null, - attachments = null, - fields = listOf( - FieldView( - name = "TestBoolean", - value = "false", - type = FieldType.BOOLEAN, - linkedId = null, - ), - FieldView( - name = "TestText", - value = "TestText", - type = FieldType.TEXT, - linkedId = null, - ), - FieldView( - name = "TestHidden", - value = "TestHidden", - type = FieldType.HIDDEN, - linkedId = null, - ), - ), - passwordHistory = null, - creationDate = Instant.MIN, - deletedDate = null, - revisionDate = Instant.MIN, - ), - result, - ) - } - - @Test - fun `toCipherView should transform SecureNotes ItemType to CipherView with original cipher`() { - val cipherView = DEFAULT_SECURE_NOTES_CIPHER_VIEW - 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 = viewState.toCipherView() - - assertEquals( - cipherView.copy( - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.SECURE_NOTE, - secureNote = SecureNoteView(SecureNoteType.GENERIC), - reprompt = CipherRepromptType.PASSWORD, - fields = emptyList(), - ), - result, - ) - } - - @Test - fun `toCipherView should transform Identity ItemType to CipherView`() { - mockkStatic(Instant::class) - every { Instant.now() } returns Instant.MIN - 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", - ), - type = VaultAddItemState.ViewState.Content.ItemType.Identity( - selectedTitle = VaultAddItemState.ViewState.Content.ItemType.Identity.Title.MR, - firstName = "mockFirstName", - lastName = "mockLastName", - middleName = "mockMiddleName", - address1 = "mockAddress1", - address2 = "mockAddress2", - address3 = "mockAddress3", - city = "mockCity", - state = "mockState", - zip = "mockPostalCode", - country = "mockCountry", - company = "mockCompany", - email = "mockEmail", - phone = "mockPhone", - ssn = "mockSsn", - username = "MockUsername", - passportNumber = "mockPassportNumber", - licenseNumber = "mockLicenseNumber", - ), - ) - - val result = viewState.toCipherView() - - assertEquals( - CipherView( - id = null, - organizationId = null, - folderId = null, - collectionIds = emptyList(), - key = null, - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.IDENTITY, - login = null, - identity = IdentityView( - title = "MR", - firstName = "mockFirstName", - lastName = "mockLastName", - middleName = "mockMiddleName", - address1 = "mockAddress1", - address2 = "mockAddress2", - address3 = "mockAddress3", - city = "mockCity", - state = "mockState", - postalCode = "mockPostalCode", - country = "mockCountry", - company = "mockCompany", - email = "mockEmail", - phone = "mockPhone", - ssn = "mockSsn", - username = "MockUsername", - passportNumber = "mockPassportNumber", - licenseNumber = "mockLicenseNumber", - ), - card = null, - secureNote = null, - favorite = false, - reprompt = CipherRepromptType.NONE, - organizationUseTotp = false, - edit = true, - viewPassword = true, - localData = null, - attachments = null, - fields = emptyList(), - passwordHistory = null, - creationDate = Instant.MIN, - deletedDate = null, - revisionDate = Instant.MIN, - ), - result, - ) - } - - @Test - fun `toCipherView should transform Identity ItemType to CipherView with original cipher`() { - val cipherView = DEFAULT_IDENTITY_CIPHER_VIEW - 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.Identity( - selectedTitle = VaultAddItemState.ViewState.Content.ItemType.Identity.Title.MR, - firstName = "mockFirstName", - lastName = "mockLastName", - middleName = "mockMiddleName", - address1 = "mockAddress1", - address2 = "mockAddress2", - address3 = "mockAddress3", - city = "mockCity", - state = "mockState", - zip = "mockPostalCode", - country = "mockCountry", - company = "mockCompany", - email = "mockEmail", - phone = "mockPhone", - ssn = "mockSsn", - username = "MockUsername", - passportNumber = "mockPassportNumber", - licenseNumber = "mockLicenseNumber", - ), - ) - - val result = viewState.toCipherView() - - assertEquals( - @Suppress("MaxLineLength") - cipherView.copy( - name = "mockName-1", - notes = "mockNotes-1", - type = CipherType.IDENTITY, - identity = IdentityView( - title = "MR", - firstName = "mockFirstName", - lastName = "mockLastName", - middleName = "mockMiddleName", - address1 = "mockAddress1", - address2 = "mockAddress2", - address3 = "mockAddress3", - city = "mockCity", - state = "mockState", - postalCode = "mockPostalCode", - country = "mockCountry", - company = "mockCompany", - email = "mockEmail", - phone = "mockPhone", - ssn = "mockSsn", - username = "MockUsername", - passportNumber = "mockPassportNumber", - licenseNumber = "mockLicenseNumber", - ), - favorite = true, - reprompt = CipherRepromptType.NONE, - fields = listOf( - FieldView( - name = "TestBoolean", - value = "false", - type = FieldType.BOOLEAN, - linkedId = null, - ), - FieldView( - name = "TestText", - value = "TestText", - type = FieldType.TEXT, - linkedId = null, - ), - FieldView( - name = "TestHidden", - value = "TestHidden", - type = FieldType.HIDDEN, - linkedId = null, - ), - FieldView( - name = "TestLinked", - value = null, - type = FieldType.LINKED, - linkedId = VaultLinkedFieldType.USERNAME.id, - ), - ), - passwordHistory = listOf( - PasswordHistoryView( - password = "old_password", - lastUsedDate = Instant.ofEpochSecond(1_000L), - ), - ), - ), - result, - ) - } } - -private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView( - id = "id1234", - organizationId = null, - folderId = null, - collectionIds = emptyList(), - key = null, - name = "cipher", - notes = "Lots of notes", - type = CipherType.LOGIN, - login = null, - identity = null, - card = null, - secureNote = null, - favorite = false, - reprompt = CipherRepromptType.PASSWORD, - organizationUseTotp = false, - edit = false, - viewPassword = false, - localData = null, - attachments = null, - fields = listOf( - FieldView( - name = "text", - value = "value", - type = FieldType.TEXT, - linkedId = null, - ), - FieldView( - name = "hidden", - value = "value", - type = FieldType.HIDDEN, - linkedId = null, - ), - FieldView( - name = "boolean", - value = "true", - type = FieldType.BOOLEAN, - linkedId = null, - ), - FieldView( - name = "linked username", - value = null, - type = FieldType.LINKED, - linkedId = 100U, - ), - FieldView( - name = "linked password", - value = null, - type = FieldType.LINKED, - linkedId = 101U, - ), - ), - passwordHistory = listOf( - PasswordHistoryView( - password = "old_password", - lastUsedDate = Instant.ofEpochSecond(1_000L), - ), - ), - creationDate = Instant.ofEpochSecond(1_000L), - deletedDate = null, - revisionDate = Instant.ofEpochSecond(1_000L), -) - -private val DEFAULT_LOGIN_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( - type = CipherType.LOGIN, - login = LoginView( - username = "username", - password = "password", - passwordRevisionDate = Instant.ofEpochSecond(1_000L), - uris = listOf( - LoginUriView( - uri = "www.example.com", - match = null, - ), - ), - totp = "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example", - autofillOnPageLoad = false, - ), -) - -private val DEFAULT_SECURE_NOTES_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( - type = CipherType.SECURE_NOTE, - fields = listOf( - FieldView( - name = "text", - value = "value", - type = FieldType.TEXT, - linkedId = null, - ), - FieldView( - name = "hidden", - value = "value", - type = FieldType.HIDDEN, - linkedId = null, - ), - FieldView( - name = "boolean", - value = "true", - type = FieldType.BOOLEAN, - linkedId = null, - ), - ), - secureNote = SecureNoteView(type = SecureNoteType.GENERIC), -) - -private val DEFAULT_IDENTITY_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy( - type = CipherType.IDENTITY, - identity = IdentityView( - title = "MR", - firstName = "mockFirstName", - lastName = "mockLastName", - middleName = "mockMiddleName", - address1 = "mockAddress1", - address2 = "mockAddress2", - address3 = "mockAddress3", - city = "mockCity", - state = "mockState", - postalCode = "mockPostalCode", - country = "mockCountry", - company = "mockCompany", - email = "mockEmail", - phone = "mockPhone", - ssn = "mockSsn", - username = "MockUsername", - passportNumber = "mockPassportNumber", - licenseNumber = "mockLicenseNumber", - ), -)