39948-vm/backend/docs/testing.md
2026-07-03 16:11:24 +02:00

78 lines
4.1 KiB
Markdown

# Backend Testing
## Overview
Backend tests use Node.js 24's built-in test runner and TypeScript test files.
The suite is split into three layers:
| Layer | Command | Location | Purpose |
|-------|---------|----------|---------|
| Unit | `npm run test` | `backend/tests/*.test.ts` | Pure helpers, validators, policy decisions, service contracts, and file/session utilities |
| Integration | `npm run test:integration` | `backend/tests/integration/*.test.ts` | Cross-module behavior such as DB-backed access policy and Express router factory contracts |
| E2E | `npm run test:e2e` | `backend/tests/e2e/*.test.ts` | Real HTTP request/response checks against local Express test apps |
| Full suite | `npm run test:all` | all test folders | Runs unit, integration, and e2e in sequence |
| Verification | `npm run verify` | static checks plus all test folders | Runs typecheck, lint, ESM boundary checks, and the full test suite |
## Current Coverage
- Request validation and `commonErrorHandler` JSON handling.
- Publish, file upload/presign, upload chunk, and tour page reorder request
validation contracts.
- File service path validation, structured file error payloads, and local
presigned URL fallback behavior.
- Environment validation for config-only runtime settings, including normalized
file-storage provider overrides.
- Circuit breaker behavior for ignored failures, recorded failures, and open
breaker rejection.
- Auth service password reset, password update rejection rules, and email
verification token behavior with real bcrypt and DB writes.
- Route ID/body ID update contract enforcement.
- Permission name mapping, own-user route bypass, runtime public read bypass,
and `AccessPolicy` public-user hardening.
- Generic DB API and entity service object-signature contracts.
- OpenAPI route coverage and internal `$ref` resolution.
- `UploadSessionManager` metadata, chunk tracking, assembly order, and cleanup behavior.
- `createEntityRouter` service/DB option propagation, query normalization, update ID mismatch handling, and CSV export behavior.
- Public runtime list blocking and response sanitization for presentation data.
- Publish service environment copy behavior for dev to stage and stage to production,
including target replacement, source preservation, audio tracks, transition
settings, and UI-control settings.
- Runtime context HTTP behavior for default, valid, and unsupported runtime headers.
## Environment Notes
DB-backed integration tests authenticate against the configured PostgreSQL
connection. If PostgreSQL is unavailable, those tests call `t.skip()` with the
connection error so non-DB integration tests can still run.
`npm run test:integration` runs with `--test-concurrency=1` because several
integration tests share a PostgreSQL transaction connection; keep DB-backed
tests sequential unless they use isolated connections.
E2E tests bind a local HTTP listener on `127.0.0.1` with an ephemeral port. In
restricted sandboxes this may require elevated permission for local socket
binding.
## Test Helpers
`backend/tests/http-test-utils.ts` provides `startTestServer(app)`, which starts
an Express app on an ephemeral local port and returns `{ baseUrl, close }`.
Use it only for e2e-style tests that must exercise real HTTP semantics.
Integration tests that do not need a network socket should drive Express apps in
memory with `node-mocks-http`; this keeps them usable in restricted sandboxes.
## Adding Tests
- Prefer unit tests for pure helpers, validators, policies, and isolated service
logic.
- Use integration tests when behavior crosses route, middleware, service, DB API,
or Sequelize transaction boundaries.
- Use e2e tests when the behavior depends on real HTTP parsing, headers, status
codes, or socket-level request handling.
- Keep new backend tests strict TypeScript compatible and avoid casts, `any`,
`eslint-disable`, and `@ts-ignore`.
- When config-backed behavior must be overridden in tests, mutate the typed
config object and restore it in `finally`; do not rely on changing
`process.env` after modules have imported `backend/src/config.ts`.
- For DB integration tests, wrap writes in a transaction and roll it back.