high priority medium complexity testing pending testing specialist Tier 8

Acceptance Criteria

A test file exists at test/integration/proxy_mode_and_mentor_selection_test.dart (or equivalent path)
Test: tapping 'Single registration' on ProxyModeSelectorScreen navigates to the single peer mentor selection screen
Test: tapping 'Bulk registration' on ProxyModeSelectorScreen navigates to the multi-select mentor list screen
Test: in single-select mode, selecting mentor A then tapping mentor B deselects A and selects only B
Test: in multi-select mode, the 'Continue' button is semantically disabled when selectedMentorIds is empty
Test: in multi-select mode, selecting one or more mentors enables 'Continue' and navigation proceeds with the correct ID list
Test: 'Select All' selects all items; 'Deselect All' clears all items; count badge updates correctly in both cases
Test: searching filters the visible list; previously selected hidden items are preserved in state after query clears
Test: Semantics tree on ProxyModeSelectorScreen contains correct labels for both mode buttons
Test: Semantics tree on multi-select screen contains liveRegion badge node and correct checked/unchecked states for mentor items
All tests pass with flutter test without requiring a physical device or simulator
Test coverage for the three screens reaches at least 80% line coverage (measured via flutter test --coverage)

Technical Requirements

frameworks
Flutter
flutter_test
BLoC
data models
PeerMentor
MentorSelectionState
BulkRegistrationWizardArgs
performance requirements
All widget tests must complete within 30 seconds total to keep CI fast
Use fake/mock data providers — no real Supabase calls in widget tests
security requirements
Test fixtures must not include real user PII — use synthetic names and IDs
ui components
ProxyModeSelectorScreen
SingleMentorSelectScreen
PeerMentorMultiSelectScreen (108-peer-mentor-multi-select)

Execution Context

Execution Tier
Tier 8

Tier 8 - 48 tasks

Can start after Tier 7 completes

Implementation Notes

Create a test helper file test/helpers/mentor_selection_helpers.dart that provides: buildMultiSelectScreen(WidgetTester, {List mentors, MentorSelectionState initialState}) returning a pumped widget tree wrapped with necessary BlocProviders and MaterialApp. This reduces boilerplate across test cases. For navigation tests, use a GoRouter test setup or a simple Navigator observer mock that captures pushed routes. For accessibility tests, enable semantics at the top of each test group with tester.binding.setSemanticsEnabled(true) and wrap assertions in an ensureSemantics() block.

When asserting disabled state of 'Continue', check both the Semantics node (isEnabled: false) and that the onTap callback is null on the underlying widget. Avoid testing BLoC logic directly in widget tests — keep widget tests focused on UI and BLoC state integration; unit-test BLoC transitions separately in test/blocs/mentor_selection_bloc_test.dart.

Testing Requirements

Use flutter_test WidgetTester for all tests — no integration_test package required unless device-level gesture testing is needed. Structure tests in groups: (1) ProxyModeSelectorScreen navigation group, (2) SingleMentorSelect enforcement group, (3) MultiSelect validation gate group, (4) SelectAll/DeselectAll group, (5) Search and selection preservation group, (6) Accessibility semantics group. Use MockMentorRepository (mockito or manual fake) returning a fixed list of 5–10 synthetic PeerMentor objects. Wrap widgets under test in BlocProvider with a real or fake BLoC seeded with known state.

Use SemanticsController (tester.semantics) for accessibility assertions. After each test group, call tester.pumpAndSettle() to ensure animations complete. Include a tearDown that calls tester.binding.setSemanticsEnabled(false) to release resources.

Component
Proxy Mode Selector Screen
ui low
Epic Risks (2)
medium impact medium prob technical

NHF coordinators may manage dozens of peer mentors across multiple chapters. If the multi-select list renders all contacts in a single unsorted ListView, performance degrades with 50+ items, and coordinators cannot efficiently locate a specific mentor, increasing the probability of selection errors and wrong-person proxy registrations.

Mitigation & Contingency

Mitigation: Use a SliverList with itemExtent for fixed-height rows to enable O(1) scroll position calculation. Implement the search filter using a debounce utility operating on an in-memory list (no extra API calls). Sort the contact list alphabetically by default. Add chapter-filter chips above the list for NHF's multi-chapter coordinators.

Contingency: If performance issues arise in testing with real data sets, introduce pagination with a 'load more' trigger at the bottom of the list and cache rendered rows using Flutter's AutomaticKeepAliveClientMixin.

high impact medium prob security

NHF has a complex 12-national-association / 9-region / 1,400-chapter hierarchy. It is ambiguous whether a coordinator can proxy-register for peer mentors outside their immediately assigned chapter. If the contact list is not correctly scoped by RLS, coordinators might see — and register on behalf of — peer mentors they do not manage, creating fraudulent activity records that skew Bufdir statistics.

Mitigation & Contingency

Mitigation: The Proxy Contact List Provider must query only peer mentors linked to the coordinator's own chapter scope via RLS. Add an explicit Supabase query test asserting that a coordinator from chapter A cannot retrieve peer mentors from chapter B. Display each mentor's chapter affiliation in the list row so coordinators can visually verify scope.

Contingency: If RLS scope is found to be too permissive in testing, apply a server-side coordinator_id filter as a secondary guard on the query. Block the feature release until the scope test passes consistently.