Unit tests: ProxyRegistrationService coverage
epic-bulk-and-proxy-registration-services-task-010 — Write unit tests for ProxyRegistrationService using flutter_test with mocked repository and duplicate detector. Test cases: permission granted for in-scope mentor, permission denied for out-of-scope mentor, duplicate warning returned non-blocking with correct structured data, successful registration returns record ID, payload always uses session coordinator ID not input, and failure modes for each typed error variant.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Structure the test file with a setUp() block that initialises all mocks and creates a fresh ProxyRegistrationService instance with injected mocks. Use when(mock.method()).thenReturn() for synchronous stubs and when(mock.method()).thenAnswer((_) async => value) for async stubs. For the 'payload uses session coordinator ID' test, configure the mock auth session to return a specific coordinator UUID and then assert that the ActivityPayload passed to repository.insert() contains that UUID regardless of the coordinatorId argument. For the DuplicateWarning non-blocking test, verify the pendingPayload in the result is structurally equal to what would have been persisted — use equatable or freezed equality on ActivityPayload.
Cover the PersistenceError path by throwing both a generic Exception and a PostgrestException from the mocked repository.
Testing Requirements
Use flutter_test as the test framework. Create mock classes for ProxyActivityRepository, ProxyDuplicateDetector, and the coordinator scope/permission validator using mockito @GenerateMocks or mocktail Mock base class. Group tests by scenario using group() blocks: 'permission checks', 'duplicate detection', 'successful registration', 'error handling', 'payload integrity'. Each group should have at least 2 test cases.
Use expect() with matcher isA
The Proxy Registration Service must verify that the coordinator has a legitimate assignment relationship with the target peer mentor before creating a record. If this check is implemented only in application code and not enforced at the DB/RLS level, a compromised or buggy client could bypass it by calling the Supabase endpoint directly, creating fraudulent proxy records for arbitrary peer mentors.
Mitigation & Contingency
Mitigation: Implement permission validation at two levels: (1) application-layer check in Proxy Registration Service that queries the assignments table before constructing the payload, and (2) RLS policy on the activities table that restricts INSERT to rows where recorded_by_user_id matches the authenticated user AND peer_mentor_id is in the set of peer mentors assigned to that coordinator. The RLS policy is the authoritative guard; the service-layer check provides early user-facing feedback.
Contingency: If RLS policy implementation is blocked by Supabase plan constraints, implement a Supabase Edge Function as a proxy endpoint that enforces the permission check server-side before forwarding to the DB. Disable direct client inserts entirely for proxy activities.
For a bulk session with 30 selected peer mentors, the Proxy Duplicate Detector must query existing activities for each mentor. If implemented as 30 sequential Supabase queries, round-trip latency could make the bulk confirmation screen feel slow (>3s), degrading coordinator experience and potentially causing timeouts.
Mitigation & Contingency
Mitigation: Implement the duplicate check as a single Supabase query using an IN clause on peer_mentor_id combined with the activity_type and date filters, returning all potential duplicates for the entire batch in one network round-trip. Group results client-side by mentor ID to produce the per-mentor warning structure.
Contingency: If the single-query approach returns too much data for very large chapters, add a database index on (peer_mentor_id, activity_type, date) and profile query time. If still insufficient, accept a short loading state on the confirmation screen with a progress indicator rather than pre-loading duplicates before navigation.