high priority medium complexity testing pending testing specialist Tier 6

Acceptance Criteria

All read methods of MentorStatusRepository have unit tests covering: happy path, null/empty result, typed exception on Supabase error
All write methods of MentorStatusRepository have unit tests covering: success with history row creation, conflict exception for invalid state transitions, transaction rollback simulation
CoordinatorNotificationService.resolveCoordinatorsForMentor has tests for: single chapter, multi-chapter, deduplication, empty result, cache hit, cache invalidation
CoordinatorNotificationService.dispatchPushNotification has tests for: all recipients success, partial failure with retry, all tokens missing, DispatchResult values
CoordinatorNotificationService.dispatchInAppNotification has tests for: batch insert count, deep_link_path format, zero recipients no-op, insert failure exception
Integration tests run against a local Supabase instance (docker-compose) and verify RLS blocks cross-chapter reads and cross-mentor writes
Integration tests verify atomic write behaviour: status update and history insert either both succeed or both fail
Overall test suite for these two components achieves >= 90% line coverage as reported by flutter test --coverage
All tests are deterministic and pass consistently in CI without network access (unit tests only — integration tests are opt-in via flag)
Test file naming follows existing project conventions (e.g., mentor_status_repository_test.dart, coordinator_notification_service_test.dart)

Technical Requirements

frameworks
Flutter
flutter_test
mocktail (for mocking)
supabase_flutter (for integration tests)
apis
Mocked Supabase client (PostgrestBuilder chain mocks)
Local Supabase instance via docker-compose for integration tests
Mocked FCM sender interface
data models
MentorStatus
MentorStatusHistory
CoordinatorProfile
InAppNotification
DispatchResult
performance requirements
Full unit test suite for both components must complete in < 30 seconds
Integration tests may take up to 60 seconds — they are run separately, not in the standard CI unit test pass
security requirements
Integration tests must use a dedicated test Supabase project or local Docker instance — never point at production or staging
Test fixtures must not contain real user UUIDs, real FCM tokens, or real personal data
RLS integration tests must use two separate authenticated test users (coordinator, mentor) to verify access boundaries

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

For mocking Supabase's fluent query builder chain (e.g., .from().select().eq().maybeSingle()), create a MockSupabaseQueryBuilder that returns preset responses. This pattern is reusable across all repository tests in the project — consider extracting to a test_helpers package if it does not already exist. Use mocktail's when(...).thenAnswer((_) async => ...) pattern consistently. For integration tests, use supabase_flutter's initialisation with a local URL and anon key from the docker-compose .env.

Seed the database with known fixture rows using the service-role key before each test and clean up with deleteAll after. For RLS tests, authenticate as a test coordinator user and verify that fetching another chapter's mentors returns an empty list (not an error, due to RLS SELECT policy). Document the docker-compose setup command in the test file header comment.

Testing Requirements

This task IS the testing task. Structure tests in three groups: (1) MentorStatusRepository unit tests — mock all Supabase calls using mocktail, test each public method independently. (2) MentorStatusRepository integration tests — spin up local Supabase with migration applied, insert fixture data, run real queries, verify RLS behaviour with two separate auth sessions. (3) CoordinatorNotificationService unit tests — mock IMentorStatusRepository, IFCMSender, and INotificationRepository interfaces, test all public methods and edge cases.

Run coverage with flutter test --coverage and verify lcov threshold. Tag integration tests with @Tags(['integration']) so they can be excluded from standard CI.

Component
Mentor Status Repository
data low
Epic Risks (3)
high impact medium prob security

Supabase RLS policies for status reads and writes must correctly distinguish between a mentor editing their own status and a coordinator editing another mentor's status within the same chapter. Incorrect policies could allow cross-chapter data leakage or silently block legitimate status updates, causing hard-to-diagnose runtime failures.

Mitigation & Contingency

Mitigation: Write RLS policies with explicit role checks (auth.uid() = mentor_id OR chapter_coordinator_check()) and verify with integration tests that cover same-chapter coordinator access, cross-chapter denial, and self-access. Review policies with a second developer before merging.

Contingency: If policy errors surface after merge, temporarily widen policy to coordinator role globally while a targeted fix is authored; use Supabase audit logs to trace any unauthorised access during the interim.

medium impact medium prob integration

CoordinatorNotificationService must correctly resolve which coordinator(s) are responsible for a given mentor's chapter. If the chapter-coordinator mapping is incomplete or a mentor belongs to multiple chapters (as with NHF multi-chapter memberships), the service could fail to notify or duplicate notifications to the wrong coordinators.

Mitigation & Contingency

Mitigation: Use the existing chapter membership data model and query all active coordinator roles for each of the mentor's chapters. Add a de-duplication step before dispatch. Write integration tests with fixtures covering single-chapter, multi-chapter, and no-coordinator edge cases.

Contingency: If resolution logic proves too complex at this stage, fall back to notifying all coordinators in the organisation until a proper chapter-scoped resolver can be delivered in a follow-up task.

high impact low prob technical

Adding new columns to peer_mentors in production could conflict with existing application code that does SELECT * queries if new non-nullable columns without defaults are introduced, causing unexpected failures in unrelated screens.

Mitigation & Contingency

Mitigation: Make all new columns nullable or provide safe defaults. Use additive migration strategy with no column renames or drops. Run migration against a staging copy of production data before applying to live.

Contingency: Prepare a rollback migration script that drops only the new columns; coordinate with the team to deploy the rollback and hotfix immediately if production issues are detected.