high priority medium complexity testing pending testing specialist Tier 7

Acceptance Criteria

Widget test verifies that the bottom sheet renders with the correct list of chapters available to the authenticated user
Tapping a chapter row dispatches a state update to ActiveChapterState (or equivalent BLoC/Riverpod provider) with the correct chapter ID
Integration test: after selecting a chapter, the app's active chapter persists after a simulated app restart (SharedPreferences or equivalent storage is written and re-read)
After chapter switch, at least one downstream widget that displays chapter-specific data rebuilds with data scoped to the newly selected chapter
All chapter list items have a touch target of at least 48×48 dp (WCAG 2.2 AA minimum)
Text contrast ratio in the bottom sheet meets WCAG 2.2 AA (≥4.5:1 for normal text, ≥3:1 for large text) using the app's design tokens
Multi-chapter peer mentor scenario (NHF): a peer mentor assigned to 3 chapters sees all 3 in the switcher and can switch between them without error
Switching chapters does not trigger duplicate network requests or state emissions
Bottom sheet is dismissible via swipe-down or tap-outside, and dismissal does not alter ActiveChapterState
Test suite passes on both iOS (simulated) and Android (emulated) targets

Technical Requirements

frameworks
Flutter
flutter_test
integration_test
BLoC or Riverpod
WidgetTester
apis
Supabase (mocked for widget tests, real sandbox for integration tests)
Local persistence (SharedPreferences or Hive)
data models
Chapter
ActiveChapterState
UserRole
OrganizationalUnit
performance requirements
Bottom sheet animation completes in under 300ms
Chapter list renders within 100ms of sheet open for lists up to 1,400 chapters (NHF scale)
security requirements
Chapter list must only include chapters the current user is authorized to access
No chapter IDs from other users' scopes appear in the bottom sheet under any test condition
ui components
ChapterSwitcherBottomSheet
ChapterListTile
ActiveChapterIndicator

Execution Context

Execution Tier
Tier 7

Tier 7 - 84 tasks

Can start after Tier 6 completes

Implementation Notes

The bottom sheet chapter list must be populated from the scoped chapter list provided by AccessScopeService — do not fetch all chapters and filter on the client. For persistence, wrap the active chapter ID write behind a repository interface so tests can inject a fake implementation without touching shared preferences directly. WCAG touch target compliance is easiest to assert by checking the `size` of the InkWell or GestureDetector wrapping each list tile — add a helper method `expectMinTouchTarget(finder, Size(48, 48))` to avoid repetition. For the downstream widget refresh assertion, identify one concrete widget (e.g., a chapter name text widget or a filtered list) and assert its text/count changes after the BLoC state emission.

Use `bloc_test` or `ProviderContainer` overrides to isolate BLoC state in widget tests.

Testing Requirements

Use flutter_test for widget tests and the integration_test package for end-to-end flow tests. Widget tests should pump a minimal widget tree with the ChapterSwitcherBottomSheet and mock the BLoC/Riverpod state. Integration tests should use a test Supabase sandbox or fully mocked HTTP layer. For WCAG compliance, use the flutter_accessibility_scanner package or manually assert sizes and colors using the design token constants.

Include a parameterized test for the multi-chapter peer mentor scenario with 1, 3, and 5 assigned chapters. Verify persistence by calling `tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.detached)` and then re-pumping the widget tree.

Component
Chapter Switcher
ui medium
Epic Risks (3)
high impact medium prob security

If the AccessScopeService and the Supabase RLS policies use different logic to determine accessible units, a coordinator could see data in the client that RLS blocks server-side, causing confusing empty states, or worse, RLS could block data the scope service declares accessible.

Mitigation & Contingency

Mitigation: Define the canonical scope computation in a single Supabase Postgres function shared by both the RLS policies and the RPC endpoint called by AccessScopeService. The client-side service calls this RPC rather than reimplementing the logic, ensuring a single source of truth.

Contingency: Add integration tests that execute the same access decision through both the RLS policy path and the AccessScopeService path and assert identical results. Use these as regression guards in the CI pipeline.

medium impact medium prob integration

When a user switches active chapter via the ChapterSwitcher, widgets that are already built may not receive the context-change event if they subscribe incorrectly to the ActiveChapterState BLoC, leading to stale data being displayed under the new chapter context.

Mitigation & Contingency

Mitigation: Use Riverpod's ref.watch on the active chapter provider at the root of each scoped data subtree rather than at individual leaf widgets. Trigger a global data refresh by invalidating all scoped providers when the chapter changes.

Contingency: Add an app-level chapter-change listener that forces a full navigation stack reset to the home screen on chapter switch, guaranteeing all widgets rebuild from scratch with the new context. Accept the UX cost of navigation reset for correctness.

medium impact medium prob scope

Non-technical organization administrators may find the hierarchy management interface too complex for the structural changes they need to make frequently (e.g., chapter renaming, coordinator reassignment), leading to low adoption and continued reliance on manual processes.

Mitigation & Contingency

Mitigation: Conduct usability testing with at least one NHF administrator before finalizing the admin portal screen layout. Prioritize the most common operations (rename, reparent, add child) as primary actions in the UI. Include inline help text and confirmation dialogs with plain-language descriptions of consequences.

Contingency: Provide a simplified 'quick edit' mode that exposes only the three most common operations (rename, deactivate, add child) and hides advanced structural operations behind an 'Advanced' toggle.