Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Comments

[PM-26063] Add Flight Recorder toast banner to Authenticator's item list#2151

Merged
matt-livefront merged 2 commits intomainfrom
matt/PM-26063-flight-recorder-toast-banner-bwa
Nov 19, 2025
Merged

[PM-26063] Add Flight Recorder toast banner to Authenticator's item list#2151
matt-livefront merged 2 commits intomainfrom
matt/PM-26063-flight-recorder-toast-banner-bwa

Conversation

@matt-livefront
Copy link
Collaborator

@matt-livefront matt-livefront commented Nov 18, 2025

🎟️ Tracking

PM-26063

📔 Objective

Adds the Flight Recorder's toast banner to Authenticator's item list when the Flight Recorder has been enabled.

📸 Screenshots

Simulator.Screen.Recording.-.iPhone.17.Pro.-.2025-11-18.at.11.48.31.mov

⏰ 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

@matt-livefront matt-livefront requested a review from a team as a code owner November 18, 2025 17:50
@claude
Copy link

claude bot commented Nov 18, 2025

Claude finished @matt-livefront's task —— View job


PR Review for PM-26063

PR Title and Description Quality

The PR title and description are clear and effective:

  • Title: Accurately describes the change (adding Flight Recorder toast banner to Authenticator's item list)
  • Objective: Well-explained with context
  • Screenshots: Excellent - video demonstration provided
  • Jira Reference: Properly linked
  • Test Plan: Referenced in the reminders checklist

Summary of Changes

This PR adds the Flight Recorder toast banner to the Authenticator app's item list view, matching similar functionality in the Password Manager app. The implementation follows established patterns and integrates with BitwardenKit's FlightRecorderToastBannerState.

Key Changes:

  • Added flightRecorderToastBanner state to ItemListState
  • Added new actions/effects for banner dismissal and navigation
  • Integrated ItemListCoordinatorDelegate for cross-tab navigation
  • Added .streamFlightRecorderLog effect to monitor recorder status
  • Updated coordinator hierarchy to support settings navigation

Findings

Finding 1: Duplicated toast binding in ItemListView

Major - Lines 48-51 and 55-58 in ItemListView.swift contain duplicate .toast() modifiers

The view has two identical toast bindings. The second one (originally at lines 59-62 before the Flight Recorder banner was added) should have been removed when the banner code was inserted.

Resolution: Remove the duplicate toast binding at lines 55-58. Keep only the first one at lines 48-51.

Location: AuthenticatorShared/UI/Vault/ItemList/ItemList/ItemListView.swift:48-58

View inline comment →


Finding 2: Missing test coverage for new functionality

⚠️ Minor - Codecov reports 12 lines missing coverage, primarily in test files and module updates

Missing Coverage Breakdown:

  • ItemListView+SnapshotTests.swift: 8 lines (test is disabled with disabletest_ prefix)
  • ItemListView.swift: 2 lines
  • TabModule.swift: 1 line
  • ItemListModule.swift: 1 line
Recommended Test Additions
  1. Enable and verify snapshot test (ItemListView+SnapshotTests.swift:45-52):

    // Currently disabled: disabletest_snapshot_flightRecorderToastBanner
    // Should be: test_snapshot_flightRecorderToastBanner
  2. Add ViewInspector test for banner interaction:

    func test_flightRecorderBanner_goToSettings_sendsAction() throws {
        processor.state.flightRecorderToastBanner.activeLog = FlightRecorderData.LogMetadata(...)
        // Find and tap the go to settings button
        // Assert .navigateToFlightRecorderSettings action sent
    }
  3. Verify coordinator tests cover the new delegate method:

    • AppCoordinatorTests.swift should test switchToSettingsTab(route:)
    • TabCoordinatorTests.swift should verify itemListDelegate parameter
    • ItemListCoordinatorTests.swift should test .flightRecorderSettings route

Locations:

  • AuthenticatorShared/UI/Vault/ItemList/ItemList/ItemListView+SnapshotTests.swift:45
  • AuthenticatorShared/UI/Vault/ItemList/ItemList/ItemListView.swift:59-68

View inline comment →


Finding 3: Potential navigation state inconsistency

💭 Inquiry - How is navigation handled when the Settings tab doesn't exist?

The ItemListCoordinator.navigate(to:) calls delegate?.switchToSettingsTab(route:) for the .flightRecorderSettings route. If the delegate is nil or the tab coordinator hasn't initialized the settings tab yet, the navigation silently fails.

Questions:

  • Should there be an assertion or error log if delegate is nil?
  • Is it possible for this to be called before TabCoordinator.start() completes?
  • Should switchToSettingsTab return a success boolean or throw an error?

Location: AuthenticatorShared/UI/Vault/ItemList/ItemListCoordinator.swift:89-90

View inline comment →


Finding 4: Architecture pattern compliance

🎨 Improvement - Consider adding DocC documentation for public delegate protocol

The ItemListCoordinatorDelegate protocol is well-implemented but could benefit from expanded documentation explaining:

  • When this method is called (user taps "Go to Settings" in Flight Recorder banner)
  • Expected behavior (switch tab + navigate to route)
  • Context (cross-tab navigation pattern)

Location: AuthenticatorShared/UI/Vault/ItemList/ItemListCoordinator.swift:11-16

View inline comment →


Good Practices Observed

  • Proper unidirectional data flow maintained throughout
  • Dependency injection via ServiceContainer used correctly
  • Consistent naming conventions for actions, effects, and routes
  • Test file co-location following project standards
  • Coordinator delegate pattern implemented cleanly
  • Mock implementations generated for testability

Action Items

Required Before Merge:

  1. ❌ Remove duplicate .toast() binding in ItemListView.swift (Finding 1)

Recommended:
2. ⚠️ Enable and verify test_snapshot_flightRecorderToastBanner snapshot test (Finding 2)
3. ⚠️ Add ViewInspector test for banner interaction (Finding 2)
4. 💭 Clarify navigation behavior when delegate is nil (Finding 3)
5. 🎨 Enhance DocC documentation for ItemListCoordinatorDelegate (Finding 4)


Comment on lines -60 to -63
.toast(store.binding(
get: \.toast,
send: ItemListAction.toastShown,
))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was duplicated from here:

.toast(store.binding(
get: \.toast,
send: ItemListAction.toastShown,
))

@github-actions
Copy link
Contributor

github-actions bot commented Nov 18, 2025

Logo
Checkmarx One – Scan Summary & Details37a9600e-5bb0-4498-9685-73028edf3391

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

@codecov
Copy link

codecov bot commented Nov 18, 2025

Codecov Report

❌ Patch coverage is 93.96985% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.04%. Comparing base (ed1dfd4) to head (d12804c).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...ItemList/ItemList/ItemListView+SnapshotTests.swift 0.00% 8 Missing ⚠️
...ared/UI/Vault/ItemList/ItemList/ItemListView.swift 84.61% 2 Missing ⚠️
...thenticatorShared/UI/Platform/Tabs/TabModule.swift 0.00% 1 Missing ⚠️
...catorShared/UI/Vault/ItemList/ItemListModule.swift 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2151      +/-   ##
==========================================
- Coverage   85.38%   84.04%   -1.35%     
==========================================
  Files        1726     1982     +256     
  Lines      145621   161180   +15559     
==========================================
+ Hits       124345   135459   +11114     
- Misses      21276    25721    +4445     

☔ 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.

fedemkr
fedemkr previously approved these changes Nov 18, 2025
// MARK: Tests

@MainActor
func disabletest_snapshot_flightRecorderToastBanner() {
Copy link

Choose a reason for hiding this comment

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

⚠️ Disabled snapshot test

This snapshot test is disabled (prefixed with disable). It should be enabled to provide visual regression coverage for the Flight Recorder banner.

Suggested change
func disabletest_snapshot_flightRecorderToastBanner() {
func test_snapshot_flightRecorderToastBanner() {

After enabling, run the snapshot tests to record the baseline image.

Comment on lines +89 to +90
case .flightRecorderSettings:
delegate?.switchToSettingsTab(route: .settings)
Copy link

Choose a reason for hiding this comment

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

💭 Navigation edge case consideration

If delegate is nil, this navigation silently fails. Consider whether this is acceptable behavior or if it should log a warning/error for debugging purposes.

Options:

  1. Keep as-is (silent failure)
  2. Add assertion in debug builds: assert(delegate != nil)
  3. Add error logging: if delegate == nil { errorReporter.log(...) }

This is likely fine as-is since the delegate should always be set during initialization, but worth considering for debugging.

Comment on lines +11 to +16
public protocol ItemListCoordinatorDelegate: AnyObject {
/// Called when the user needs to switch to the settings tab and navigate to a `SettingsRoute`.
///
/// - Parameter route: The route to navigate to in the settings tab.
///
func switchToSettingsTab(route: SettingsRoute)
Copy link

Choose a reason for hiding this comment

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

🎨 Documentation enhancement suggestion

Consider expanding the documentation to explain:

  • When called: User taps "Go to Settings" in the Flight Recorder toast banner
  • Expected behavior: The app should switch to the Settings tab and navigate to the specified route
  • Context: Used for cross-tab navigation from the item list
Suggested change
public protocol ItemListCoordinatorDelegate: AnyObject {
/// Called when the user needs to switch to the settings tab and navigate to a `SettingsRoute`.
///
/// - Parameter route: The route to navigate to in the settings tab.
///
func switchToSettingsTab(route: SettingsRoute)
/// A delegate of `ItemListCoordinator` that is notified when navigation events occur that
/// require coordination with other parts of the app.
///
/// This delegate is typically implemented by `AppCoordinator` to handle navigation
/// that crosses tab boundaries.
///
@MainActor
public protocol ItemListCoordinatorDelegate: AnyObject {
/// Called when the user needs to switch to the settings tab and navigate to a `SettingsRoute`.
///
/// This is primarily used when the user taps "Go to Settings" from the Flight Recorder
/// toast banner in the item list.
///
/// - Parameter route: The route to navigate to in the settings tab.
///
func switchToSettingsTab(route: SettingsRoute)
}

goToSettingsAction: {
store.send(.navigateToFlightRecorderSettings)
},
)
Copy link

Choose a reason for hiding this comment

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

Duplicate toast binding

There are two identical .toast() modifiers in this view (lines 48-51 and 55-58 in the final code). The second one at lines 55-58 should be removed since the toast binding is already applied at lines 48-51.

This duplication causes the same toast to be applied twice, which is unnecessary and could potentially cause issues.

@matt-livefront matt-livefront merged commit bdc2c53 into main Nov 19, 2025
34 of 42 checks passed
@matt-livefront matt-livefront deleted the matt/PM-26063-flight-recorder-toast-banner-bwa branch November 19, 2025 22:33
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