Skip to content

Conversation

@HankYuLinksys
Copy link
Collaborator

@HankYuLinksys HankYuLinksys commented Jan 15, 2026

User description

Summary

  • Extract focused providers from monolithic DashboardManagerProvider:
    • DeviceInfoProvider - device model and SKU information
    • EthernetPortsProvider - WAN/LAN port connection status
    • RouterTimeProvider - router local time
    • SystemStatsProvider - CPU/memory load and uptime
    • WifiRadiosProvider - WiFi radio settings and guest network info
    • SessionProvider - session management (login state, cloud connection, timeout)
  • Add new SessionService for session-related business logic
  • Add polling_helpers.dart utility for polling data extraction
  • Add comprehensive unit tests for all new providers and services
  • Fix undefined dashboardManagerProvider references in instant_verify_view.dart and wifi_bundle_provider.dart
  • Add --collect flag to run_screenshot_tests.dart for golden test collection
  • Remove deprecated DashboardManagerProvider, DashboardManagerState, and DashboardManagerService

PR Type

Enhancement, Tests, Refactoring


Description

  • Extract monolithic DashboardManagerProvider into six focused domain providers:

    • DeviceInfoProvider - device model and SKU information
    • EthernetPortsProvider - WAN/LAN port connection status
    • RouterTimeProvider - router local time
    • SystemStatsProvider - CPU/memory load and uptime
    • WifiRadiosProvider - WiFi radio settings and guest network info
    • SessionProvider - session management (login state, cloud connection, timeout)
  • Add new SessionService for session-related JNAP operations with error handling

  • Add polling_helpers.dart utility module for safe polling data extraction

  • Refactor DashboardHomeService to accept four focused state parameters instead of monolithic state

  • Update DashboardHomeProvider to watch multiple focused providers instead of single provider

  • Migrate all views and services to use new focused providers:

    • InstantVerifyView, InstantAdminView, LoginLocalView - use individual providers
    • WifiBundleProvider, DeviceFilteredListProvider - use focused providers
    • RouterProvider, AuthProvider, SelectNetworkView - use SessionProvider
  • Add comprehensive unit tests for all new providers and services (1,700+ lines of test coverage)

  • Add --collect flag to run_screenshot_tests.dart for golden file collection

  • Remove deprecated DashboardManagerProvider, DashboardManagerState, and DashboardManagerService


Diagram Walkthrough

flowchart LR
  DMP["DashboardManagerProvider<br/>(Monolithic)"]
  DIP["DeviceInfoProvider"]
  EPP["EthernetPortsProvider"]
  RTP["RouterTimeProvider"]
  SSP["SystemStatsProvider"]
  WRP["WifiRadiosProvider"]
  SP["SessionProvider"]
  SS["SessionService"]
  
  DMP -- "Extract device info" --> DIP
  DMP -- "Extract port status" --> EPP
  DMP -- "Extract router time" --> RTP
  DMP -- "Extract system stats" --> SSP
  DMP -- "Extract WiFi radios" --> WRP
  DMP -- "Extract session logic" --> SP
  SP -- "Uses" --> SS
  
  DIP --> PH["polling_helpers.dart"]
  EPP --> PH
  RTP --> PH
  SSP --> PH
  WRP --> PH
Loading

File Walkthrough

Relevant files
Tests
19 files
dashboard_home_service_test.dart
Update dashboard home service tests for focused providers

test/page/dashboard/services/dashboard_home_service_test.dart

  • Refactored test setup to use individual domain provider states
    (deviceInfoState, wifiRadiosState, ethernetPortsState,
    systemStatsState) instead of monolithic dashboardManagerState
  • Updated all test cases to create and pass separate state objects
    matching the new provider architecture
  • Modified service method calls to accept four focused parameters
    instead of single dashboardManagerState parameter
+144/-46
dashboard_home_provider_test.dart
Refactor dashboard home provider tests for domain providers

test/page/dashboard/providers/dashboard_home_provider_test.dart

  • Removed MockDashboardManagerNotifier class and replaced with
    individual provider overrides
  • Updated test setup to override deviceInfoProvider, wifiRadiosProvider,
    ethernetPortsProvider, and systemStatsProvider with values instead of
    notifiers
  • Modified all test assertions to verify individual domain states
    instead of monolithic state
  • Updated mock service to track separate state parameters
+108/-59
wifi_radios_provider_test.dart
Add comprehensive tests for wifi radios provider                 

test/core/data/providers/wifi_radios_provider_test.dart

  • New comprehensive test suite for wifiRadiosProvider with 297 lines of
    test coverage
  • Tests extraction of main radios and guest radios from polling data
  • Validates handling of missing data, JNAP errors, and state equality
  • Includes mock polling notifier for isolated provider testing
+297/-0 
system_stats_provider_test.dart
Add comprehensive tests for system stats provider               

test/core/data/providers/system_stats_provider_test.dart

  • New comprehensive test suite for systemStatsProvider with 298 lines of
    test coverage
  • Tests extraction of uptime, CPU load, and memory load from polling
    data
  • Validates handling of missing fields, JNAP errors, and state equality
  • Includes mock polling notifier for isolated provider testing
+298/-0 
session_provider_test.dart
Add comprehensive tests for session provider                         

test/core/data/providers/session_provider_test.dart

  • New comprehensive test suite for sessionProvider with 271 lines of
    test coverage
  • Tests session management operations: saveSelectedNetwork,
    checkRouterIsBack, checkDeviceInfo
  • Validates SharedPreferences persistence, serial number validation, and
    error handling
  • Tests fallback logic for missing serial numbers and service error
    propagation
+271/-0 
ethernet_ports_provider_test.dart
Add comprehensive tests for ethernet ports provider           

test/core/data/providers/ethernet_ports_provider_test.dart

  • New comprehensive test suite for ethernetPortsProvider with 251 lines
    of test coverage
  • Tests extraction of WAN and LAN port connection states from polling
    data
  • Validates handling of missing data, JNAP errors, and various
    connection states
  • Includes mock polling notifier for isolated provider testing
+251/-0 
router_time_provider_test.dart
Add comprehensive tests for router time provider                 

test/core/data/providers/router_time_provider_test.dart

  • New comprehensive test suite for routerTimeProvider with 218 lines of
    test coverage
  • Tests parsing of ISO 8601 time strings from polling data
  • Validates fallback to system time when data is unavailable or invalid
  • Tests error handling and various time format scenarios
+218/-0 
device_info_provider_test.dart
Add comprehensive tests for device info provider                 

test/core/data/providers/device_info_provider_test.dart

  • New comprehensive test suite for deviceInfoProvider with 206 lines of
    test coverage
  • Tests extraction of device info and SKU model number from polling data
  • Validates handling of missing data, JNAP errors, and state equality
  • Includes mock polling notifier for isolated provider testing
+206/-0 
session_service_test.dart
Add comprehensive tests for session service                           

test/core/data/services/session_service_test.dart

  • New comprehensive test suite for SessionService with 200 lines of test
    coverage
  • Tests checkRouterIsBack method with serial number validation and error
    handling
  • Tests checkDeviceInfo method with caching and API fallback logic
  • Validates error mapping from JNAP errors to service errors
+200/-0 
session_notifier_mocks.dart
Add generated mocks for session notifier                                 

test/mocks/session_notifier_mocks.dart

  • New generated mock file for SessionNotifier with 168 lines
  • Provides mock implementation for testing providers that depend on
    sessionProvider
  • Includes fake implementations for NotifierProviderRef and
    NodeDeviceInfo
+168/-0 
test_helper.dart
Update test helper for session provider migration               

test/common/test_helper.dart

  • Replaced MockDashboardManagerNotifier with MockSessionNotifier
  • Updated imports to use sessionProvider instead of
    dashboardManagerProvider
  • Removed DashboardManagerState import and related mock setup
  • Updated provider overrides to use new session provider
+5/-8     
dashboard_home_test_data.dart
Refactor test data builders for focused providers               

test/mocks/test_data/dashboard_home_test_data.dart

  • Refactored test data builders to create individual domain states
    instead of monolithic DashboardManagerState
  • Added separate builder methods: createDeviceInfoState(),
    createWifiRadiosState(), createEthernetPortsState(),
    createSystemStatsState()
  • Removed createDashboardManagerState(),
    createDashboardManagerStateWithGuest(), and
    createEmptyDashboardManagerState() methods
  • Updated imports to use new provider state classes
+55/-28 
wifi_bundle_provider_test.dart
Update wifi bundle provider tests for focused providers   

test/page/wifi_settings/providers/wifi_bundle_provider_test.dart

  • Removed MockDashboardManagerNotifier class and related mock setup
  • Updated test setup to override wifiRadiosProvider with value instead
    of notifier
  • Changed test data initialization to use WifiRadiosState directly
  • Simplified provider overrides by removing dashboard manager provider
+6/-16   
auth_provider_test.dart
Update auth provider tests to use session provider             

test/providers/auth/auth_provider_test.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated mock class from MockDashboardManagerNotifier to
    MockSessionNotifier
  • Changed provider override to use sessionProvider instead of
    dashboardManagerProvider
  • Updated comment referencing DashboardManager to reference
    SessionProvider
+7/-9     
dashboard_manager_test_state.dart
Rename dashboard manager test states to session provider 

test/test_data/dashboard_manager_test_state.dart

  • Renamed test state constants from dashboardManager* to
    sessionProvider*
  • Updated three test state constants: dashboardManagerChrry7TestState,
    dashboardManagerPinnacleTestState, dashboardManagerTestState
+3/-3     
dashboard_manager_test_data.dart
Rename dashboard manager test data to session test data   

test/mocks/test_data/dashboard_manager_test_data.dart

  • Renamed class from DashboardManagerTestData to SessionTestData
  • Updated documentation comment to reference SessionManagerService
    instead of DashboardManagerService
  • Maintains factory methods for creating JNAP mock responses
+2/-2     
_index.dart
Update mock exports to reference session notifier               

test/mocks/_index.dart

  • Updated export statement from dashboard_manager_notifier_mocks.dart to
    session_notifier_mocks.dart
  • Maintains mock export structure with renamed file reference
+1/-1     
login_local_view_test.dart
Update login view test to use session notifier mock           

test/page/login/localizations/login_local_view_test.dart

  • Updated mock reference from mockDashboardManagerNotifier to
    mockSessionNotifier
  • Changed method call to checkDeviceInfo(null) on session notifier mock
+1/-2     
session_notifier_spec.dart
Create mockito spec for session notifier                                 

test/mocks/mockito_specs/session_notifier_spec.dart

  • New mockito specification file for SessionNotifier
  • Generates mock implementation for session provider notifier
  • Imports SessionNotifier from session provider module
+5/-0     
Enhancement
14 files
wifi_bundle_provider.dart
Migrate wifi bundle provider to focused providers               

lib/page/wifi_settings/providers/wifi_bundle_provider.dart

  • Replaced dashboardManagerProvider with wifiRadiosProvider and
    ethernetPortsProvider
  • Updated build() method to read individual focused providers instead of
    monolithic state
  • Modified WiFi settings initialization to use wifiRadiosState and
    ethernetPortsState
  • Updated performFetch() to use ethernetPortsState for LAN connection
    check
+20/-19 
session_provider.dart
Add new session provider for session management                   

lib/core/data/providers/session_provider.dart

  • New provider file with SessionNotifier class (102 lines) for session
    management
  • Implements saveSelectedNetwork() to persist router selection to
    SharedPreferences
  • Implements checkRouterIsBack() to validate router connectivity and
    serial number
  • Implements checkDeviceInfo() to retrieve device info with caching
    support
  • Includes selectedNetworkIdProvider state provider for tracking active
    network
+102/-0 
session_service.dart
Add new session service for JNAP operations                           

lib/core/data/services/session_service.dart

  • New service file with SessionService class (98 lines) for
    session-related JNAP operations
  • Implements checkRouterIsBack() with serial number validation and error
    handling
  • Implements checkDeviceInfo() with caching support and API fallback
  • Includes _mapJnapError() helper to convert JNAP errors to service
    errors
  • Provides sessionServiceProvider for dependency injection
+98/-0   
dashboard_home_service.dart
Refactor dashboard home service for focused providers       

lib/page/dashboard/services/dashboard_home_service.dart

  • Updated buildDashboardHomeState() method signature to accept four
    focused parameters: deviceInfoState, wifiRadiosState,
    ethernetPortsState, systemStatsState
  • Replaced single dashboardManagerState parameter with individual domain
    states
  • Updated method implementation to read from appropriate focused states
  • Updated imports to use new provider state classes
+15/-9   
router_provider.dart
Migrate router provider to session provider                           

lib/route/router_provider.dart

  • Replaced dashboardManagerProvider with sessionProvider for session
    operations
  • Updated imports to use sessionProvider and deviceInfoProvider
  • Changed _getStateDeviceInfo() to read from deviceInfoProvider instead
    of dashboardManagerProvider
  • Updated all calls to session methods to use sessionProvider.notifier
+7/-6     
instant_verify_view.dart
Migrate instant verify view to focused providers                 

lib/page/instant_verify/views/instant_verify_view.dart

  • Replaced dashboardManagerProvider with individual focused providers:
    deviceInfoProvider, systemStatsProvider, routerTimeProvider,
    ethernetPortsProvider
  • Updated _deviceInfoCard() to read from separate providers for device
    info, system stats, and router time
  • Updated _portsCard() to use ethernetPortsProvider instead of dashboard
    manager provider
  • Updated imports to include new provider imports
+13/-9   
prepare_dashboard_view.dart
Migrate prepare dashboard view to session provider             

lib/page/dashboard/views/prepare_dashboard_view.dart

  • Replaced dashboardManagerProvider with sessionProvider for session
    operations
  • Updated imports to use sessionProvider instead of
    dashboardManagerProvider
  • Updated all calls to session methods to use sessionProvider.notifier
+4/-4     
run_screenshot_tests.dart
Add golden file collection feature to screenshot tests     

tools/run_screenshot_tests.dart

  • Added new --collect flag to enable golden file collection after tests
    complete
  • Implemented _copyGoldensToSnapshots() function to copy golden files
    from test directories to snapshots folder
  • Added conditional logic to invoke golden file collection when flag is
    set
+41/-1   
wifi_radios_provider.dart
Create new WiFi radios provider for radio settings             

lib/core/data/providers/wifi_radios_provider.dart

  • New provider extracting WiFi radio settings from polling data
  • Provides main radios, guest radios, and guest network enabled status
  • Uses polling_helpers.dart utility for data extraction
  • Implements WifiRadiosState with equatable for state management
+51/-0   
device_info_provider.dart
Create new device info provider for device details             

lib/core/data/providers/device_info_provider.dart

  • New provider extracting device information from polling data
  • Provides device info and SKU model number
  • Uses polling_helpers.dart utility for data extraction
  • Implements DeviceInfoState with equatable for state management
+45/-0   
system_stats_provider.dart
Create new system stats provider for performance metrics 

lib/core/data/providers/system_stats_provider.dart

  • New provider extracting system statistics from polling data
  • Provides uptime, CPU load, and memory load information
  • Uses polling_helpers.dart utility for data extraction
  • Implements SystemStatsState with equatable for state management
+41/-0   
ethernet_ports_provider.dart
Create new ethernet ports provider for port status             

lib/core/data/providers/ethernet_ports_provider.dart

  • New provider extracting Ethernet port connection status from polling
    data
  • Provides WAN port connection and LAN port connections list
  • Uses polling_helpers.dart utility for data extraction
  • Implements EthernetPortsState with equatable for state management
+37/-0   
router_time_provider.dart
Create new router time provider for local time                     

lib/core/data/providers/router_time_provider.dart

  • New provider extracting router's local time from polling data
  • Returns milliseconds since epoch for router time
  • Falls back to system time if router time unavailable
  • Uses polling_helpers.dart utility for data extraction
+27/-0   
polling_helpers.dart
Create polling helpers utility for data extraction             

lib/core/data/providers/polling_helpers.dart

  • New utility module for extracting polling data
  • Provides getPollingOutput() function to safely extract action output
    from polling data
  • Includes internal _getPollingSuccess() helper for result validation
  • Handles null checks and error cases gracefully
+24/-0   
Refactoring
11 files
instant_verify_pdf_service.dart
Split dashboard manager into focused providers in PDF service

lib/page/instant_verify/services/instant_verify_pdf_service.dart

  • Replaced monolithic dashboardManagerProvider import with focused
    deviceInfoProvider and systemStatsProvider
  • Updated state variable names from dashboardState to deviceInfoState
    and systemStatsState
  • Refactored property access to use appropriate provider states (e.g.,
    systemStatsState.uptimes, deviceInfoState.skuModelNumber)
+8/-6     
instant_admin_view.dart
Migrate instant admin view to device info provider             

lib/page/instant_admin/views/instant_admin_view.dart

  • Replaced dashboardManagerProvider and dashboardManagerState imports
    with deviceInfoProvider
  • Updated state variable from dashboardManagerState to deviceInfoState
  • Changed method parameter type from DashboardManagerState to
    DeviceInfoState
  • Updated property access to use deviceInfoState.skuModelNumber and
    deviceInfoState.deviceInfo
+6/-7     
dashboard_home_provider.dart
Refactor dashboard home to use focused providers                 

lib/page/dashboard/providers/dashboard_home_provider.dart

  • Replaced single dashboardManagerProvider with four focused providers:
    deviceInfoProvider, wifiRadiosProvider, ethernetPortsProvider,
    systemStatsProvider
  • Updated DashboardHomeNotifier.build() to watch multiple focused
    providers instead of monolithic provider
  • Refactored service call to pass individual state objects instead of
    combined dashboard state
+12/-3   
login_local_view.dart
Update login view to use session provider                               

lib/page/login/views/login_local_view.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated provider reference from dashboardManagerProvider.notifier to
    sessionProvider.notifier
  • Simplified method call to checkDeviceInfo(null) on session provider
+2/-5     
home_title.dart
Migrate home title widget to router time provider               

lib/page/dashboard/views/components/widgets/home_title.dart

  • Replaced dashboardManagerProvider import with routerTimeProvider
  • Updated state variable from state to routerTime with appropriate type
  • Changed time extraction to use routerTimeProvider directly instead of
    accessing nested property
+3/-3     
auth_provider.dart
Update auth provider to use session provider                         

lib/providers/auth/auth_provider.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated provider reference from dashboardManagerProvider.notifier to
    sessionProvider.notifier
  • Updated comment to reference session provider instead of dashboard
    manager
+3/-3     
select_network_view.dart
Update select network view to use session provider             

lib/page/select_network/views/select_network_view.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated provider reference from dashboardManagerProvider.notifier to
    sessionProvider.notifier
  • Simplified method call to saveSelectedNetwork() on session provider
+4/-5     
devices_filter_widget.dart
Migrate devices filter widget to WiFi radios provider       

lib/page/instant_device/views/devices_filter_widget.dart

  • Replaced dashboardManagerProvider import with wifiRadiosProvider
  • Updated provider watch from dashboardManagerProvider to
    wifiRadiosProvider
  • Changed property access to use mainRadios from focused provider
+2/-2     
device_filtered_list_provider.dart
Update device filter config to use WiFi radios provider   

lib/page/instant_device/providers/device_filtered_list_provider.dart

  • Replaced dashboardManagerProvider import with wifiRadiosProvider
  • Updated provider reference from dashboardManagerProvider to
    wifiRadiosProvider
  • Changed property access to use mainRadios from focused provider
+2/-2     
dialogs.dart
Update dialogs to use session provider                                     

lib/page/components/shortcuts/dialogs.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated provider reference from dashboardManagerProvider.notifier to
    sessionProvider.notifier
  • Changed method call to checkRouterIsBack() on session provider
+2/-2     
router_repository.dart
Update router repository to use session provider                 

lib/core/jnap/router_repository.dart

  • Replaced dashboardManagerProvider import with sessionProvider
  • Updated provider reference to use new session provider
+1/-1     
Miscellaneous
1 files
app.dart
Update app comments to reference session provider               

lib/app.dart

  • Updated commented code reference from dashboardManagerProvider to
    sessionProvider
  • Maintains existing commented-out functionality with updated provider
    name
+1/-1     
Additional files
9 files
dashboard_manager_provider.dart +0/-55   
dashboard_manager_state.dart +0/-131 
dashboard_manager_service.dart +0/-211 
dashboard_manager_provider_test.dart +0/-323 
dashboard_manager_state_test.dart +0/-367 
dashboard_manager_service_test.dart +0/-364 
dashboard_manager_notifier_mocks.dart +0/-230 
dashboard_manager_notifier_spec.dart +0/-5     
dashboard_home_view_test.dart +0/-5     

…ManagerProvider

- Extract device info data into dedicated `deviceInfoProvider`
- Extract ethernet ports data into `ethernetPortsProvider`
- Extract router time data into `routerTimeProvider`
- Extract system stats data into `systemStatsProvider`
- Extract WiFi radios data into `wifiRadiosProvider`
- Add `polling_helpers.dart` for shared polling data extraction utilities
- Rename `DashboardManagerProvider` to `SessionProvider` for session operations
- Rename `DashboardManagerService` to `SessionService` for clarity
- Update all consumers to use new focused providers
- Add comprehensive unit tests for all new providers
- Remove obsolete `DashboardManagerState` and related files
- Add new `--collect` / `-p` flag to collect golden files after tests
- Implement `_copyGoldensToSnapshots()` function to copy all golden files from test directories to snapshots folder
- Fix issue where golden files were never collected when using the Dart tool (since it always passes `-f` to shell script)
…netPortsProvider

- Fix instant_verify_view.dart using undefined dashboardManagerProvider
- Fix wifi_bundle_provider.dart using undefined dashboardManagerProvider
@qodo-code-review
Copy link

qodo-code-review bot commented Jan 15, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Insecure local storage

Description: The new flow persists serialNumber and networkId via
sessionProvider.notifier.saveSelectedNetwork(...), which (per accompanying tests) stores
values in SharedPreferences, meaning potentially sensitive identifiers can be retained
unencrypted on-device and be recoverable from app storage on compromised devices or via
device backups.
router_provider.dart [410-456]

Referred Code
      return null;
    }
    await _ref
        .read(sessionProvider.notifier)
        .saveSelectedNetwork(serialNumber, '');
  } else if (_ref.read(selectedNetworkIdProvider) == null) {
    _ref.read(selectNetworkProvider.notifier).refreshCloudNetworks();
    if (networkId == null || serialNumber == null) {
      return RoutePath.selectNetwork;
    }
    await _ref
        .read(sessionProvider.notifier)
        .saveSelectedNetwork(serialNumber, networkId);
  }
  return null;
}

Future<String?> _prepareLocal(String? serialNumber) async {
  logger.i('[Prepare]: local - $serialNumber');
  // If auto parent first login, then go to auto parent first login page
  final autoParentFirstLogin = _ref.read(autoParentFirstLoginStateProvider);


 ... (clipped 26 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Login events logging: The diff shows new session management logic/tests but does not include the corresponding
implementation changes needed to verify that login/session-critical events are
consistently audit-logged with user ID, timestamp, action, and outcome.

Referred Code

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Secrets-like strings: The newly added tests include WiFi passphrase-like fields (e.g., passphrase,
guestWPAPassphrase) which may be acceptable dummy data but should be verified to not
mirror real credentials and to ensure no production logging would ever emit such values.

Referred Code
      'wpaPersonalSettings': {
        'passphrase': 'password123',
      },
    },
  });
}
if (radioCount >= 2) {
  radios.add({
    'radioID': 'RADIO_5GHz',
    'physicalRadioID': 'wl1',
    'bssid': 'AA:BB:CC:DD:EE:02',
    'band': '5GHz',
    'supportedModes': const ['802.11a/n/ac'],
    'supportedChannelsForChannelWidths': const [
      {
        'channelWidth': 'Auto',
        'channels': [36, 40, 44, 48],
      }
    ],
    'supportedSecurityTypes': const ['None', 'WPA2-Personal'],
    'maxRADIUSSharedKeyLength': 64,


 ... (clipped 44 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Credential-like test data: The new test fixtures store credential-like values (e.g., wpaPersonalSettings.passphrase
and guestWPAPassphrase) which requires confirmation that these are non-sensitive
placeholders and that the actual providers/services never persist or expose real secrets
unsafely.

Referred Code
    'settings': {
      'isEnabled': true,
      'mode': '802.11b/g/n',
      'ssid': 'TestNetwork-2.4',
      'broadcastSSID': true,
      'channelWidth': 'Auto',
      'channel': 6,
      'security': 'WPA2-Personal',
      'wpaPersonalSettings': {
        'passphrase': 'password123',
      },
    },
  });
}
if (radioCount >= 2) {
  radios.add({
    'radioID': 'RADIO_5GHz',
    'physicalRadioID': 'wl1',
    'bssid': 'AA:BB:CC:DD:EE:02',
    'band': '5GHz',
    'supportedModes': const ['802.11a/n/ac'],


 ... (clipped 53 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

qodo-code-review bot commented Jan 15, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure test override uses updated state
Suggestion Impact:The test setup was refactored so radio test data is created first, then wifiRadiosState is assigned before a new ProviderContainer is created with wifiRadiosProvider.overrideWithValue(wifiRadiosState). This ensures the override receives the correct, updated state (matching the suggestion’s intent). Additional unrelated changes include adding an ethernetPortsProvider override.

code diff:

-  void seedWithRadios() {
+  /// Creates test data for radios and returns both RouterRadios and WiFiItems.
+  (List<RouterRadio>, List<WiFiItem>) createRadiosTestData() {
     final radios = [
       RouterRadio(
           radioID: 'RADIO_2.4GHz',
           physicalRadioID: '1',
           bssid: '00:00:00:00:00:01',
           band: '2.4GHz',
-          supportedModes: const [], // Empty to avoid crash
+          supportedModes: const [],
           supportedChannelsForChannelWidths: const [],
           supportedSecurityTypes: [WifiSecurityType.wpa2Personal.value],
           maxRadiusSharedKeyLength: 64,
@@ -162,9 +165,7 @@
               channel: 36,
               security: WifiSecurityType.wpa2Personal.value)),
     ];
-    wifiRadiosState = WifiRadiosState(mainRadios: radios);
-
-    // Create WiFiItems matching the seeded radios for the mock
+
     final wifiItems = [
       WiFiItem.fromMap(const {
         'radioID': 'RADIO_2.4GHz',
@@ -192,7 +193,20 @@
       }),
     ];
 
-    // Stub createInitialWifiListSettings to return the matching WiFiItems
+    return (radios, wifiItems);
+  }
+
+  /// Seeds the container with radio data by:
+  /// 1. Creating test data first
+  /// 2. Setting up the mock stub
+  /// 3. Creating a NEW container with the proper state override
+  void seedWithRadios() {
+    final (radios, wifiItems) = createRadiosTestData();
+
+    // First: Prepare the state BEFORE creating the container
+    wifiRadiosState = WifiRadiosState(mainRadios: radios);
+
+    // Second: Set up mock stub to return matching WiFiItems
     when(() => mockWifiSettingsService.createInitialWifiListSettings(
           mainRadios: any(named: 'mainRadios'),
           isGuestNetworkEnabled: any(named: 'isGuestNetworkEnabled'),
@@ -209,17 +223,19 @@
       simpleModeWifi: wifiItems.first,
     ));
 
-    // Re-create container to pick up new stub
+    // Third: Create container with the prepared state
     container = ProviderContainer(
       overrides: [
         wifiSettingsServiceProvider.overrideWithValue(mockWifiSettingsService),
         wifiRadiosProvider.overrideWithValue(wifiRadiosState),
+        ethernetPortsProvider.overrideWithValue(const EthernetPortsState()),
         dashboardHomeProvider.overrideWith(() => mockDashboardHomeNotifier),
         deviceManagerProvider.overrideWith(() => mockDeviceManagerNotifier),
         routerRepositoryProvider.overrideWithValue(mockRouterRepository),
       ],
     );
-    // Trigger build
+
+    // Trigger build to initialize provider
     container.read(wifiBundleProvider);
   }

Fix the test logic by assigning data to wifiRadiosState before creating the
ProviderContainer to ensure the provider override receives the correct test
data.

test/page/wifi_settings/providers/wifi_bundle_provider_test.dart [113-165]

+// First seed the radios state
+wifiRadiosState = WifiRadiosState(mainRadios: radios);
+// Then create the container with the proper override
 container = ProviderContainer(
   overrides: [
     wifiSettingsServiceProvider.overrideWithValue(mockWifiSettingsService),
     wifiRadiosProvider.overrideWithValue(wifiRadiosState),
     dashboardHomeProvider.overrideWith(() => mockDashboardHomeNotifier),
     // ...
   ],
 );
-// later in the same test
-wifiRadiosState = WifiRadiosState(mainRadios: radios);

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical logic error in the test setup where the ProviderContainer is created with stale data, which would cause the test to fail or produce incorrect results.

High
Watch providers for reactivity

In the build method, replace ref.read with ref.watch to ensure the provider
rebuilds reactively when its dependencies change.

lib/page/wifi_settings/providers/wifi_bundle_provider.dart [34-38]

 @override
 WifiBundleState build() {
-  final wifiRadiosState = ref.read(wifiRadiosProvider);
-  final deviceManagerState = ref.read(deviceManagerProvider);
-  final ethernetPortsState = ref.read(ethernetPortsProvider);
+  final wifiRadiosState = ref.watch(wifiRadiosProvider);
+  final deviceManagerState = ref.watch(deviceManagerProvider);
+  final ethernetPortsState = ref.watch(ethernetPortsProvider);
   // ...

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that ref.read is used in a build method where ref.watch is needed for reactivity, which is a fundamental concept in Riverpod and crucial for the UI to update correctly.

Medium
Use safe parsing for numeric data

Replace the unsafe cast as int? with int.tryParse to safely parse the
uptimeSeconds value and prevent potential runtime errors.

lib/core/data/providers/system_stats_provider.dart [14-19]

 final statsOutput = getPollingOutput(pollingData, JNAPAction.getSystemStats);
 if (statsOutput != null) {
-  uptimes = statsOutput['uptimeSeconds'] as int? ?? 0;
+  uptimes = int.tryParse(statsOutput['uptimeSeconds']?.toString() ?? '') ?? 0;
   cpuLoad = statsOutput['CPULoad'] as String?;
   memoryLoad = statsOutput['MemoryLoad'] as String?;
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a potential runtime TypeError due to an unsafe cast and provides a more robust solution using int.tryParse, improving the code's resilience to variations in API data.

Medium
Safely convert list from API response

Use .whereType().toList() to safely create the lanConnections list, preventing
runtime errors if the API response contains non-string elements.

lib/core/data/providers/ethernet_ports_provider.dart [13-18]

 final portsOutput =
     getPollingOutput(pollingData, JNAPAction.getEthernetPortConnections);
 if (portsOutput != null) {
   wanConnection = portsOutput['wanPortConnection'] as String?;
-  lanConnections = List<String>.from(portsOutput['lanPortConnections'] ?? []);
+  lanConnections = (portsOutput['lanPortConnections'] as List?)
+          ?.whereType<String>()
+          .toList() ??
+      [];
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out a potential runtime error when creating a list from dynamic API data and proposes a safer alternative using whereType<String>() to prevent crashes.

Medium
General
Use DateTime.parse for ISO-8601

Replace the custom DateFormat with the standard DateTime.parse inside a
try-catch block for more reliable parsing of the ISO-8601 timestamp.

lib/core/data/providers/router_time_provider.dart [14-24]

 final timeOutput = getPollingOutput(pollingData, JNAPAction.getLocalTime);
 if (timeOutput != null) {
   final timeString = timeOutput['currentTime'] as String?;
   if (timeString != null) {
-    final parsedTime =
-        DateFormat("yyyy-MM-ddThh:mm:ssZ").tryParse(timeString);
-    if (parsedTime != null) {
+    try {
+      final parsedTime = DateTime.parse(timeString);
       return parsedTime.millisecondsSinceEpoch;
+    } catch (_) {
+      // fall through to system clock
     }
   }
 }
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the custom DateFormat is incorrect and brittle, proposing the use of the standard DateTime.parse, which is the idiomatic and more robust solution for this task.

Medium
Remove unused parameter from method

Remove the unused serialNumber parameter from the checkDeviceInfo method
signature to avoid confusion.

lib/core/data/providers/session_provider.dart [68-76]

-Future<NodeDeviceInfo> checkDeviceInfo(String? serialNumber) async {
+Future<NodeDeviceInfo> checkDeviceInfo() async {
   final benchMark = BenchMarkLogger(name: 'checkDeviceInfo');
   benchMark.start();
   final service = ref.read(sessionServiceProvider);
   final cachedDeviceInfo = ref.read(deviceInfoProvider).deviceInfo;
   final nodeDeviceInfo = await service.checkDeviceInfo(cachedDeviceInfo);
   benchMark.end();
   return nodeDeviceInfo;
 }
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies an unused parameter in a new method, and removing it improves code clarity and maintainability.

Low
Remove redundant logging statement

Remove the redundant logger.i call from saveSelectedNetwork to improve clarity
and rely on the more descriptive logger.d statement.

lib/core/data/providers/session_provider.dart [85-93]

 Future<void> saveSelectedNetwork(
     String serialNumber, String networkId) async {
-  logger.i('[Session]: saveSelectedNetwork - $networkId, $serialNumber');
   final pref = await SharedPreferences.getInstance();
   logger.d('[Session]: save selected network - $serialNumber, $networkId');
   await pref.setString(pCurrentSN, serialNumber);
   await pref.setString(pSelectedNetworkId, networkId);
   ref.read(selectedNetworkIdProvider.notifier).state = networkId;
 }
  • Apply / Chat
Suggestion importance[1-10]: 2

__

Why: The suggestion correctly points out redundant logging, and the proposed change improves code cleanliness, which is a minor but valid improvement.

Low
  • Update

…vider_test

- Add import for pref_key.dart constants
- Replace hardcoded 'currentSN' with pCurrentSN constant
- Replace hardcoded 'selectedNetworkId' with pSelectedNetworkId constant
- Replace hardcoded 'pnpConfiguredSN' with pPnpConfiguredSN constant
… test design

- Add ethernetPortsProvider mock override to match provider dependencies
- Extract createRadiosTestData() helper function for test data creation
- Refactor seedWithRadios() to properly set state before container creation
- Add documentation comments explaining the test setup sequence
Copy link
Collaborator

@AustinChangLinksys AustinChangLinksys left a comment

Choose a reason for hiding this comment

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

Looks good to me

@AustinChangLinksys AustinChangLinksys merged commit 56eeccd into dev-2.0.0 Jan 16, 2026
2 checks passed
@AustinChangLinksys AustinChangLinksys deleted the refactoring-dashboard-manager branch January 16, 2026 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants