Write widget tests for MentorMultiSelectWidget
epic-coordinator-proxy-registration-foundation-task-011 — Write Flutter widget tests for MentorMultiSelectWidget covering: rendering of mentor list items, search debounce filtering, chip display for selected mentors, deselect from chip, select-all behavior, empty state when no mentors match search, accessibility semantics output. Use flutter_test and mock the mentor data source. Verify that the widget emits the correct list of selected mentor IDs on confirmation.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 4 - 323 tasks
Can start after Tier 3 completes
Implementation Notes
Debounce tests are the trickiest part: wrap the test body in fakeAsync { ... } and pump the widget tree before and after advancing the timer to simulate the debounce window accurately. Use Key widgets on MentorListItem checkboxes and chip delete buttons to make find.byKey() reliable and avoid fragile find.byText() lookups that break when names change. For the semantics test, call tester.pumpWidget() then tester.pump() once to let the widget settle, then use tester.getSemantics(find.byKey(mentorItemKey)).label to assert the label content.
Keep mock data in a shared test fixture file (e.g., test/fixtures/mock_mentors.dart) so it can be reused across widget and unit tests without duplication.
Testing Requirements
Use flutter_test with WidgetTester. Wrap the widget under test in a ProviderScope with overrides for the mentor list provider (inject a fixed list of 5–10 mock PeerMentorSummary objects). Use tester.enterText() for search input tests. Use fakeAsync and tester.pump(Duration(milliseconds: 300)) to advance past the debounce timer.
Use tester.tap(find.byKey(...)) for chip delete and select-all interactions. Assert semantics with tester.getSemantics(find.byType(MentorListItem)). Capture onSelectionChanged emissions by passing a local List variable to the callback and asserting its contents after each interaction.
Supabase RLS policies for org-scoped proxy access may be difficult to express correctly, especially for coordinators with multi-chapter access. An overly permissive policy could allow cross-org proxy registrations, corrupting Bufdir reporting; an overly restrictive policy could block legitimate coordinators from registering.
Mitigation & Contingency
Mitigation: Write integration tests covering all access boundary cases (same org, cross-org, multi-chapter coordinator) before merging any RLS migration. Use parameterised RLS test helpers already established by the auth feature.
Contingency: If RLS proves insufficient, add a server-side Edge Function validation layer that re-checks org membership before persisting any proxy record, providing defence in depth.
Adding new tables and foreign key constraints to an existing production Supabase database risks migration failures or locking issues if the database already contains active sessions during deployment.
Mitigation & Contingency
Mitigation: Use additive-only migrations (no DROP or ALTER on existing tables). Test full migration sequence in a staging Supabase project before production deployment. Schedule during low-traffic window.
Contingency: Maintain a rollback migration script. If the migration fails, the feature remains unreachable behind a feature flag while the schema issue is resolved.
Audit log entries must be immutable for compliance, but Supabase RLS by default allows row owners to update their own rows. If audit records are accidentally mutable, dispute resolution and accountability guarantees are invalidated.
Mitigation & Contingency
Mitigation: Configure the proxy_audit_log table with an RLS policy that allows INSERT for coordinators but denies UPDATE and DELETE for all roles including service_role, enforced at the database level.
Contingency: If RLS cannot fully prevent updates, create a database trigger that reverts any UPDATE to the audit table and logs the attempt as a security event.