From 3973ab402900fb57719f7b996e4c4875cf82e091 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Fri, 31 Jul 2026 16:21:25 +0100 Subject: [PATCH 01/10] Displaying Identities vault list when autofilling for an Identity --- .../autofill/model/AutofillSelectionData.kt | 1 + .../autofill/util/FilledDataExtensions.kt | 5 +- .../util/AutofillSelectionDataExtensions.kt | 1 + .../util/AutofillSelectionDataExtensions.kt | 4 ++ .../itemlisting/VaultItemListingViewModel.kt | 16 +++++ .../AutofillSelectionDataExtensionsTest.kt | 1 + .../AutofillSelectionDataExtensionsTest.kt | 17 +++++ .../VaultItemListingViewModelTest.kt | 70 +++++++++++++++++++ .../util/VaultItemListingDataUtil.kt | 8 +-- ui/src/main/res/values/strings.xml | 1 + 10 files changed, 116 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/model/AutofillSelectionData.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/model/AutofillSelectionData.kt index 0327ebf2413..5254eb93efd 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/model/AutofillSelectionData.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/model/AutofillSelectionData.kt @@ -23,6 +23,7 @@ data class AutofillSelectionData( enum class Type { CARD, LOGIN, + IDENTITY, } /** diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/util/FilledDataExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/util/FilledDataExtensions.kt index 4af7c3545ae..67baa1be9de 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/util/FilledDataExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/data/autofill/util/FilledDataExtensions.kt @@ -37,10 +37,7 @@ fun FilledData.buildVaultItemDataset( type = when (this.originalPartition) { is AutofillPartition.Card -> AutofillSelectionData.Type.CARD is AutofillPartition.Login -> AutofillSelectionData.Type.LOGIN - // AutofillSelectionData.Type has no IDENTITY value yet (deliberately deferred -- it - // cascades into the vault item listing/add-edit UI flows). This is a no-op placeholder - // today since nothing yet produces an Identity-only partition. - is AutofillPartition.Identity -> AutofillSelectionData.Type.LOGIN + is AutofillPartition.Identity -> AutofillSelectionData.Type.IDENTITY }, uri = this.uri, ) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensions.kt index 89e5f2da7e9..ffad59450da 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensions.kt @@ -10,4 +10,5 @@ fun AutofillSelectionData.Type.toVaultItemListingType(): VaultItemListingType = when (this) { AutofillSelectionData.Type.CARD -> VaultItemListingType.Card AutofillSelectionData.Type.LOGIN -> VaultItemListingType.Login + AutofillSelectionData.Type.IDENTITY -> VaultItemListingType.Identity } diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensions.kt index d7b0927540d..479aa2980f0 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensions.kt @@ -32,6 +32,10 @@ fun AutofillSelectionData.toDefaultAddTypeContent( ), ) } + + AutofillSelectionData.Type.IDENTITY -> { + VaultAddEditState.ViewState.Content.ItemType.Identity() + } } return VaultAddEditState.ViewState.Content( common = VaultAddEditState.ViewState.Content.Common( diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 9107d6871d8..84b49eec082 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -2867,6 +2867,18 @@ class VaultItemListingViewModel @Inject constructor( ) } } + + AutofillSelectionData.Type.IDENTITY -> { + this.map { vaultData -> + vaultData.copy( + decryptCipherListResult = vaultData.decryptCipherListResult.copy( + successes = vaultData.decryptCipherListResult.successes + .filter { it.type is CipherListViewType.Identity }, + failures = emptyList(), + ), + ) + } + } } } @@ -3050,6 +3062,10 @@ data class VaultItemListingState( AutofillSelectionData.Type.LOGIN -> { BitwardenString.items_for_uri.asText(it) } + + AutofillSelectionData.Type.IDENTITY -> { + BitwardenString.identities_for_x.asText(it) + } } } } diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensionsTest.kt index 30881e342ad..81c4a4017af 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/rootnav/util/AutofillSelectionDataExtensionsTest.kt @@ -11,6 +11,7 @@ class AutofillSelectionDataExtensionsTest { mapOf( AutofillSelectionData.Type.CARD to VaultItemListingType.Card, AutofillSelectionData.Type.LOGIN to VaultItemListingType.Login, + AutofillSelectionData.Type.IDENTITY to VaultItemListingType.Identity, ) .forEach { (type, expected) -> assertEquals( diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensionsTest.kt index 4b0f6d9c1a5..5308b5da306 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/AutofillSelectionDataExtensionsTest.kt @@ -39,6 +39,23 @@ class AutofillSelectionDataExtensionsTest { ) } + @Test + fun `toDefaultAddTypeContent for an Identity type should return the correct Content`() { + assertEquals( + VaultAddEditState.ViewState.Content( + common = VaultAddEditState.ViewState.Content.Common(), + isIndividualVaultDisabled = false, + type = VaultAddEditState.ViewState.Content.ItemType.Identity(), + ), + AutofillSelectionData( + type = AutofillSelectionData.Type.IDENTITY, + framework = AutofillSelectionData.Framework.AUTOFILL, + uri = null, + ) + .toDefaultAddTypeContent(isIndividualVaultDisabled = false), + ) + } + @Test fun `toDefaultAddTypeContent for a Login type should return the correct Content`() { every { UUID.randomUUID().toString() } returns "uuid" diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt index 9aee5faef81..c03b62138d7 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt @@ -2906,6 +2906,76 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { ) } + @Suppress("MaxLineLength") + @Test + fun `vaultDataStateFlow Loaded with items and autofill filtering for Identity should update ViewState to Content with filtered data`() = + runTest { + setupMockUri() + + val cipherView1 = createMockCipherListView( + number = 1, + type = CipherListViewType.Identity, + ) + val cipherView2 = createMockCipherListView( + number = 2, + type = CipherListViewType.Login( + createMockLoginListView(number = 2), + ), + ) + + val autofillSelectionData = AutofillSelectionData( + type = AutofillSelectionData.Type.IDENTITY, + framework = AutofillSelectionData.Framework.AUTOFILL, + uri = "https://www.test.com", + ) + specialCircumstanceManager.specialCircumstance = + SpecialCircumstance.AutofillSelection( + autofillSelectionData = autofillSelectionData, + shouldFinishWhenComplete = true, + ) + val dataState = DataState.Loaded( + data = VaultData( + decryptCipherListResult = createMockDecryptCipherListResult( + number = 1, + successes = listOf(cipherView1, cipherView2), + ), + folderViewList = listOf(createMockFolderView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), + sendViewList = listOf(createMockSendView(number = 1)), + ), + ) + + val viewModel = createVaultItemListingViewModel( + savedStateHandle = createSavedStateHandleWithVaultItemListingType( + vaultItemListingType = VaultItemListingType.Identity, + ), + ) + + mutableVaultDataStateFlow.value = dataState + + assertEquals( + createVaultItemListingState( + itemListingType = VaultItemListingState.ItemListingType.Vault.Identity, + viewState = VaultItemListingState.ViewState.Content( + displayCollectionList = emptyList(), + displayItemList = listOf( + createMockDisplayItemForCipher( + number = 1, + cipherType = CipherType.IDENTITY, + subtitle = "mockSubtitle-1", + secondSubtitleTestTag = "PasskeySite", + subtitleTestTag = "PasswordName", + isAutofill = true, + ), + ), + displayFolderList = emptyList(), + ), + ) + .copy(autofillSelectionData = autofillSelectionData), + viewModel.stateFlow.value, + ) + } + @Suppress("MaxLineLength") @Test fun `vaultDataStateFlow Loaded with items and totp data filtering should update ViewState to Content with filtered data`() = diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt index f08bead83a5..c64ffca465a 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt @@ -197,7 +197,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_id_card), extraIconList = persistentListOf( IconData.Local( @@ -225,9 +225,9 @@ fun createMockDisplayItemForCipher( ListingItemOverflowAction.VaultAction.ArchiveClick(cipherId = "mockId-$number"), ), optionsTestTag = "CipherOptionsButton", - isAutofill = false, - isCredentialCreation = false, - shouldShowMasterPasswordReprompt = false, + isAutofill = isAutofill, + isCredentialCreation = isCredentialCreation, + shouldShowMasterPasswordReprompt = shouldShowMasterPasswordReprompt, iconTestTag = "IdentityCipherIcon", itemType = VaultItemListingState.DisplayItem.ItemType.Vault(type = cipherType), ) diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index f38700c934f..6090286c824 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -1161,6 +1161,7 @@ Do you want to switch to this account? Bitwarden could not decrypt %1$d vault items. Copy and share this error report with customer success to avoid additional data loss. Select a card for %s + Identities for %s Advanced options More about match detection Keep your credentials secure From 4ea52fb75afcc6464db08c0251d2003fc4a25e11 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Thu, 17 Sep 2026 18:03:28 +0100 Subject: [PATCH 02/10] updated text --- .../ui/vault/feature/itemlisting/VaultItemListingViewModel.kt | 2 +- ui/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 84b49eec082..b6876ca63bb 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3064,7 +3064,7 @@ data class VaultItemListingState( } AutofillSelectionData.Type.IDENTITY -> { - BitwardenString.identities_for_x.asText(it) + BitwardenString.choose_an_identity.asText() } } } diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 6090286c824..94d7682b026 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -1161,7 +1161,7 @@ Do you want to switch to this account? Bitwarden could not decrypt %1$d vault items. Copy and share this error report with customer success to avoid additional data loss. Select a card for %s - Identities for %s + Choose an identity Advanced options More about match detection Keep your credentials secure From e02683b4a78a3a2e4b92372ed06b0f221a38dcc0 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Thu, 17 Sep 2026 19:05:24 +0100 Subject: [PATCH 03/10] Addressed PR comments --- .../feature/itemlisting/VaultItemListingViewModel.kt | 4 +++- .../itemlisting/util/VaultItemListingDataUtil.kt | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index b6876ca63bb..9bd6d9780b0 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -2872,7 +2872,9 @@ class VaultItemListingViewModel @Inject constructor( this.map { vaultData -> vaultData.copy( decryptCipherListResult = vaultData.decryptCipherListResult.copy( - successes = vaultData.decryptCipherListResult.successes + successes = vaultData + .decryptCipherListResult + .successes .filter { it.type is CipherListViewType.Identity }, failures = emptyList(), ), diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt index c64ffca465a..a2d55a0bbc9 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt @@ -97,7 +97,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_note), extraIconList = persistentListOf( IconData.Local( @@ -145,7 +145,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_payment_card), extraIconList = persistentListOf( IconData.Local( @@ -241,7 +241,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_ssh_key), extraIconList = persistentListOf( IconData.Local( @@ -285,7 +285,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_payment_card), extraIconList = persistentListOf( IconData.Local( @@ -329,7 +329,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_note), extraIconList = persistentListOf( IconData.Local( @@ -373,7 +373,7 @@ fun createMockDisplayItemForCipher( secondSubtitle = secondSubtitle, secondSubtitleTestTag = secondSubtitleTestTag, subtitle = subtitle, - subtitleTestTag = "CipherSubTitleLabel", + subtitleTestTag = subtitleTestTag, iconData = IconData.Local(BitwardenDrawable.ic_note), extraIconList = persistentListOf( IconData.Local( From 565e02f029f8d5862cc48454f8d3956d8c19d63d Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Thu, 17 Sep 2026 19:24:51 +0100 Subject: [PATCH 04/10] keeping always choose_identity for identity listing screen --- .../ui/vault/feature/itemlisting/VaultItemListingViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 9bd6d9780b0..ba906e97469 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3447,7 +3447,7 @@ data class VaultItemListingState( * An Identity item listing. */ data object Identity : Vault() { - override val titleText: Text get() = BitwardenString.identities.asText() + override val titleText: Text get() = BitwardenString.choose_an_identity.asText() override val hasFab: Boolean get() = true } From c7958845d4c6c9febc8ea8388d77f480dca6230a Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Thu, 17 Sep 2026 19:36:59 +0100 Subject: [PATCH 05/10] fixed VaultItemListingScreenTest --- .../ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt index d25192a97e5..5d7e2144a25 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt @@ -1341,7 +1341,7 @@ class VaultItemListingScreenTest : BitwardenComposeTest() { it.copy(itemListingType = VaultItemListingState.ItemListingType.Vault.Identity) } composeTestRule - .onNodeWithText(text = "Identities") + .onNodeWithText(text = "Choose an identity") .assertIsDisplayed() mutableStateFlow.update { From 6fd66e135b620db2a3718f8ef8a72dec23f1730c Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Fri, 18 Sep 2026 11:43:49 +0100 Subject: [PATCH 06/10] reverting identities change --- .../ui/vault/feature/itemlisting/VaultItemListingViewModel.kt | 2 +- .../ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index ba906e97469..9bd6d9780b0 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3447,7 +3447,7 @@ data class VaultItemListingState( * An Identity item listing. */ data object Identity : Vault() { - override val titleText: Text get() = BitwardenString.choose_an_identity.asText() + override val titleText: Text get() = BitwardenString.identities.asText() override val hasFab: Boolean get() = true } diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt index 5d7e2144a25..d25192a97e5 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt @@ -1341,7 +1341,7 @@ class VaultItemListingScreenTest : BitwardenComposeTest() { it.copy(itemListingType = VaultItemListingState.ItemListingType.Vault.Identity) } composeTestRule - .onNodeWithText(text = "Choose an identity") + .onNodeWithText(text = "Identities") .assertIsDisplayed() mutableStateFlow.update { From f8313d5b1d36ecbccdec9ca15c0f8141c5eb68f9 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 11:16:03 +0000 Subject: [PATCH 07/10] Show 'Choose an identity' for identity autofill regardless of uri Keeps the vault browse listing title as 'Identities' and handles the identity autofill case in appBarTitle above the uri check, so the title no longer depends on the request carrying a parsable uri. Co-authored-by: aj-rosado <109146700+aj-rosado@users.noreply.github.com> --- .../itemlisting/VaultItemListingViewModel.kt | 11 +++----- .../itemlisting/VaultItemListingScreenTest.kt | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 9bd6d9780b0..44dc2ded8d2 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3053,6 +3053,9 @@ data class VaultItemListingState( val appBarTitle: Text get() = autofillSelectionData ?.let { data -> + if (data.type == AutofillSelectionData.Type.IDENTITY) { + return@let BitwardenString.choose_an_identity.asText() + } data.uri ?.toHostOrPathOrNull() ?.let { @@ -3061,13 +3064,7 @@ data class VaultItemListingState( BitwardenString.select_a_card_for_x.asText(it) } - AutofillSelectionData.Type.LOGIN -> { - BitwardenString.items_for_uri.asText(it) - } - - AutofillSelectionData.Type.IDENTITY -> { - BitwardenString.choose_an_identity.asText() - } + else -> BitwardenString.items_for_uri.asText(it) } } } diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt index d25192a97e5..db62f9a20e5 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt @@ -1371,6 +1371,34 @@ class VaultItemListingScreenTest : BitwardenComposeTest() { .assertIsDisplayed() } + @Suppress("MaxLineLength") + @Test + fun `topBar title should be displayed for identity autofill selection regardless of the uri`() { + mutableStateFlow.update { + it.copy( + itemListingType = VaultItemListingState.ItemListingType.Vault.Identity, + autofillSelectionData = AUTOFILL_SELECTION_DATA.copy( + type = AutofillSelectionData.Type.IDENTITY, + uri = null, + ), + ) + } + composeTestRule + .onNodeWithText(text = "Choose an identity") + .assertIsDisplayed() + + mutableStateFlow.update { + it.copy( + autofillSelectionData = AUTOFILL_SELECTION_DATA.copy( + type = AutofillSelectionData.Type.IDENTITY, + ), + ) + } + composeTestRule + .onNodeWithText(text = "Choose an identity") + .assertIsDisplayed() + } + @Test fun `on overflow item click should display menu`() { composeTestRule From 7ad3727656c58d8775d9bf0f440f6baa96eea094 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Mon, 21 Sep 2026 15:07:25 +0100 Subject: [PATCH 08/10] improved readibility --- .../feature/itemlisting/VaultItemListingViewModel.kt | 8 ++++++-- .../feature/itemlisting/VaultItemListingScreenTest.kt | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 44dc2ded8d2..a3da00de578 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3064,7 +3064,10 @@ data class VaultItemListingState( BitwardenString.select_a_card_for_x.asText(it) } - else -> BitwardenString.items_for_uri.asText(it) + AutofillSelectionData.Type.LOGIN, + -> { + BitwardenString.items_for_uri.asText(it) + } } } } @@ -3158,7 +3161,8 @@ data class VaultItemListingState( * Displays the overwrite passkey confirmation prompt to the user. */ @Parcelize - data class OverwritePasskeyConfirmationPrompt(val cipherViewId: String) : DialogState() + data class OverwritePasskeyConfirmationPrompt(val cipherViewId: String) : + DialogState() /** * Represents a dialog to prompt the user for their master password as part of the diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt index db62f9a20e5..faf87247bb0 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt @@ -1371,7 +1371,6 @@ class VaultItemListingScreenTest : BitwardenComposeTest() { .assertIsDisplayed() } - @Suppress("MaxLineLength") @Test fun `topBar title should be displayed for identity autofill selection regardless of the uri`() { mutableStateFlow.update { From a36e901d591c4a03e6f25f48d71d6ccfce3233a6 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Mon, 21 Sep 2026 17:24:42 +0100 Subject: [PATCH 09/10] improved readibility --- .../itemlisting/VaultItemListingViewModel.kt | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index a3da00de578..ef3bf392884 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3053,23 +3053,18 @@ data class VaultItemListingState( val appBarTitle: Text get() = autofillSelectionData ?.let { data -> - if (data.type == AutofillSelectionData.Type.IDENTITY) { - return@let BitwardenString.choose_an_identity.asText() - } - data.uri - ?.toHostOrPathOrNull() - ?.let { - when (data.type) { - AutofillSelectionData.Type.CARD -> { - BitwardenString.select_a_card_for_x.asText(it) - } + when (data.type) { + AutofillSelectionData.Type.IDENTITY -> + BitwardenString.choose_an_identity.asText() - AutofillSelectionData.Type.LOGIN, - -> { - BitwardenString.items_for_uri.asText(it) - } - } - } + AutofillSelectionData.Type.CARD -> data.uri + ?.toHostOrPathOrNull() + ?.let { BitwardenString.select_a_card_for_x.asText(it) } + + AutofillSelectionData.Type.LOGIN -> data.uri + ?.toHostOrPathOrNull() + ?.let { BitwardenString.items_for_uri.asText(it) } + } } ?: createCredentialRequest ?.relyingPartyIdOrNull From 24dbd243f7b3875bd93924f07a463ae5cdde4a91 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Mon, 21 Sep 2026 18:45:53 +0100 Subject: [PATCH 10/10] improved formatting --- .../itemlisting/VaultItemListingViewModel.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index ef3bf392884..cc747a24ac8 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -3054,16 +3054,21 @@ data class VaultItemListingState( get() = autofillSelectionData ?.let { data -> when (data.type) { - AutofillSelectionData.Type.IDENTITY -> + AutofillSelectionData.Type.IDENTITY -> { BitwardenString.choose_an_identity.asText() + } - AutofillSelectionData.Type.CARD -> data.uri - ?.toHostOrPathOrNull() - ?.let { BitwardenString.select_a_card_for_x.asText(it) } + AutofillSelectionData.Type.CARD -> { + data.uri + ?.toHostOrPathOrNull() + ?.let { BitwardenString.select_a_card_for_x.asText(it) } + } - AutofillSelectionData.Type.LOGIN -> data.uri - ?.toHostOrPathOrNull() - ?.let { BitwardenString.items_for_uri.asText(it) } + AutofillSelectionData.Type.LOGIN -> { + data.uri + ?.toHostOrPathOrNull() + ?.let { BitwardenString.items_for_uri.asText(it) } + } } } ?: createCredentialRequest @@ -3156,8 +3161,7 @@ data class VaultItemListingState( * Displays the overwrite passkey confirmation prompt to the user. */ @Parcelize - data class OverwritePasskeyConfirmationPrompt(val cipherViewId: String) : - DialogState() + data class OverwritePasskeyConfirmationPrompt(val cipherViewId: String) : DialogState() /** * Represents a dialog to prompt the user for their master password as part of the