Immunizations Service — Testing Strategy
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template
1. Coverage Targets
| Scope | Target |
|---|---|
| Line coverage | ≥ 80% |
| Branch coverage | ≥ 75% |
| Domain layer (use cases, domain model) | ≥ 90% |
2. Test Types
| Type | Framework | Scope |
|---|---|---|
| Unit | Jest | Use cases, forecast engine, domain model, value objects |
| Integration | Jest + Testcontainers (PostgreSQL) | Repository adapters, outbox relay, RLS policies |
| Contract (consumer) | Pact | Events produced: immunization.recorded, forecast.updated; events consumed: patient.registered, patient.merged |
| API (E2E) | Supertest | REST endpoints against in-process NestJS app |
| Performance | k6 | Forecast endpoint; record create endpoint |
3. Mandatory Integration Tests
The following integration tests must pass before any release:
tenant-isolation.integration.spec.ts— Verify that immunization records from tenant A are never accessible to tenant B under RLS.outbox.integration.spec.ts— Verify that recording an immunization writes to the outbox in the same transaction; outbox relay publishes to NATS exactly once.forecast-refresh.integration.spec.ts— Verify that after recording dose 1 of a multi-dose series, the forecast correctly advances the next due date and emitsforecast.updated.
4. Scenario Coverage Matrix
| Scenario | Unit | Integration | Contract |
|---|---|---|---|
| Record administration — happy path | Yes | Yes | Yes |
| Record refusal — happy path | Yes | Yes | Yes |
| Contraindication blocks administration | Yes | Yes | No |
| Contraindication override with reason | Yes | No | No |
| Forecast computation — EPI schedule full series | Yes | Yes | No |
| Forecast after dose 1 of 3 | Yes | Yes | No |
| Forecast after all doses complete | Yes | No | No |
| Forecast suppressed for deceased patient | Yes | Yes | No |
| Historical import triggers forecast refresh | Yes | Yes | No |
| Merge — immunization records reassigned | No | Yes | No |
| Defaulter query — overdue patients | Yes | Yes | No |
| Coverage report — correct count | Yes | Yes | No |
| Digital certificate — valid JWT signature | Yes | No | No |
| Registry sync — success path | No | Yes | No |
| Registry sync — retry on failure | No | Yes | No |
| Tenant isolation (RLS) | No | Yes | No |
| Optimistic lock conflict on amendment | Yes | Yes | No |
| Patient not found returns 404 | Yes | No | No |
| Module not entitled returns 403 | Yes | No | No |
5. Contract Tests
| Event | Role | Consumer |
|---|---|---|
IMMUNIZATIONS.immunization.recorded.v1 | Producer | communication-service, analytics-service |
IMMUNIZATIONS.forecast.updated.v1 | Producer | communication-service |
REGISTRATION.patient.registered.v1 | Consumer | immunizations-service |
REGISTRATION.patient.merged.v1 | Consumer | immunizations-service |
6. Performance Tests
| Scenario | Tool | Target |
|---|---|---|
POST /v1/immunizations — 50 concurrent users | k6 | p95 < 500 ms |
GET /v1/immunizations/forecast/:patientId — 100 concurrent | k6 | p95 < 2 000 ms |
GET /v1/immunizations/defaulters — 10 concurrent | k6 | p95 < 1 000 ms |