kavachOS

Test utilities

Mock auth for testing your app.

@kavachos/test-utils provides factories, mock servers, and assertion helpers so you can test auth-dependent code without a real database or network.

Install

pnpm add -D @kavachos/test-utils

Factories

Factory functions create realistic mock entities with sensible defaults. Pass overrides for any fields relevant to the test.

import {
  createMockUser,
  createMockSession,
  createMockAgent,
  createMockPermission,
} from '@kavachos/test-utils';

const user = createMockUser({ email: 'alice@example.com' });
const session = createMockSession({ user });
const agent = createMockAgent({ type: 'service', permissions: [] });
const perm = createMockPermission({ resource: 'files', actions: ['read', 'write'] });

Each call generates unique IDs, so you can create multiple entities in the same test without collisions.

Mock auth server

createMockAuthServer returns an in-memory AuthAdapter implementation with zero network or database calls. Use it in server-side unit tests that exercise code paths calling resolveUser, getUser, or syncUser.

import { createMockAuthServer, createMockUser } from '@kavachos/test-utils';

const server = createMockAuthServer();
const user = createMockUser();

server.addUser(user);
server.setActiveUser(user.id);

const resolved = await server.resolveUser(new Request('https://example.com'));
// resolved.id === user.id

Per-request user override

Set the x-mock-kavach-user-id header on a Request to override the active user for that specific request only, without calling setActiveUser:

import { MOCK_USER_ID_HEADER } from '@kavachos/test-utils';

const req = new Request('https://example.com', {
  headers: { [MOCK_USER_ID_HEADER]: user.id },
});

const resolved = await server.resolveUser(req);

Cleanup

afterEach(() => server.reset()); // clears the store and active session

Assertions

Three typed assertion helpers narrow ActionResult<T> and throw descriptive errors on failure.

import {
  expectAuthenticated,
  expectUnauthenticated,
  expectPermissionDenied,
} from '@kavachos/test-utils';

// Passes only when result.success === true
expectAuthenticated(result);
console.log(result.data); // typed

// Passes only when result.success === false
expectUnauthenticated(result);

// Passes only when result.success === false and error contains "permission"
expectPermissionDenied(result);

// Custom substring match
expectPermissionDenied(result, 'not allowed');

The mock server has zero runtime dependencies. It matches the AuthAdapter interface structurally, so TypeScript will accept it anywhere an AuthAdapter is expected.

On this page