Integration test CertificationExpiryJob end-to-end
epic-peer-mentor-pause-core-logic-task-012 — Write integration tests for CertificationExpiryJob covering: job correctly identifies only expired-certificate active HLF mentors, auto-pause is applied via the RPC and recorded in audit history, already-paused mentors are skipped without error, coordinator notifications are dispatched with correct grouped payloads, per-record failure handling allows remaining mentors to be processed, and the job log output matches the expected structured JSON schema. Use a Supabase local emulator or test database with seeded HLF mentor data.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 6 - 158 tasks
Can start after Tier 5 completes
Implementation Notes
Structure the test file as a single Deno test suite with named sub-tests for each scenario. Extract the seed data setup into a shared helper (seedHlfMentors(db, overrides)) so each test can vary only the fields relevant to that scenario. For the RPC failure simulation, create a trigger or a wrapper function in the test schema that raises an exception when the mentor_id matches a sentinel UUID — this avoids needing to mock at the Deno layer and tests the real RPC path. Use a fixed reference date (e.g.
'2026-03-29') as the job's 'today' parameter in all tests to eliminate date-dependency flakiness. Capture stdout from the job run and parse the final JSON log line to assert schema compliance — do not rely on database state alone for the log assertions.
Testing Requirements
Integration tests using Deno test runner against supabase local (supabase start). Each test case seeds its own data in a beforeEach hook and tears down in afterEach using DELETE or ROLLBACK. Test coverage must reach 100% of the job's branching paths: happy path, skip-already-paused, per-record RPC failure, zero-eligible-mentors (no-op). Notification dispatch is tested by injecting a spy/stub for CoordinatorNotificationService that records calls without making real FCM requests.
Final job log schema is validated using a JSON schema validator (e.g. ajv or zod) to catch structural regressions. All tests must be runnable with `deno test --allow-env --allow-net` against the local emulator.
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.
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.
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.