high priority medium complexity testing pending testing specialist Tier 4

Acceptance Criteria

Test file covers all valid transitions: active→paused via pauseMentor, paused→active via reactivateMentor, active→inactive via deactivateMentor
Test file covers all invalid transitions: paused→inactive, inactive→active, inactive→paused — each must return MentorStatusError.invalidTransition
Tests verify that CoordinatorNotificationService.notifyStatusChange is called exactly once after each successful transition with the correct payload fields
Tests verify that CoordinatorNotificationService is NOT called when a transition fails (RPC rejection or network error)
Tests verify that a failure in CoordinatorNotificationService does not change the return value of the transition method
Tests verify getMentorsByStatus returns an empty list when no mentors match the given status
Tests verify getMentorsByStatus applies chapterId filter when provided and omits it when null
Tests verify network errors from Supabase are wrapped into MentorStatusError.networkFailure
Tests verify getMentorStatus returns MentorStatusError.notFound when the mentorId does not exist
All tests use flutter_test framework with mocked dependencies (no real Supabase calls)
Test file achieves 100% branch coverage on MentorStatusService transition logic as verified by flutter test --coverage
Tests are organized into logical describe/group blocks by method name for readability

Technical Requirements

frameworks
Flutter
Dart
flutter_test
data models
assignment
performance requirements
Full test suite must complete in under 10 seconds
No test should depend on external network calls or real Supabase connections
security requirements
Test fixtures must not contain real personnummer, real user IDs, or production credentials
Mock actorId values must be clearly labeled as test data (e.g., 'test-actor-uuid-001')

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Create a MockSupabaseClient that implements the minimal Supabase client interface needed — do not import the full supabase_flutter package in unit tests if it requires platform initialization. Use a Fake or Stub pattern for CoordinatorNotificationService with a call-count tracker and argument capture so tests can assert on payload fields. Use setUp() to reset all mocks between tests to prevent state leakage. Consider parameterized test patterns (using test() inside a for loop over transition matrices) for the invalid transition matrix to keep the test file concise.

The test for notification failure non-propagation is especially critical — use a mock that throws on the first call to simulate FCM failure and assert the transition result is still a success.

Testing Requirements

This task IS the testing requirement. Use flutter_test for all tests. Use mockito or manual Dart test doubles for Supabase client and CoordinatorNotificationService. Structure tests in groups by method: pauseMentor, reactivateMentor, deactivateMentor, getMentorStatus, getMentorsByStatus.

Each group must have at minimum: happy path, invalid input, network error, not found (where applicable). Run flutter test --coverage and confirm 100% branch coverage on the service file. Submit coverage report as part of task completion.

Component
Mentor Status Service
service medium
Epic Risks (3)
medium impact low prob technical

The status state machine must handle race conditions where two concurrent callers (e.g., a mentor self-pausing and a coordinator force-pausing simultaneously) attempt to update the same mentor's status. Without a concurrency guard, both writes could succeed, leaving the audit log in an inconsistent state.

Mitigation & Contingency

Mitigation: Use a Supabase RPC with a row-level lock (SELECT FOR UPDATE) inside a transaction so only one transition wins. Return a clear error to the losing caller. Test with concurrent requests in the integration test suite.

Contingency: If row-level locking proves unreliable in the Supabase environment, add an optimistic-locking version field to peer_mentors and have the service retry up to three times on version conflict before surfacing an error to the caller.

high impact medium prob technical

If the CertificationExpiryJob Edge Function fails silently (network timeout, Supabase cold start), HLF mentors with expired certifications could remain in active status and continue appearing on the chapter website, creating a compliance breach.

Mitigation & Contingency

Mitigation: Implement structured error logging inside the Edge Function, write a monitoring query that checks for mentors with expired certifications still in active status, and set up an alert if any are detected 30 minutes after the scheduled nightly run.

Contingency: Provide a coordinator-accessible manual trigger for the expiry check that can be invoked via the admin interface if the scheduled job is known to have failed. Document the manual recovery procedure for HLF coordinators.

medium impact medium prob dependency

pg_cron registration in Supabase requires superuser-level access that may not be available in all environments (local dev, staging, CI). If the cron job cannot be registered automatically, the Edge Function will never execute on schedule, breaking the HLF certification expiry workflow.

Mitigation & Contingency

Mitigation: Use Supabase's recommended pg_cron setup via the SQL editor migration script and document the exact commands. Validate cron registration in the staging environment as part of the epic's deployment checklist.

Contingency: If pg_cron is unavailable, switch to a Supabase scheduled Edge Function invocation via an external cron service (e.g., a GitHub Actions scheduled workflow calling the Edge Function endpoint with a service-role key) until the pg_cron approach is resolved.