Skip to content

[PM-41057] feat: Gate VFO-1 naming work behind vfo1-foundation feature flag - #7219

Open
andrebispo5 wants to merge 12 commits into
readd-vfo1-naming-changesfrom
PM-41057-gate-vfo1-work-with-feature-flag
Open

[PM-41057] feat: Gate VFO-1 naming work behind vfo1-foundation feature flag#7219
andrebispo5 wants to merge 12 commits into
readd-vfo1-naming-changesfrom
PM-41057-gate-vfo1-work-with-feature-flag

Conversation

@andrebispo5

@andrebispo5 andrebispo5 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-41057

📔 Objective

Adds a vfo1-foundation feature flag and gates the already-developed VFO-1 terminology rename work (Owner→Vault, Collection→Shared folder, Organization→Vault, Folders→My folders) behind it, so this branch can merge to main with an instant kill-switch instead of relying on a revert PR if issues surface.

The flag is exposed via MainState.featureFlagsStateLocalFeatureFlagsState, following the pattern already scaffolded in the codebase, and read directly via FeatureFlagManager in ViewModels/data-mapping functions that can't access a CompositionLocal. Renamed strings/icons render the old terminology when the flag is off, and the previously-deleted strings/icon needed for that fallback have been restored. Default is false.

📸 Screenshots

Screen_recording_20260729_161938.mp4

Declares FlagKey.Vfo1Foundation (default false), adds its debug-menu
entry, converts FeatureFlagsState to a real data class carrying the
flag, and adds a vfo1Foundation(new, old) Composable helper for
gating renamed strings/icons at call sites.
Injects FeatureFlagManager into MainViewModel, adds
isVfo1FoundationEnabled to MainState (initialized synchronously and
kept live via getFeatureFlagFlow), and exposes it through
MainState.featureFlagsState so it reaches LocalFeatureFlagsState.
Re-adds the folders, collections, no_items_collection,
no_collections_to_list, select_one_collection, and move_to_vault
strings, plus the ic_collections drawable, all previously deleted as
unused once the VFO1 rename shipped unconditionally. They're needed
again now that the rename is gated: the flag-off path renders these.
Wraps the Vault, Settings, Folders, item listing, add/edit item, item
detail, and move-to-organization screens' VFO1-renamed strings and
icons with the vfo1Foundation() helper, so they read the old
terminology when the flag is off.
Injects the flag's live value into VaultAddEditState and threads it
into CipherViewExtensions.toAvailableOwners, gating the "shared
folder" validation message and the personal-vault owner name ("My
vault" vs. the account email) between the new and old behavior.
Injects the live flag value into VaultMoveToOrganizationState, gating
its appBarText ("Move"/"Shared folders" vs. "Move to vault"/
"Collections") and its "select at least one" validation message.
Adds VaultTrailingIcon.COLLECTION_LEGACY and a matching
VaultItemLocation.Collection icon parameter, and threads
isVfo1FoundationEnabled through CipherListViewExtensions.toLabelIcons
and the Vault/Search/ItemListing display-item construction functions,
so the collection icon and any old/new terminology in these lists
follow the flag.
@github-actions github-actions Bot added app:password-manager Bitwarden Password Manager app context app:authenticator Bitwarden Authenticator app context t:feature Change Type - Feature Development labels Jul 29, 2026
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.21154% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.97%. Comparing base (3c5de4a) to head (897d944).

Files with missing lines Patch % Lines
...itemlisting/util/VaultItemListingDataExtensions.kt 50.00% 7 Missing ⚠️
...rden/ui/vault/components/CollectionItemSelector.kt 50.00% 4 Missing ⚠️
...movetoorganization/VaultMoveToOrganizationEmpty.kt 0.00% 4 Missing ⚠️
...toorganization/VaultMoveToOrganizationViewModel.kt 81.81% 4 Missing ⚠️
...ui/vault/feature/vault/util/VaultDataExtensions.kt 71.42% 4 Missing ⚠️
.../ui/vault/feature/addedit/VaultAddEditViewModel.kt 82.35% 3 Missing ⚠️
...rm/feature/search/util/SearchTypeDataExtensions.kt 66.66% 2 Missing ⚠️
...vault/feature/addedit/util/CipherViewExtensions.kt 50.00% 1 Missing and 1 partial ⚠️
...warden/ui/vault/feature/item/VaultItemViewModel.kt 80.00% 1 Missing and 1 partial ⚠️
...c/main/kotlin/com/x8bit/bitwarden/MainViewModel.kt 92.85% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@                      Coverage Diff                      @@
##           readd-vfo1-naming-changes    #7219      +/-   ##
=============================================================
- Coverage                      86.09%   85.97%   -0.13%     
=============================================================
  Files                            891     1020     +129     
  Lines                          64869    67420    +2551     
  Branches                        9700     9762      +62     
=============================================================
+ Hits                           55846    57961    +2115     
- Misses                          5552     5955     +403     
- Partials                        3471     3504      +33     
Flag Coverage Δ
app-data 17.87% <0.00%> (+0.14%) ⬆️
app-ui-auth-tools 19.07% <7.00%> (+0.32%) ⬆️
app-ui-platform 17.06% <9.00%> (+0.54%) ⬆️
app-ui-vault 28.01% <70.67%> (+0.69%) ⬆️
authenticator 6.09% <0.00%> (-0.02%) ⬇️
lib-core-network-bridge 4.01% <0.00%> (-0.12%) ⬇️
lib-data-ui 1.14% <0.00%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@andrebispo5 andrebispo5 added the ai-review Request a Claude code review label Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Re-reviewed the vfo1-foundation flag after the latest round of fixes. I diffed this branch directly against main to confirm the net effect of the rename work plus the gating: every pre-VFO-1 string, drawable, owner name, validation message, app-bar title, and collection icon is still present and is what renders when the flag is off, and all eight re-added strings have their localized translations intact. All production call sites of toViewState/toLabelIcons/appendFolderAndOwnerData now thread the flag explicitly, every default parameter is fail-safe (false / ic_collections), and each positional vfo1Foundation(new, old) call site passes its arguments in the correct order. No new findings.

Code Review Details

No new findings this round. Previously reported items have been addressed:

  • Helper and data-class defaults are now fail-safe (isVfo1FoundationEnabled = false, VaultItemLocation.Collection.icon = ic_collections).
  • The move-to-organization screen (label, dialogTitle, supportingText, empty state, app-bar text) now falls back to organization / move_to_org_desc / no_orgs_to_list / move_to_organization.
  • The unused move_to_vault string was removed.
  • VaultMoveToOrganizationScreenTest regained flag-on coverage.

Still-open items from earlier rounds (not re-posted, existing threads cover them): SearchViewModel, VaultItemListingViewModel, VaultItemViewModel, and VaultAddEditViewModel.appendFolderAndOwnerData read the flag at mapping time rather than re-deriving on flag change, so flipping the kill switch leaves those surfaces mixed until their data re-emits — only VaultViewModel re-derives its view state. Flag-off branches remain largely unasserted in tests (patch coverage 15.5%), which is a reasonable tradeoff for temporary gating code but does mean the kill-switch path is verified manually rather than by CI.

@andrebispo5
andrebispo5 requested a review from Copilot July 29, 2026 15:49
@andrebispo5
andrebispo5 marked this pull request as ready for review July 29, 2026 15:50
@andrebispo5
andrebispo5 requested review from a team and david-livefront as code owners July 29, 2026 15:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new vfo1-foundation feature flag and threads it through core + UI so the previously implemented VFO-1 terminology/icon changes can be toggled on/off at runtime (default off), providing a kill-switch for merging the work safely to main.

Changes:

  • Introduces FlagKey.Vfo1Foundation and exposes it via MainState.featureFlagsStateLocalFeatureFlagsState.
  • Gates renamed terminology and icon variants behind the flag across Vault-related screens/view-model mapping.
  • Restores legacy strings/icons needed to render the pre-VFO-1 terminology when the flag is disabled, and updates tests accordingly.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ui/src/main/res/values/strings.xml Restores legacy terminology strings (e.g., Collections/Folders variants) used when the flag is off.
ui/src/main/res/values/strings_non_localized.xml Adds a debug-menu label for the new flag.
ui/src/main/res/drawable/ic_collections.xml Adds legacy collections icon resource for the flag-off path.
ui/src/main/kotlin/com/bitwarden/ui/platform/components/debug/FeatureFlagListItems.kt Exposes the new flag in the debug feature flags UI.
core/src/main/kotlin/com/bitwarden/core/data/manager/model/FlagKey.kt Adds FlagKey.Vfo1Foundation (key name + default).
core/src/test/kotlin/com/bitwarden/core/data/manager/model/FlagKeyTest.kt Adds/updates unit coverage for the new flag key.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/model/FeatureFlagsState.kt Converts UI feature flags from data object to data class with isVfo1FoundationEnabled.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/composition/util/Vfo1FoundationExtensions.kt Adds a Compose helper to switch resources/values based on vfo1-foundation.
app/src/main/kotlin/com/x8bit/bitwarden/MainViewModel.kt Reads flag initially + subscribes to updates to publish into MainState.featureFlagsState.
app/src/test/kotlin/com/x8bit/bitwarden/MainViewModelTest.kt Adds test ensuring MainState updates when the flag flow changes.
app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/base/BitwardenComposeTest.kt Updates default FeatureFlagsState construction for tests.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/model/VaultTrailingIcon.kt Adds a legacy trailing icon entry for the flag-off collection icon/label.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/util/CipherListViewExtensions.kt Threads flag to icon selection for cipher “label icons”.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt Subscribes to the flag flow and threads it into Vault view state generation.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt Mocks the new flag flow for VaultViewModel tests.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultContent.kt Gates Vault screen headers and collection icon resources via Compose helper.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt Threads flag through Vault data → view-state mapping (including trailing icons).
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt Threads flag into item-listing view-state mapping.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt Mocks flag state for item listing view-model tests.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingContent.kt Gates listing headers + collection icon resources via Compose helper.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensions.kt Gates empty-state messaging and trailing icons in item listing mapping.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt Threads flag into item screen “locations” icon choice.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModelTest.kt Adds FeatureFlagManager mocking for the new flag in tests.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemScreen.kt Gates overflow menu labels between terminology variants.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/model/VaultItemLocation.kt Allows collection location icon to vary (parameterized) for gating.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt Reads + subscribes to flag updates and gates terminology in validation and mapping.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt Mocks flag flows and updates expected state snapshots.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreen.kt Gates overflow/menu labels and bottom-sheet titles via Compose helper.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditItemContent.kt Gates field labels (folder/vault) via Compose helper.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/CipherViewExtensions.kt Threads flag into owner naming in available owners list.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/util/CipherViewExtensionsTest.kt Updates mapping tests to include the new flag parameter.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/components/CollectionItemSelector.kt Gates collections/shared-folders section labels and empty text.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/movetoorganization/VaultMoveToOrganizationViewModel.kt Injects FeatureFlagManager and updates UI state when the flag changes.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/movetoorganization/VaultMoveToOrganizationViewModelTest.kt Adds flag manager mocking and new state parameter coverage.
app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/movetoorganization/VaultMoveToOrganizationContent.kt Gates strings shown in the move-to-organization UI via Compose helper.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/movetoorganization/VaultMoveToOrganizationScreenTest.kt Updates screen test state to include isVfo1FoundationEnabled.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsScreen.kt Gates “My folders/Folders” settings row label.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/folders/FoldersScreen.kt Gates folders screen title.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt Injects FeatureFlagManager and threads flag into search mapping.
app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModelTest.kt Mocks FeatureFlagManager for VFO-1 flag in search tests.
app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt Gates trailing icons in search results mapping via the flag.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultScreenTest.kt Passes feature flags state into compose test content.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt Passes feature flags state into compose test content.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemScreenTest.kt Passes feature flags state into compose test content.
app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditScreenTest.kt Passes feature flags state into compose test content and updates default states.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 42 to 52
fun VaultData.toViewState(
isPremium: Boolean,
hasMasterPassword: Boolean,
isIconLoadingDisabled: Boolean,
baseIconUrl: String,
vaultFilterType: VaultFilterType,
restrictItemTypesPolicyOrgIds: List<String>,
validTotpIds: Set<String>,
isNewItemTypesEnabled: Boolean,
isVfo1FoundationEnabled: Boolean = true,
): VaultState.ViewState {
Comment on lines 123 to 135
@@ -131,6 +131,7 @@ fun VaultData.toViewState(
totpData: TotpData?,
isPremiumUser: Boolean,
restrictItemTypesPolicyOrgIds: List<String>,
isVfo1FoundationEnabled: Boolean = true,
): VaultItemListingState.ViewState {
Comment on lines 175 to 183
fun List<CipherListView>.toViewState(
searchTerm: String,
baseIconUrl: String,
hasMasterPassword: Boolean,
isIconLoadingDisabled: Boolean,
isAutofill: Boolean,
isPremiumUser: Boolean,
isVfo1FoundationEnabled: Boolean = true,
): SearchState.ViewState =
Comment on lines 42 to +47
BitwardenMultiSelectButton(
label = stringResource(id = BitwardenString.vault),
dialogTitle = stringResource(id = BitwardenString.filter_by_vault),
dialogTitle = vfo1Foundation(
stringResource(id = BitwardenString.filter_by_vault),
null,
),
@@ -40,7 +41,10 @@ fun VaultMoveToOrganizationContent(
item {
BitwardenMultiSelectButton(
label = stringResource(id = BitwardenString.vault),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ IMPORTANT: With the flag off this screen still shows VFO-1 "vault" terminology

Details and fix

dialogTitle on this same widget is gated, but the rest of the Organization→Vault rename (PR 7192) on this screen is not. With vfo1-foundation disabled the screen renders a mix of old and new wording:

Element Flag-off renders Pre-VFO-1
label (line 43) vault → "Vault" organization → "Organization"
supportingText (line 60) move_to_vault_desc → "Choose a vault…" move_to_org_desc
VaultMoveToOrganizationEmpty.kt:29 no_vaults_to_list → "No vaults to list." no_orgs_to_list
VaultMoveToOrganizationViewModel.appBarText move_to_vault → "Move to vault" move_to_organization → "Move to Organization"

…while the shared-folders header and the validation error on the same screen do fall back to "Collections" / "You must select at least one collection."

organization still exists in strings.xml, but move_to_org_desc, no_orgs_to_list, and move_to_organization were removed by PR 7192 and were not restored in this PR, so completing the gate needs those three strings added back alongside the ones already restored in d61ba4dd2.

*/
@Composable
@ReadOnlyComposable
fun <T> vfo1Foundation(new: T, old: T): T =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is neat!

isIconLoadingDisabled: Boolean,
isAutofill: Boolean,
isPremiumUser: Boolean,
isVfo1FoundationEnabled: Boolean = true,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this default value a bit risky?

label = stringResource(
id = vfo1Foundation(
BitwardenString.shared_folders,
BitwardenString.collections,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add names to these params?

text = stringResource(
id = vfo1Foundation(
BitwardenString.there_are_no_shared_folders_to_list,
BitwardenString.no_collections_to_list,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

id = BitwardenString.move,
id = vfo1Foundation(
BitwardenString.move,
BitwardenString.move_to_vault,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Names?

This branch's flag-off fallbacks for the Organization->Vault rename
were restored from main, which turned out to be incompletely reverted
(fixed separately in PM-41100). Corrects the "old" argument in three
existing vfo1Foundation() calls from move_to_vault to
move_to_organization, and gates two previously-hardcoded sites
(the Move-to-organization dropdown label/description and its
empty-state text) that were always showing "Vault" text regardless of
the flag. Adds the move_to_organization/move_to_org_desc/
no_orgs_to_list strings needed for the flag-off path.
Comment thread ui/src/main/res/values/strings.xml Outdated
<string name="move_to_organization">Move to Organization</string>
<string name="no_orgs_to_list">No organizations to list.</string>
<string name="move_to_org_desc">Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved.</string>
<string name="move_to_vault">Move to vault</string>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ DEBT: move_to_vault is added here but never referenced.

Details and fix

The flag-on path uses BitwardenString.move and the flag-off path uses BitwardenString.move_to_organization (matching main after #7220), so nothing reads move_to_vault. move_to_vault_desc and no_vaults_to_list are both still used by the flag-on path, but this one is dead.

Suggest dropping the line so the eventual flag cleanup doesn't have to reason about it.

Comment on lines +2746 to +2747
isVfo1FoundationEnabled = featureFlagManager
.getFeatureFlag(FlagKey.Vfo1Foundation),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ DEBT: Reading the flag here (not observing it) means flipping the kill switch leaves this screen in a mixed state until the vault data re-emits.

Details and fix

VaultItemListingContent resolves its section headers and group icons through vfo1Foundation(...) / LocalFeatureFlagsState, which recomposes as soon as MainViewModel observes the flag change. The per-row extraIconList comes from this toViewState call, which only re-runs on a new vaultDataStateFlow emission. So after the flag is flipped off, the header reads "Collections" while the rows still carry the ic_shared_folder icon and "Shared folders" content description.

Same shape in:

  • SearchViewModel.kt:1094
  • VaultItemViewModel.kt:197
  • VaultAddEditViewModelVfo1FoundationFlagUpdateReceive updates the boolean but never re-runs appendFolderAndOwnerData, so selectedOwner.name stays on the old value ("My vault" vs. the account email).

VaultViewModel.handleVfo1FoundationFlagUpdateReceive already shows the fix: observe getFeatureFlagFlow(FlagKey.Vfo1Foundation), store it in state, and re-derive the view state on update. Since the whole point of this flag is an instant kill switch, it'd be worth applying that pattern consistently.

Default isVfo1FoundationEnabled to false (matching the flag's kill-switch
default) instead of true, so any future call site that omits it fails safe.
Name the new/old arguments at every multi-line vfo1Foundation(...) call site
for readability, and drop the now-unreferenced move_to_vault string.
isAutofill: Boolean,
isFido2Creation: Boolean,
isPremiumUser: Boolean,
isVfo1FoundationEnabled: Boolean = true,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ DEBT: Private helpers still default isVfo1FoundationEnabled to true, inverting the kill-switch's safe default.

Details and fix

The public entry points were changed to = false in response to earlier review feedback, but the private helpers were not:

  • VaultItemListingDataExtensions.kt:462, :495, :537, :544
  • SearchTypeDataExtensions.kt:213, :236

Every current call site passes the value explicitly, so these defaults are unreachable today — but if a new call site omits the argument it silently gets VFO-1 terminology while vfo1-foundation is off, which is the opposite of what the kill switch is for.

Suggested fix: drop the default entirely on the private helpers (they are all called with an explicit argument), or set it to false to match the flag default and the public functions.

The public toViewState/toDisplayItem entry points were already flipped to
isVfo1FoundationEnabled = false, but their private per-item helpers in
VaultItemListingDataExtensions.kt and SearchTypeDataExtensions.kt still
defaulted to true, leaving an unreachable-today but unsafe default.
),
dialogState = null,
onlyShowCollections = false,
isVfo1FoundationEnabled = true,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ DEBT: This test renders a flag combination that can't occur in production, and drops flag-on coverage for this screen.

Details and fix

setup() calls setContent { … } without featureFlagsState, so BitwardenComposeTest supplies FeatureFlagsState()isVfo1FoundationEnabled = false. The state here sets it to true. The screen therefore renders half-old / half-new:

Element Source Renders
appBarText state.isVfo1FoundationEnabled = true "Move" / "Shared folders"
label, supportingText, collections header, empty text vfo1Foundation(...)LocalFeatureFlagsState = false "Organization", "Choose an organization that…", "Collections"

Because of that, the assertions at lines 139/149, 156/164, 204 and 236 had to be changed from the VFO-1 wording back to the pre-VFO-1 wording — so the flag-on rendering of those elements (the state that actually ships when the flag is enabled) is no longer asserted anywhere for this screen.

The other four screen tests touched by this PR (VaultAddEditScreenTest:140, VaultItemScreenTest:94, VaultItemListingScreenTest:136, VaultScreenTest:112) all pass featureFlagsState = FeatureFlagsState(isVfo1FoundationEnabled = true). Suggest doing the same here and restoring the original VFO-1 assertions, keeping the new the app bar title should display the old text when the flag is off test (or adding a second setContent variant) for the flag-off path.

…ization screen test

setup() left LocalFeatureFlagsState.isVfo1FoundationEnabled at its false
default while the mocked ViewModel state defaulted isVfo1FoundationEnabled
to true, so the screen rendered a half-old/half-new combination that can't
happen in production and the assertions had drifted to pre-VFO1 wording,
dropping flag-on coverage. Pass featureFlagsState explicitly to match the
other four screen tests and restore the VFO-1 wording assertions.
override val icon: Int
get() = BitwardenDrawable.ic_shared_folder
}
@DrawableRes override val icon: Int = BitwardenDrawable.ic_shared_folder,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ DEBT: icon defaults to the VFO-1 value, the last remaining flag default that isn't fail-safe.

Details and fix

Every other isVfo1FoundationEnabled parameter in this PR was flipped to default to the pre-VFO-1 value so an omitted argument fails safe. This default goes the other way: any construction that omits icon gets ic_shared_folder even with the kill switch off.

VaultItemViewModel.kt:208 is the only production caller and it passes icon explicitly, so there's no user-visible impact today — but the ItemHeader.kt previews (lines 481–532) and VaultItemScreenTest/VaultItemViewModelTest all rely on the default and silently render new terminology.

@DrawableRes override val icon: Int = BitwardenDrawable.ic_collections,

…FO1 value

icon defaulted to ic_shared_folder (the VFO-1 icon), the last remaining
non-fail-safe default in this gating work. The only production caller
(VaultItemViewModel) already passes the flag-derived icon explicitly, so
flip the default to ic_collections and pin the mockk stub matchers in
VaultItemViewModelTest that relied on the old default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request a Claude code review app:authenticator Bitwarden Authenticator app context app:password-manager Bitwarden Password Manager app context t:feature Change Type - Feature Development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants