Skip to content

Conversation

@LRNcardozoWDF
Copy link
Member

@LRNcardozoWDF LRNcardozoWDF commented Nov 28, 2025

🎟️ Tracking

PM-25906

📔 Objective

Add tests for account switcher for iOS 26.

📸 Screenshots

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@LRNcardozoWDF LRNcardozoWDF requested review from a team and matt-livefront as code owners November 28, 2025 04:40
@claude
Copy link

claude bot commented Nov 28, 2025

Claude finished @LRNcardozoWDF's task —— View job


Code Review Complete

Summary

This PR adds comprehensive test coverage for account switcher visibility on iOS 26. The changes add 1207 lines across 5 test files, providing parallel iOS 26 test coverage for profile switcher functionality previously only tested on iOS <26.

However, there are critical test setup ordering issues in 2 files that will cause these tests to fail or produce incorrect results.


Critical Issues

Finding 1: Test setup ordering violation in VaultItemSelectionProcessorTests

Location: BitwardenShared/UI/Vault/Vault/VaultItemSelection/VaultItemSelectionProcessorTests.swift:164-189

The test test_perform_profileSwitcher_accountPressed_iOS26() configures mock data after performing the action being tested:

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
authRepository.activeAccount = .fixture(profile: .fixture(userId: "42"))  // ❌ Too late!
authRepository.altAccounts = [.fixture()]  // ❌ Too late!
authRepository.vaultTimeout = [...]  // ❌ Too late!

Impact: The mocks are configured after perform() executes, meaning the test runs with uninitialized/default mock values. This produces false positive results.

Fix: Move lines 173-180 above line 172 (before the await subject.perform() call).

Reference: Per Testing.md:1033-1037, tests must follow "Arrange-Act-Assert" ordering: configure mocks → perform action → verify results.


Finding 2: Identical test setup ordering violation in VaultAutofillListProcessorTests

Location: BitwardenShared/UI/Vault/Vault/AutofillList/VaultAutofillListProcessorTests.swift:192-212

The test test_perform_profileSwitcher_accountPressed_iOS26() has the same ordering issue:

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
authRepository.activeAccount = .fixture(profile: .fixture(userId: "42"))  // ❌ Too late!
authRepository.altAccounts = [.fixture()]  // ❌ Too late!
authRepository.vaultTimeout = [...]  // ❌ Too late!

Impact: Same as Finding 1 - the test executes with uninitialized mocks.

Fix: Move lines 201-208 above line 200 (before the await subject.perform() call).


PR Title and Description

💭 The PR title and description are adequate but could be improved:

Title: Currently "PM-25906 Add account switcher visibility tests"

  • ✅ Clear and specific
  • ✅ References Jira ticket
  • ⚠️ Could be more precise: "Add iOS 26 account switcher visibility tests"

Description:

  • ✅ Includes Jira reference
  • ✅ Has clear objective
  • ⚠️ Missing screenshots/recordings (expected for UI changes per review guidelines)
  • ⚠️ Objective could be more specific about what was backfilled
Suggested improvements

Title:

[PM-25906] Add iOS 26 account switcher visibility tests

Objective section:

## 📔 Objective

Backfill test coverage for iOS 26 account switcher visibility behavior. The account switcher on iOS 26 uses a new sheet-based presentation that requires different dismiss handling compared to iOS <26. This PR adds parallel iOS 26 tests for:
- Profile switcher visibility toggling
- Account switching with proper dismissal
- Lock/logout actions with sheet dismissal
- Error handling with sheet cleanup

Tests use `#available(iOS 26, *)` guards and XCTSkip for proper version gating.

Good Practices Observed

  • Consistent use of #available(iOS 26, *) guards with XCTSkip for version-specific testing
  • TODOs removed from pre-iOS 26 tests (good cleanup)
  • Test naming follows established patterns (test_perform_X_Y_iOS26)
  • Proper test documentation with multi-line comments
  • Tests verify dismissal behavior specific to iOS 26 sheet presentation

Action Items

  1. MUST FIX: Correct test setup ordering in VaultItemSelectionProcessorTests.swift:164-189
  2. MUST FIX: Correct test setup ordering in VaultAutofillListProcessorTests.swift:192-212
  3. 🎨 OPTIONAL: Enhance PR title to mention "iOS 26" explicitly
  4. 🎨 OPTIONAL: Expand objective section with more context about the iOS 26 sheet behavior

@github-actions
Copy link
Contributor

github-actions bot commented Nov 28, 2025

Logo
Checkmarx One – Scan Summary & Details728a1030-f219-487d-ba84-b76eba5b5807

Great job! No new security vulnerabilities introduced in this pull request

@codecov
Copy link

codecov bot commented Nov 28, 2025

Codecov Report

❌ Patch coverage is 96.22642% with 40 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.57%. Comparing base (8ce5d66) to head (d95a520).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...I/Auth/VaultUnlock/VaultUnlockProcessorTests.swift 96.66% 14 Missing ⚠️
...Shared/UI/Auth/Landing/LandingProcessorTests.swift 96.61% 11 Missing ⚠️
...ault/Vault/VaultList/VaultListProcessorTests.swift 96.08% 9 Missing ⚠️
...AutofillList/VaultAutofillListProcessorTests.swift 92.30% 3 Missing ⚠️
...emSelection/VaultItemSelectionProcessorTests.swift 93.47% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2168      +/-   ##
==========================================
+ Coverage   85.39%   85.57%   +0.18%     
==========================================
  Files        1731     1731              
  Lines      145718   146774    +1056     
==========================================
+ Hits       124433   125606    +1173     
+ Misses      21285    21168     -117     

☔ View full report in Codecov by Sentry.
📢 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.

}

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
Copy link

Choose a reason for hiding this comment

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

Test setup ordering issue: Mock data is configured AFTER the action is performed (line 173), but these values should be set up BEFORE calling perform() on line 173.

The lines 174-181 should be moved above line 172. The test setup should follow this order:

  1. Configure all mock dependencies and initial state
  2. Perform the action being tested
  3. Assert the results

This same issue appears in VaultAutofillListProcessorTests.swift:test_perform_profileSwitcher_accountPressed_iOS26() at line 201.

}

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
Copy link

Choose a reason for hiding this comment

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

Test setup ordering issue: Same problem as in VaultItemSelectionProcessorTests.swift - mock data (lines 202-209) is configured AFTER the action is performed (line 201).

Move lines 202-209 above line 200 to ensure proper test setup order.

}

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
Copy link

Choose a reason for hiding this comment

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

Critical: Test setup ordering violation

Mock data is configured AFTER the action is performed. Lines 173-180 must be moved above line 172.

Current (incorrect) order:

  1. Set state (line 171) ✅
  2. Perform action (line 172) ❌ Too early!
  3. Configure mocks (lines 173-180) ❌ Too late!

Correct order should be:

  1. Set state
  2. Configure all mocks (activeAccount, altAccounts, vaultTimeout)
  3. Then perform action
  4. Assert results

This follows the standard Arrange-Act-Assert pattern (Testing.md:1033-1037). Currently the test runs with uninitialized mock values, producing incorrect results.

Suggested change
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
authRepository.activeAccount = .fixture(profile: .fixture(userId: "42"))
authRepository.altAccounts = [
.fixture(),
]
authRepository.vaultTimeout = [
"1": .fiveMinutes,
"42": .immediately,
]

}

subject.state.profileSwitcherState.isVisible = true
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
Copy link

Choose a reason for hiding this comment

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

Critical: Test setup ordering violation

Same issue as VaultItemSelectionProcessorTests - mock data (lines 201-208) is configured AFTER the action is performed (line 200).

Move lines 201-208 above line 200 to ensure mocks are configured before the test executes.

Suggested change
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
await subject.perform(.profileSwitcher(.accountPressed(ProfileSwitcherItem.fixture(userId: "1"))))
authRepository.activeAccount = .fixture(profile: .fixture(userId: "42"))
authRepository.altAccounts = [
.fixture(),
]
authRepository.vaultTimeout = [
"1": .fiveMinutes,
"42": .immediately,
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants