Skip to main content

Testing

Running Tests

pnpm test # all 151 tests, 15 suites
pnpm test:watch # watch mode with re-run on change

Test Suites

SuiteTestsWhat It Covers
config.test.ts22Config loading, validation, env var resolution, .codex path walk-up, fail_mode, readFailMode
airs-client.test.ts9SDK wrapper, prompt/response scanning, block verdicts
scanner.test.ts22Observe/enforce/bypass modes, UX messages, separator width, fail-open/fail-closed, correlation pass-through
code-extractor.test.ts10Fenced, indented, heuristic extraction, mixed content
codex-adapter.test.ts6Exact Codex stdout shapes per event (block/deny/stop)
tool-name-parser.test.ts11mcp__server__tool parsing, isMcpToolName
hooks-config.test.ts13hooks.json build/merge/remove, idempotency, foreign-hook preservation, absolute-node commands
circuit-breaker.test.ts7State transitions, cooldown, probe success/failure
content-limits.test.ts6Skip/truncate thresholds
dlp-masking.test.ts8Enforcement priority, content masking
logger.test.ts5JSON Lines output, content stripping, directory creation
log-rotation.test.ts3Size threshold, rotation, missing file handling
hooks-integration.test.ts21End-to-end Codex JSON contract (tsx + compiled JS)
bundles.test.ts5Standalone bundle runs from a temp dir, size budget
cli.test.ts3CLI dispatch, usage, invoking-cwd behavior

Integration Tests

The hooks-integration.test.ts suite runs actual hook scripts with piped JSON:

// Runs: echo '{"prompt":"..."}' | npx tsx src/hooks/user-prompt-submit.ts
// And: echo '{"prompt":"..."}' | node dist/hooks/user-prompt-submit.js

These verify the real Codex contract end-to-end, including JSON parsing, config loading, fail-open and fail-closed behavior, the PreToolUse silent-allow rule, and the Stop JSON-only stdout rule.

The bundles.test.ts suite goes one step further: it spawns each minified dist/hooks/*.mjs bundle from an OS temp directory with no node_modules or NODE_PATH available, proving the bundles are genuinely self-contained.

Mocking

  • AIRS API: Not mocked in integration tests -- hooks fail-open when the API is unreachable, which validates the fail-mode design
  • SDK: Mocked via vi.mock("@cdot65/prisma-airs-sdk") in unit tests (airs-client.test.ts); the scanner suite mocks src/airs-client.ts
  • File system: Tests use temporary directories (test/.tmp-*) cleaned up in afterEach

Adding Tests

  1. Create test/<module>.test.ts matching the source file
  2. Use vitest's describe/it/expect API
  3. Clean up any temp files in afterEach
  4. For integration tests, use spawnSync to run hooks with piped JSON