Skip to main content

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

LevelMinimum CoverageApplies To
Unit tests≥ 80% line coverageEvery service and shared package
Integration testsKey paths coveredDB operations, NATS pub/sub, external adapter calls
Contract testsAll public APIsOpenAPI schema validation (REST), FHIR interaction conformance
E2E testsCritical user flowsPlaywright — clinician + portal workflows
Sync / offline-first testsModules with disconnected workflowsQueue replay, idempotency, conflict handling, tenant isolation on replay
Kong route contractsExternally exposed HTTPAt 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

ToolPurpose
JestUnit and integration tests
SupertestHTTP integration tests (NestJS controllers)
PlaywrightE2E browser tests
nats-mock or test containersNATS JetStream integration tests
pg-mem or test containersPostgreSQL 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 CapabilityStatement declares all owned resources.
  • Validate read/search/create responses conform to FHIR R4 base resource rules.
  • Validate OperationOutcome for 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.mjs asserts kong.yml and kong.dev.yml expose the same *-service entries and critical paths (e.g. /fhir, /v1/portal). Syntax validation: bash infra/kong/validate-declarative.sh runs deck file validate on 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-PatternWhyFix
Testing only happy pathMisses error handling bugsTest each error code path explicitly
Mocking the thing under testTests prove nothingMock dependencies, not the SUT
Shared mutable test stateFlaky testsIsolate per test; use beforeEach cleanup
Snapshot tests for API responsesBrittle; obscures intentAssert specific fields
Skipping tenant isolation testsCross-tenant data leak riskAlways test multi-tenant scenarios
synchronize: true in test DBSchema drift from prodUse migrations in test environments

10. CI Integration

  • Kong: Workflow .github/workflows/ci-infra.yml validates declarative config (deck + Node contract tests) when infra/kong/** changes.
  • Jest runs in CI with --forceExit --detectOpenHandles --coverage.
  • Coverage ≥80%: Enforce per service by adding coverageThreshold to that service’s jest.config.js and running pnpm --filter <service> test:cov in CI. Until a service opts in, the default test script 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.