# Testing Patterns

## Test Coverage Goal

Tests should cover all paths in the corresponding `docs/commands/*.md`:

- **Process Flow**: Each branch in the mermaid flowchart = one test case
- **Error Scenarios**: Each error code listed = one test case
- **Idempotent paths**: If flowchart shows "Already exists? → Return existing"

## Mock Database

```typescript
const { db, spies } = createMockDb<DB>();

// Single return
spies.select.mockReturnValue(entity);

// Sequential returns (in query execution order)
spies.select.mockReturnValueOnce(first).mockReturnValueOnce(second);
```

## Custom Fields Passthrough

For commands with generic `CF`, add one test verifying custom fields reach `.values()`:

- Import from `./createX.generated` (the generated shell that wires permissions)
- Pass extra fields in the input: `await createX(db, { name: "Test", myField: "value" }, ctx)`
- Assert with `spies.values`: `expect(spies.values).toHaveBeenNthCalledWith(1, expect.objectContaining({ myField: "value" }))`
- Use `toHaveBeenNthCalledWith(n, ...)` when multiple inserts occur (e.g., audit events)

## Test Case Documentation Sync

Command and query docs include a `## Test Cases` section listing each `it()` description. This list must stay in sync with the actual test file:

- Each `it("...")` in the test file must appear as `- ...` in the doc's `## Test Cases`
- Each item in `## Test Cases` must have a corresponding `it()` in the test file
- Run `erp-kit module sync-check` to verify alignment
- When adding a new test, add the `it()` description to the doc first, then write the test
- Test case descriptions should match the doc's Process Flow branches and Error Scenarios

## Fixtures (`testing/fixtures.ts`)

- Import `Schema` from `lib/types` (not `Namespace` from generated code)
- Pattern: `export const baseEntity = { ... } as const satisfies Entity<Schema>`
- Fixed IDs for traceability: `"entity-1"`
- Consistent timestamp: `new Date("2024-01-01T00:00:00.000Z")`
- `updatedAt: null` for base fixtures
