Testing Standards — Ghasi EHR Platform
Scope: Testing coverage and quality standards enforced system-wide.
Authority: Normative. Every service MUST meet these requirements.
1. Coverage Targets
| Level | Minimum Coverage | Applies To |
|---|---|---|
| Unit tests | ≥ 80% line coverage | Every service and shared package |
| Integration tests | Key paths covered | DB operations, NATS pub/sub, external adapter calls |
| Contract tests | All public APIs | OpenAPI schema validation (REST), FHIR interaction conformance |
| E2E tests | Critical user flows | Playwright — clinician + portal workflows |
| Sync / offline-first tests | Modules with disconnected workflows | Queue replay, idempotency, conflict handling, tenant isolation on replay |
| Kong route contracts | Externally exposed HTTP | At least one path per service through Kong (same host/path as clients) in non-dev CI where applicable |
Critical domains (identity, registration, orders, medications, billing, and other safety-critical services defined per module) SHOULD target ≥90% line coverage when those services exist, aligned with REQUIREMENTS_GUARD_RAILS.md.
Per-Service Enforcement
- CI pipeline MUST fail if unit test coverage drops below 80%.
- Coverage reports generated per service using Jest
--coverage. - Shared packages (
packages/@ghasi/*) MUST also maintain ≥ 80% coverage.
2. Testing Framework
| Tool | Purpose |
|---|---|
| Jest | Unit and integration tests |
| Supertest | HTTP integration tests (NestJS controllers) |
| Playwright | E2E browser tests |
| nats-mock or test containers | NATS JetStream integration tests |
| pg-mem or test containers | PostgreSQL integration tests |
3. Test Organization
{service-name}/
src/
{domain}/
__tests__/
{domain}.service.spec.ts # Unit tests
{domain}.controller.spec.ts # Controller unit tests
test/
integration/
{domain}.integration.spec.ts # DB + NATS integration
e2e/
{domain}.e2e-spec.ts # HTTP E2E (Supertest)
fixtures/
{entity}.factory.ts # Test data factories
4. Unit Test Requirements
What to test (at minimum per service):
- Domain service business logic (state transitions, validation, business rules)
- DTO validation (valid + invalid inputs)
- Guard behavior (RBAC, module entitlement, ABAC)
- Event payload construction (CloudEvents envelope + data)
- Error handling paths (not-found, conflict, forbidden, module-not-active)
Rules:
- Mock all external dependencies (repositories, NATS, Redis, HTTP clients).
- Test each business rule explicitly (reference the BR-* ID in test description).
- Test edge cases listed in module specs (§13 Edge Cases).
5. Integration Test Requirements
What to test:
- Database migrations apply cleanly
- Repository CRUD with tenant isolation (verify cross-tenant queries return empty)
- NATS event publishing (event is published with correct subject and envelope)
- NATS consumer idempotency (same event processed twice → no duplicate side effects)
- FHIR adapter mapping (internal entity ↔ FHIR resource round-trip)
6. Contract Test Requirements
REST API Contracts:
- Validate every endpoint against its OpenAPI schema.
- Test request validation (missing fields, wrong types → 400).
- Test auth enforcement (no token → 401, wrong role → 403, wrong tenant → 404).
- Test module licensing enforcement (disabled module → 422 MODULE_NOT_ACTIVE).
FHIR Contracts:
- Validate
CapabilityStatementdeclares all owned resources. - Validate read/search/create responses conform to FHIR R4 base resource rules.
- Validate
OperationOutcomefor errors.
Kong (public edge) Contracts:
- For each HTTP service exposed outside the private network, maintain at least one automated test that calls the Kong base URL (declarative config in repo, e.g. docker-compose CI profile).
- Assert auth plugins, rate limits, or correlation headers behave as configured for representative routes.
- Declarative checks (repo-local, no running Kong):
node --test infra/kong/kong.declarative.contract.test.mjsassertskong.ymlandkong.dev.ymlexpose the same*-serviceentries and critical paths (e.g./fhir,/v1/portal). Syntax validation:bash infra/kong/validate-declarative.shrunsdeck file validateon both YAML files plus the Node tests (requires Docker).
7. E2E Test Requirements (Playwright)
Critical paths to cover:
- Login → navigate to module → perform primary workflow → verify outcome
- Module licensing: disabled module → nav entry hidden, direct URL shows appropriate error
- RTL rendering: switch language → verify layout direction
- Patient portal: login → view summary → view released results → send message
8. Test Data Management
- Use factory functions (not raw fixtures) to generate test entities.
- Factories MUST produce tenant-scoped data with realistic identifiers.
- Seed data for integration tests MUST be isolated per test suite (use transactions or cleanup).
9. Testing Anti-Patterns (AVOID)
| Anti-Pattern | Why | Fix |
|---|---|---|
| Testing only happy path | Misses error handling bugs | Test each error code path explicitly |
| Mocking the thing under test | Tests prove nothing | Mock dependencies, not the SUT |
| Shared mutable test state | Flaky tests | Isolate per test; use beforeEach cleanup |
| Snapshot tests for API responses | Brittle; obscures intent | Assert specific fields |
| Skipping tenant isolation tests | Cross-tenant data leak risk | Always test multi-tenant scenarios |
synchronize: true in test DB | Schema drift from prod | Use migrations in test environments |
10. CI Integration
- Kong: Workflow
.github/workflows/ci-infra.ymlvalidates declarative config (deck+ Node contract tests) wheninfra/kong/**changes. - Jest runs in CI with
--forceExit --detectOpenHandles --coverage. - Coverage ≥80%: Enforce per service by adding
coverageThresholdto that service’sjest.config.jsand runningpnpm --filter <service> test:covin CI. Until a service opts in, the defaulttestscript may use--no-coverage; treat missing thresholds as backlog, not a pass. - Coverage threshold enforced in
jest.config.ts:
coverageThreshold: {
global: {
branches: 75,
functions: 80,
lines: 80,
statements: 80,
},
},
- Playwright E2E runs in a separate CI stage after services are deployed to a test environment.
- Test results published as CI artifacts for review.