Widget Tests: Org Hierarchy Navigator
epic-admin-portal-core-services-task-020 — Write Flutter widget tests for OrgHierarchyNavigator covering: initial render with mocked tree data, expand/collapse interactions, search field filtering, breadcrumb update on node selection, and WCAG semantic label presence. Verify selected-node event emissions trigger correct state in parent BLoC.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 6 - 158 tasks
Can start after Tier 5 completes
Implementation Notes
Inject the org tree via a Riverpod ProviderScope override pointing to a FakeOrgHierarchyRepository that returns a hardcoded tree. Use bloc_test's whenListen to set up BLoC state if the navigator reads from a BLoC. For breadcrumb testing, assert the displayed text matches the expected 'Org → Region → Chapter' format. For WCAG testing, wrap the widget under test in a MaterialApp with a Semantics tree and use expect(tester.getSemantics(find.byType(OrgTreeNode)), ...) assertions.
Keep mock tree fixtures small (3–5 nodes) to keep tests fast. The most common mistake with tree widgets is forgetting to call tester.pumpAndSettle() after an animated expand — use it consistently. If animations cause flakiness, consider wrapping expand transitions in a flag that disables animation in test mode.
Testing Requirements
Flutter widget tests using flutter_test and bloc_test. Use MockBloc or ProviderScope overrides to inject deterministic tree data. Test scenarios: (1) initial render with 3-level tree, (2) expand top-level node, (3) expand + collapse, (4) search filtering with match, (5) search with no match, (6) node selection updates breadcrumb, (7) node selection event fired to BLoC, (8) empty tree state, (9) single-node tree, (10) semantic label presence via find.bySemanticsLabel. Use tester.pump() and tester.tap() for interaction simulation.
Assert Semantics tree correctness using tester.getSemantics(). All tests must be deterministic and side-effect free.
OrgHierarchyNavigator rendering NHF's full 1,400-chapter tree in a single widget may cause Flutter frame-rate drops below 60 fps on mid-range devices, making the navigator unusable for NHF national admins.
Mitigation & Contingency
Mitigation: Implement lazy expansion: only load immediate children on node expand rather than the full tree upfront. Use virtual scrolling for long sibling lists. Test with a synthetic 1,400-node dataset on a low-end Android device during development.
Contingency: If lazy expansion is insufficient, replace the tree widget with a paginated drill-down navigator (select level → select child) that avoids rendering more than 50 nodes at a time.
Bufdir may update their required export column structure or file format during or after development. If the AdminExportService hardcodes the current Bufdir schema, any format change requires a code release rather than a config update.
Mitigation & Contingency
Mitigation: Drive the Bufdir column mapping from a configuration repository rather than hardcoded constants. Abstract column definitions into a named schema config so that format changes require only a config update and re-deployment without service logic changes.
Contingency: If Bufdir format changes post-launch, release a config update within one sprint. If the change is structural (new required sections), scope a targeted service update and communicate timeline to partner organisations.
Role transition side-effects in UserManagementService (e.g., certification expiry removing mentor from chapter listing, pause triggering coordinator notification) may interact with external services like HLF's website sync. Incomplete side-effect handling could leave the system in an inconsistent state.
Mitigation & Contingency
Mitigation: Model side-effects as explicit domain events published after the primary state change is persisted. Implement event handlers as idempotent operations so re-processing is safe. Write integration tests that assert all side-effects fire correctly for each role transition type.
Contingency: If a side-effect fails after the primary change is persisted, log the failure with full context and trigger a manual reconciliation alert to the on-call team. Provide an admin-accessible re-trigger action for failed side-effects.
If AdminStatisticsService cache TTL is set too long, org_admin may see significantly stale KPI values (e.g., a mentor newly paused an hour ago still appears as active), undermining trust in the dashboard.
Mitigation & Contingency
Mitigation: Default cache TTL to 5 minutes with a manual refresh action on the dashboard. Implement cache invalidation triggered by UserManagementService write operations that affect counted entities.
Contingency: If staleness causes org admin complaints post-launch, reduce TTL to 60 seconds and introduce a real-time Supabase subscription for high-impact counters (paused mentors, expiring certifications).