@kilterset/auth0-actions-testing
Version:
Test and develop Auth0 Actions or Okta CIC Actions locally.
65 lines (41 loc) • 4.82 kB
Markdown
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What this is
`@kilterset/auth0-actions-testing` is a published npm library that lets developers test Auth0 / Okta CIC Actions locally. It builds realistic, randomized `event` and `api` mock objects for each Auth0 Flow, lets a test `simulate()` an Action handler against them, and then exposes the resulting state for assertions. Written in TypeScript, compiled to CommonJS in `dist/`, targeting Node 18 and 22 (the Node versions Auth0 Actions run on).
## Commands
```sh
npm run build # tsc --build, then copy hand-written .d.ts files into dist (see Build quirk)
npm run build:watch # tsc --watch
npm run build:clean # rm -rf dist && build
npm test # test:src + test:examples
npm run test:src # node --test on dist/**/*.test.js — REQUIRES a build first
npm run test:examples # cd examples && node --test (runs the example .js tests)
```
Run a single test file (after building):
```sh
node --test dist/test/api/post-login.test.js
node --test --test-name-pattern "lucky number" dist/test/api/post-login.test.js
```
There is no separate lint step. Type-checking happens through `tsc` during build.
### Build quirk
Tests run against compiled output in `dist/`, not `src/`. **You must `npm run build` before `test:src` will see your changes.** The build has two stages: `tsc --build` compiles `.ts`, then `build:copy-declarations` rsyncs hand-authored `.d.ts` files from `src/` into `dist/` (tsc does not emit these because they are declaration source, not compiled). If you add a new `.d.ts` type file, it only reaches `dist/` through this copy step.
## Architecture
### The three-layer mock pattern (per Flow)
Every supported Flow (PostLogin, CredentialsExchange, PreUserRegistration, etc.) is implemented as three coordinated layers. To add or change a Flow, you touch all three:
1. **`src/mock/events/<flow>.ts`** — builds the randomized `event` payload (the first argument an Action receives). Uses `define()` + `chance` for realistic random data.
2. **`src/mock/api/<flow>.ts`** — the heart of the pattern. Returns `{ implementation, state }`:
- `implementation` is the `api` object passed to the Action. Its properties are **getters that rebuild a fresh api facade on each access** (e.g. `get access() { return access.build(api); }`), so method calls mutate a shared `state` object.
- `state` is a plain object recording the cumulative effect of `api` calls (denied access, set metadata, redirects, etc.). This is what tests assert against.
3. **`src/mock/actions/<flow>.ts`** — wires event + api together. Exposes `simulate(handler)` which runs the Action, and returns a **`Proxy`** that surfaces both `{ event, simulate }` and every key of `state`, so a test can read `action.user`, `action.access.denied`, etc. directly.
Individual `api` sub-behaviors live in their own files under `src/mock/api/` (`access.ts`, `cache.ts`, `redirect.ts`, `user.ts`, ...) and follow the same `{ build, state }` shape so they can be composed into each Flow's api.
### Randomized data
`src/mock/define.ts` wraps [Fishery](https://github.com/thoughtbot/fishery) factories into a simple `(attributes?, transient?) => built` function. Factories use `chance` (`src/mock/chance/`) for randomized values. The design philosophy (see README): explicitly declared attributes are fixed; everything else is randomized each run — some optional fields randomly resolve to `undefined`. Tests should pin any value the Action's behavior depends on.
### Top-level exports (`src/index.ts`)
- `mock` — everything above (`mock.actions.postLogin(...)`, `mock.user(...)`, `mock.api`, `mock.events`).
- `jwt` — `src/jwt/`, HS256 sign/decode for testing redirect-with-JWT flows.
- `nodeTestRunner` — `src/test-runners/node-test-runner/`. `actionTestSetup(t)` configures `fetch-mock` (with a fetch polyfill for older Node) and registers cleanup via the test context's `afterEach`. Returns `{ fetchMock, auth0 }`.
### Other pieces
- `src/script-analysis/` — static analysis of Action source code (`requires`, `exports`, `secrets`), exposed via `ANALYSERS` and `analyse`.
- `src/types/` — hand-authored `.d.ts` files describing the Auth0 `Events`, `API`, `User`, etc. shapes. These are the contract the mocks implement; keep them in sync when a Flow's mock changes. (Copied to `dist/` by the build, see above.)
### Tests
`src/test/**/*.test.ts` mirror the `mock/` and `api/` structure. The `examples/` directory is a separate npm package of runnable example Actions + tests (plain `.js`) that doubles as both documentation and an integration test suite; CI builds the library, `npm install`s in `examples/`, then runs both suites across Node 18 and 22.