Document Service — Testing Strategy
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · TESTING_STANDARDS.md
1. Coverage Targets
| Test type | Coverage target | Tool |
|---|---|---|
| Unit tests | ≥ 80 % statement + branch | Vitest |
| Integration tests | All use cases covered | Vitest + Testcontainers (PostgreSQL + MinIO + ClamAV) |
| Contract tests (consumer) | All API endpoints + event schemas | Pact + JSON Schema |
| E2E tests | Critical generation + upload flows | SuperTest against running service |
| Visual regression (PDF) | Platform reference forms | PDF hash contract tests |
2. Mandatory Test Scenarios
2.1 Tenant Isolation (test/integration/tenant-isolation.spec.ts)
| Scenario | Expected |
|---|---|
| GET /v1/documents?patientId for Tenant A documents by Tenant B caller | 0 results (RLS) |
| Download document owned by Tenant B as Tenant A actor | 404 Not Found |
| RLS policy: SELECT on document_templates with wrong tenant setting | 0 rows |
| Cross-tenant template fork attempt | 403 Forbidden |
2.2 Outbox (test/integration/outbox.spec.ts)
| Scenario | Expected |
|---|---|
| Template version published → event in outbox before tx commit | Event in outbox table |
Artifact registered → document.artifact.registered.v1 in outbox | Event present |
| Relay publishes to NATS → marks delivered_at | delivered_at not null |
2.3 Inbox (test/integration/inbox.spec.ts)
| Scenario | Expected |
|---|---|
Same document.artifact.registered.v1 delivered twice | Second delivery acknowledged, not processed |
3. Unit Test Scenarios
| Module | Key scenarios |
|---|---|
PublishTemplateVersionUseCase | Transitions draft to published; rejects if already published |
GenerateDocumentSyncUseCase | Resolves FHIR bindings; rejects retired version; idempotency via clientMutationId |
FinalizeUploadUseCase | Clean file → DocumentReference created; virus detected → quarantine event |
ForkPlatformTemplateUseCase | Creates tenant copy; sets forkedFromPlatformFormKey; preserves lineage |
PDFRenderer | RTL output correct for ps-AF locale; binding placeholders substituted |
PresignedUrlGenerator | TTL enforced; tenantId validated |
InputSnapshotHasher | Deterministic SHA-256 for same input; different for different FHIR data |
4. Contract Tests
Pact Consumer Contracts
| Provider | Interactions tested |
|---|---|
interop-service (FHIR gateway) | GET /fhir/R4/Patient/{id}, GET /fhir/R4/Encounter/{id}, POST /fhir/R4/DocumentReference, POST /fhir/R4/Binary |
config-service | GET /internal/config/tokens (tenant branding for PDF) |
audit-service | Event schema: document.artifact.registered.v1 |
Event Schema Tests
All 9 event subjects validated against registered JSON schema on publish.
PDF Contract Tests (Platform Reference Forms)
For each platformFormKey in the reference forms catalog:
- Generate PDF with fixed input snapshot
- Compare SHA-256 hash or visual diff against golden fixture
- Ensures platform form upgrades do not silently break output
5. Performance Tests
| Scenario | Target |
|---|---|
| Sync generation, typical prescription template | p95 < 5 s |
| Sync generation, complex 4-page report template | p95 < 10 s |
| Concurrent generation: 20 rps | No deadlocks; p99 < 15 s |
| Template list query (1000 templates) | p95 < 200 ms |
6. Security Tests
| Test | Expected |
|---|---|
| Upload file with EICAR virus signature | 422 VIRUS_DETECTED; quarantine event |
Generate without ehr.documents license | 403 MODULE_NOT_LICENSED |
| Edit platform reference template | 403 PLATFORM_TEMPLATE_IMMUTABLE |
| Access another tenant's document (RLS bypass attempt) | 0 results via RLS; 404 via controller |
| Presigned URL with expired signature | 403 from object storage |
Generate document with expired effectiveTo template version | 422 TEMPLATE_VERSION_NOT_PUBLISHED |