high priority medium complexity testing pending testing specialist Tier 6

Acceptance Criteria

All valid state transitions (active→paused, paused→active, any→expired_cert) have at least one passing test case each
All invalid transition guards produce the correct exception or error state and are tested (e.g., pause when already paused, reactivate when already active)
PauseNotificationService.dispatch() is called exactly once on a valid transition and never on an invalid transition — verified via mock verify()
Repository persistence method (upsertPauseRecord / insertStatusLog) is called with correct arguments on every valid transition
Repository is NOT called when a transition guard rejects — confirmed via verifyNever()
Branch coverage on PauseManagementService state machine logic is ≥90% as reported by flutter test --coverage
Test file compiles with zero warnings under strict Dart analysis
Tests run in <10 seconds total (no real network or Supabase calls)
Edge cases covered: null reason string, reason exceeding max length, expected_return_date in the past, expired_cert transition triggered mid-pause
All test descriptions are in English and clearly identify which transition or guard is under test

Technical Requirements

frameworks
flutter_test
mockito (or mocktail)
data models
PeerMentorStatus
PauseRecord
PauseStatusLog
PauseTransitionResult
performance requirements
Entire unit test suite completes in under 10 seconds
No async leaks — all futures and streams are properly awaited or closed in tearDown
security requirements
No real Supabase credentials or network calls in unit tests
Mock objects must not log sensitive mentor data to stdout

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 completes

Implementation Notes

The state machine should be modeled as a pure function or a class method that accepts the current PeerMentorStatus and a requested transition, returning a Result/Either type rather than throwing exceptions — this makes branch coverage measurement straightforward. When mocking the repository, stub both the success path and failure path (e.g., Supabase network error) to ensure error propagation is tested. For the expired_cert transition, ensure the test simulates the certification expiry event as an input to the service rather than relying on a timer, since timers are difficult to test reliably. Use mockito's captor or argument matchers to assert the exact PauseRecord payload written to the repository.

Avoid testing UI or BLoC layer here — those belong in widget and integration tests.

Testing Requirements

Unit tests only — no widget or integration tests in this task. Use flutter_test with mockito or mocktail for mocking PauseManagementRepository and PauseNotificationService. Organize tests in groups: 'valid transitions', 'invalid transition guards', 'notification side effects', 'repository persistence'. Use setUp() to construct a fresh PauseManagementService with mocks before each test.

Use verify() / verifyNever() to assert mock interactions. Run flutter test --coverage and confirm coverage report shows ≥90% branch coverage on the service file. Parameterize transition tests where possible to avoid duplication.

Component
Pause Management Service
service medium
Dependencies (3)
Extend the PauseActivationScreen to handle the reactivation journey when the current mentor status is paused. Show a reactivation prompt with the original pause reason and expected return date displayed as context. Provide a reactivate action that calls PauseManagementService.reactivateMentor() and returns the mentor to active status. Use the PauseStatusIndicator widget to reflect the updated state after reactivation. epic-peer-mentor-pause-management-core-workflows-task-008 Build the core business logic service enforcing the pause state machine with transitions: active→paused (via mentor self-service), paused→active (reactivation), any→expired_cert (triggered externally by certification checker). Implement activatePause(mentorId, reason, expectedReturnDate), reactivateMentor(mentorId), and expireCertification(mentorId). Each transition must persist via PeerMentorStatusRepository and trigger PauseNotificationService. Enforce invariants: cannot pause already-paused mentor, cannot reactivate non-paused mentor. epic-peer-mentor-pause-management-core-workflows-task-006 Implement the peer mentor-facing pause activation screen. Display current status, a confirmation prompt explaining implications of pausing, an optional reason input field, and the ExpectedReturnDatePicker widget. Include a clearly labelled confirm button and a cancel action. On confirmation, call PauseManagementService.activatePause() and display a success confirmation with the expected return date if set. Handle loading and error states with accessible error messaging. epic-peer-mentor-pause-management-core-workflows-task-007
Epic Risks (3)
medium impact medium prob technical

Concurrent status transitions (e.g., coordinator and automated scheduler both attempting to update the same mentor's status simultaneously) may produce race conditions or inconsistent state in the database, leading to audit log gaps or incorrect notifications.

Mitigation & Contingency

Mitigation: Implement all status transitions as atomic Postgres RPC functions with optimistic locking (version column or updated_at check). Use database-level constraints rather than application-level guards as the final enforcement point.

Contingency: Add a compensation job that reconciles status and log table consistency on each nightly scheduler run, surfacing any discrepancies to coordinator dashboards.

medium impact medium prob integration

The coordinator-to-mentor assignment relationship may not always be 1:1 or may be stale (coordinator reassigned after a pause was set), causing notifications to be sent to the wrong coordinator or not sent at all.

Mitigation & Contingency

Mitigation: Query the assignment relationship at notification dispatch time rather than caching it at pause creation time. Add a fallback to notify the chapter administrator if no active coordinator assignment exists.

Contingency: Log all undeliverable notification attempts with the originating mentor ID so administrators can manually follow up, and surface undelivered notification counts on the coordinator dashboard.

medium impact low prob technical

The CoordinatorPauseRosterScreen may load slowly for coordinators managing large rosters with many concurrent certification expiry queries, degrading usability on low-bandwidth mobile connections.

Mitigation & Contingency

Mitigation: Use a single Supabase RPC that joins mentor status, certification expiry, and assignment data in one query rather than N+1 individual calls. Implement pagination with a configurable page size and skeleton loading states.

Contingency: Add an offline cache of the last-fetched roster state using Riverpod with SharedPreferences, ensuring coordinators can at minimum view stale data when connectivity is poor.