Skip to main content

Testing

Running Tests

pnpm test # All unit tests (vitest run)
pnpm run test:watch # Watch mode
pnpm run test:coverage # Coverage report (V8 provider)
pnpm tsc --noEmit # Type-check (strict mode, src/ only)
No AIRS credentials needed for the unit suite

Unit tests never instantiate the @cdot65/prisma-airs-sdk clients. They inject mock service implementations directly into the code paths under test, so the SDK and its HTTP layer are bypassed entirely. You can run pnpm test with no AIRS env vars set.

Test Structure

tests/
├── unit/ spec files
│ ├── airs/ management.spec.ts, modelsecurity.spec.ts, promptsets.spec.ts,
│ │ redteam.spec.ts, runtime.spec.ts, scanner.spec.ts
│ ├── backup/ io.spec.ts
│ ├── cli/ backup-renderer.spec.ts, backup.spec.ts, bulk-scan-state.spec.ts,
│ │ parse-input.spec.ts, profile-builder.spec.ts, profiles-cleanup.spec.ts,
│ │ redteam-init.spec.ts, restore.spec.ts, topics-apply.spec.ts,
│ │ topics-create.spec.ts, topics-eval.spec.ts, topics-revert.spec.ts,
│ │ topics-sample.spec.ts
│ ├── config/ loader.spec.ts, schema.spec.ts
│ └── core/ constraints.spec.ts, metrics.spec.ts, prompt-loader.spec.ts
└── helpers/ mocks.ts

Mocking

Mocks are defined in tests/helpers/mocks.ts as service-level factories, not HTTP-level interceptors. Each factory returns an in-memory implementation of one of the project's service interfaces from src/airs/types.ts:

FactoryReturnsUsed to test
createMockManagementService()ManagementServiceTopic and profile CRUD code paths
createMockScanService()ScanServiceSynchronous scanning, with optional regex triggerPatterns
createMockAllowScanService()ScanServiceAllow-intent scanner behavior (matching prompts → topic_violation: true)
createMockRedTeamService()RedTeamServiceRed team scan and target operations
createMockModelSecurityService()ModelSecurityServiceModel security groups, rules, scans

The unit suite injects these mocks directly into the code under test via constructor or function arguments — the SDK and its Scanner / ManagementClient / RedTeamClient / ModelSecurityClient are never instantiated. Because no HTTP requests ever leave the process, no AIRS credentials are required.

No tests in this repo hit a live API. For live AIRS coverage, run the manual checklist in Live Smoke Tests — that's the authoritative way to catch backend wire-format drift, especially under SDK 0.8.0's now-on runtime Zod validation.

Coverage

Coverage is collected via V8 and excludes files that aren't meaningfully testable:

Excluded patternWhy
src/cli/**Interactive UI (prompts, rendering)
src/index.tsRe-exports only
**/types.tsType-only files, no runtime code

Thresholds (from vitest.config.ts): 90% lines, 95% functions, 80% branches, 90% statements.

pnpm run test:coverage

Running Specific Tests

Single file:

pnpm test -- tests/unit/core/metrics.spec.ts

By name pattern:

pnpm test -- -t "computes coverage as min of TPR and TNR"
Watch a single file
pnpm run test:watch -- tests/unit/core/metrics.spec.ts