Unit tests: data models and role guard
epic-proxy-activity-registration-foundation-task-011 — Write comprehensive unit tests for all four Dart model classes (ProxyActivityRecord, BulkParticipant, DuplicateConflict, BulkRegistrationRequest) and CoordinatorRoleGuard. Cover serialisation/deserialisation, copyWith edge cases, equality, enum boundary values, and role guard permission enforcement. Use flutter_test with mockito for Riverpod container setup.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Generate mockito mocks with build_runner (@GenerateMocks annotation) placed in a test/helpers/mocks.dart file shared across test files. Use fixtures (static factory methods or JSON files in test/fixtures/) to reduce boilerplate. For copyWith edge cases, test: updating every field individually, updating no fields (returns equal object), and chaining copyWith twice. For enum boundary tests, iterate over MyEnum.values in a for-loop test rather than writing one test per value — this ensures new enum values automatically get tested.
For CoordinatorRoleGuard, create a thin FakeAuthStateNotifier that extends StateNotifier and exposes a setRole(UserRole?) method to drive guard state without async complexity.
Testing Requirements
Pure unit tests using flutter_test. No widget tests or integration tests in this task. Use ProviderContainer (not ProviderScope) for Riverpod-dependent guard tests to keep them lightweight. Use mockito-generated mocks for any auth state dependency injected into CoordinatorRoleGuard.
Organise tests in describe-style group() blocks: one group per class, nested groups per method/scenario. Each test must have a descriptive name following the pattern 'given [state] when [action] then [expectation]'. Verify that fromJson raises a meaningful FormatException (not a null crash) when required fields are missing.
The activities table migration adding registered_by and attributed_to columns may conflict with existing RLS policies or FK constraints if the user profile table structure differs from assumptions, blocking all subsequent epics.
Mitigation & Contingency
Mitigation: Review existing activities table schema and RLS policies before writing the migration. Run the migration against a staging database clone first. Write rollback scripts alongside the migration.
Contingency: If migration fails in staging, isolate the conflict with a targeted schema audit, adjust FK references or RLS policy scope, and re-run before touching production.
The RLS policy must filter proxy inserts to the coordinator's chapter scope. If the chapter-scope resolver pattern differs between organisations (multi-chapter coordinators in NHF vs single-chapter in HLF), the policy may be too broad or too restrictive.
Mitigation & Contingency
Mitigation: Design the RLS policy to accept a coordinator's full set of assigned chapter IDs (array) rather than a single chapter_id. Validate the policy against NHF multi-chapter test fixtures during the integration test phase.
Contingency: If the policy is found to be incorrect after deployment, introduce a server-side validation edge function as a safety net while the RLS policy is corrected.
The bulk_register_activities RPC function may time out or cause lock contention when inserting large participant batches (e.g. 40+ peer mentors in a single group session), degrading the user experience.
Mitigation & Contingency
Mitigation: Benchmark the RPC function with 50-participant batches during development. Use unnest-based bulk insert rather than row-by-row PL/pgSQL loops. Set a reasonable statement_timeout.
Contingency: If performance is insufficient, split the client-side submission into chunks of 20 participants with progress feedback, rather than a single RPC call.