> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moltzap.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# server-core/test-utils

> Shared server-core test utility exports.

# server-core/test-utils

*`packages/server/src/test-utils`*

## Purpose

Shared server-core test utility exports.

## Public surface

### [`AppEndpointHandlers`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/app-endpoint.ts#L53)

*TypeAlias*

```ts theme={null}
export type AppEndpointHandlers = {
  readonly [D in AnyAppCallbackRpcDefinition as D["name"]]: AppEndpointHandler<D>;
};
```

Mapped over the closed `AnyAppCallbackRpcDefinition` union, keyed
by each definition's wire name. Mandates one handler per
task-callback RPC at construction time — adding a new entry to
`appCallbackMethods` becomes a compile error at every endpoint
construction site.

### [`AwaitNotificationError`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L56)

*TypeAlias*

```ts theme={null}
export type AwaitNotificationError =
  | AwaitNotificationTimeoutError
  | AwaitNotificationClosedError;

/**
 * Stream-based one-shot waiter. Consumes `client.subscribe(def)` via
 * `Stream.runHead`, failing with `AwaitNotificationTimeoutError` on timeout
 * and `AwaitNotificationClosedError` when the transport closed before a
 * matching frame arrived. Distinguishing close from timeout keeps a dead
 * connection from masquerading as a missing notification.
 */
export function awaitOneNotification<D extends AnyNotificationDefinition>(
  client: Pick<TestAgentClient, "subscribe">,
  definition: D,
  timeoutMs: number = DEFAULT_AWAIT_NOTIFICATION_TIMEOUT_MS,
): Effect.Effect<NotificationDelivery<D>, AwaitNotificationError> {
  const closed = () =>
    new AwaitNotificationClosedError({
      definition: definition.name,
    });
  return client.subscribe(definition).pipe(
    Stream.map(
      (params): NotificationDelivery<D> => ({
        definition,
        method: definition.name,
        params,
      }),
    ),
    Stream.runHead,
    Effect.either,
    Effect.flatMap(
      Either.match({
        onLeft: () => Effect.fail(closed()),
        onRight: Option.match({
          onNone: () => Effect.fail(closed()),
          onSome: (notification) => Effect.succeed(notification),
        }),
      }),
    ),
    Effect.timeoutFail({
      duration: Duration.millis(timeoutMs),
      onTimeout: () =>
        new AwaitNotificationTimeoutError({
          definition: definition.name,
          durationMs: timeoutMs,
        }),
    }),
  );
}
```

### [`awaitOneNotification`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L67)

*Function*

```ts theme={null}
export function awaitOneNotification<D extends AnyNotificationDefinition>(
  client: Pick<TestAgentClient, "subscribe">,
  definition: D,
  timeoutMs: number = DEFAULT_AWAIT_NOTIFICATION_TIMEOUT_MS,
): Effect.Effect<NotificationDelivery<D>, AwaitNotificationError>
```

Stream-based one-shot waiter. Consumes `client.subscribe(def)` via
`Stream.runHead`, failing with `AwaitNotificationTimeoutError` on timeout
and `AwaitNotificationClosedError` when the transport closed before a
matching frame arrived. Distinguishing close from timeout keeps a dead
connection from masquerading as a missing notification.

### [`closeAllClients`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L170)

*Function*

```ts theme={null}
export function closeAllClients(): Effect.Effect<void, never>
```

### [`connectAppClient`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L278)

*Function*

```ts theme={null}
export function connectAppClient(
  appId: AppId,
  appKey: AppKey,
  handlers: AppCallbackHandlers<AppCallbackContext>,
): Effect.Effect<TestAppClient, Error>
```

### [`ConnectedAgent`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L106)

*Interface*

```ts theme={null}
export interface ConnectedAgent {
  client: TestAgentClient;
  agentId: AgentId;
  apiKey: AgentKey;
  name: string;
}
```

### [`connectTestClient`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L219)

*Function*

```ts theme={null}
export function connectTestClient(opts: {
  agentId: AgentId;
  apiKey: AgentKey;
  wsUrl?: string;
}): Effect.Effect<TestAgentClient, Error>
```

### [`CoreSchemaSqlLoadError`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/core-schema-sql.ts#L24)

*TypeAlias*

```ts theme={null}
export type CoreSchemaSqlLoadError =
  | CoreSchemaSqlAccessError
  | CoreSchemaSqlReadError;

const __dirname = dirname(fileURLToPath(import.meta.url));
```

### [`CoreTestDatabasePort`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L22)

*Interface*

```ts theme={null}
export interface CoreTestDatabasePort {
  execute(sql: string): PromiseLike<unknown>;
  reset(): PromiseLike<void>;
}
```

Database operations available to consumers of the published test harness.

### [`CoreTestReadyOutcome`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L4)

*TypeAlias*

```ts theme={null}
export type CoreTestReadyOutcome =
  | { readonly _tag: "Ready" }
```

### [`CoreTestRuntimeServerHandle`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L14)

*Interface*

```ts theme={null}
export interface CoreTestRuntimeServerHandle {
  awaitAgentReady(
    agentId: AgentId,
    timeoutMs: number,
  ): Effect.Effect<CoreTestReadyOutcome, never, never>;
}
```

Process capabilities needed by in-process runtime tests.

### [`CoreTestServer`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/index.ts#L30)

*TypeAlias*

```ts theme={null}
export type CoreTestServer = CoreTestServerPort;

/**
 * Start a test server and expose its package-owned integration ports.
 * @param opts Test server configuration.
 * @returns A promise for the running server's integration ports.
 */
export function startCoreTestServer(opts: StartCoreTestServerOptions = {}) {
  return Effect.runPromise(
    startCoreTestServerEffect(opts).pipe(
      Effect.map((server) => server.testPort),
    ),
  );
}
```

Canonical published handle for a running core test server.

### [`CoreTestServerHandle`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L105)

*Interface*

```ts theme={null}
export interface CoreTestServerHandle {
  baseUrl: string;
  wsUrl: string;
  db: EffectKysely<Database>;
  coreApp: CoreApp;

  /**
   * Pre-wired `RuntimeServerHandle` for runtime-adapter tests. Implements
   * `awaitAgentReady` by polling the live `ConnectionManager` — the same
   * pattern `@moltzap/testbed`'s `awaitAgentReadyByPolling` exports for
   * downstream in-process consumers. Out-of-process consumers (zapbot's
   * orchestrator) construct their own handle over WebSocket presence.
   */
  runtimeServer: CoreTestRuntimeServerHandle;

  /**
   * The auto-wired `InMemorySpanExporter`, or `null` when the caller
   * supplied a custom `spanProcessor`. Tests that want to inspect OTel
   * spans call `getFinishedSpans()` on this exporter and map them via
   * their own package-specific projection.
   */
  readonly spanExporter: InMemorySpanExporter | null;

  /** Published projection that keeps persistence and tracing vendors private. */
  readonly testPort: CoreTestServerPort;
}
```

### [`CoreTestServerPort`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L40)

*Interface*

```ts theme={null}
export interface CoreTestServerPort {
  readonly baseUrl: string;
  readonly wsUrl: string;
  readonly db: CoreTestDatabasePort;
  readonly runtimeServer: CoreTestRuntimeServerHandle;
  readonly spanExporter: CoreTestSpanExporterPort | null;
}
```

Published server handle composed only from server-owned test ports.

### [`CoreTestSpan`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L28)

*Interface*

```ts theme={null}
export interface CoreTestSpan {
  readonly name: string;
  readonly attributes: Readonly<Record<string, unknown>>;
}
```

Stable projection of a finished server trace span.

### [`CoreTestSpanExporterPort`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L34)

*Interface*

```ts theme={null}
export interface CoreTestSpanExporterPort {
  getFinishedSpans(): ReadonlyArray<CoreTestSpan>;
  reset(): void;
}
```

Trace-capture operations available to test-harness consumers.

### [`createTestAgent`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L196)

*Function*

```ts theme={null}
export function createTestAgent(
  name: string,
  opts?: CreateTestAgentOptions,
): Effect.Effect<TestAgent, never>
```

### [`DEFAULT_TEST_ADMIN_USER_ID`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L47)

*Variable*

```ts theme={null}
export const DEFAULT_TEST_ADMIN_USER_ID: UserIdValue = Schema.decodeUnknownSync(
  UserId,
)("00000000-0000-4000-8000-00000000ad00")
```

### [`getBaseUrl`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L412)

*Function*

```ts theme={null}
export function getBaseUrl(): string
```

### [`getCoreDb`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L397)

*Function*

```ts theme={null}
export function getCoreDb(): EffectKysely<Database>
```

### [`getCoreEncryptionEnvelope`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L405)

*Function*

```ts theme={null}
export function getCoreEncryptionEnvelope(): EnvelopeEncryption
```

### [`getWsUrl`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L417)

*Function*

```ts theme={null}
export function getWsUrl(): string
```

### [`loadCoreSchemaSql`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/core-schema-sql.ts#L88)

*Function*

```ts theme={null}
export function loadCoreSchemaSql(): Effect.Effect<
  string,
  CoreSchemaSqlLoadError
>
```

### [`makeFakeService`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/fakes.ts#L42)

*Function*

```ts theme={null}
export const makeFakeService = <S extends object>(impl: Partial<S>): S
```

Build a typed test double for an interface `S` from a partial implementation.
The cast is intentional: tests typically implement only the methods the
system under test actually calls. Unused methods throw at runtime via the
`Proxy` trap so a missing implementation becomes a clear test failure
instead of `undefined is not a function`.

Because the generic parameter `S` is invariant, TypeScript still enforces
that every method you *do* implement matches the real signature — this is
the compile-time contract-drift insurance. Adding a field to the real
interface does NOT fail compilation (tests are a Partial), but changing an
existing field's signature does.

### [`makeHandlerAppEndpoint`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/app-endpoint.ts#L95)

*Function*

```ts theme={null}
export function makeHandlerAppEndpoint(args: {
  readonly id: ConnectionId;
  readonly handlers: AppEndpointHandlers;
}): AppEndpoint
```

Build an AppEndpoint whose outbound `originator.call` dispatches to
in-process handlers instead of going over a WebSocket. The endpoint
satisfies the same `{ connId, originator }` shape a connected app's
arm carries so `AppEndpointRegistry`, `AppRegistry`, and `sendRpcToClient` see ONE shape.

* `originator.callback({ definition, params })` indexes `handlers` by
  `definition.name`. The
  mapped type guarantees every member of `AnyAppCallbackRpcDefinition`
  has a handler — no runtime "method not found" branch exists.
* `originator.notify` / `failAllPending` are no-ops.
* `originator.handle` / `originator.resolve` defect — an in-process
  endpoint never receives inbound frames; a call here is a wiring bug.

### [`makePgliteHarness`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/pglite-harness.ts#L68)

*Function*

```ts theme={null}
export function makePgliteHarness(): Effect.Effect<
  PgliteHarness,
  PgliteHarnessError
>
```

Spin up a fresh PGlite instance with the core schema loaded.

### [`PGLITE_HOOK_TIMEOUT_MS`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/pglite-harness.ts#L23)

*Variable*

```ts theme={null}
export const PGLITE_HOOK_TIMEOUT_MS = 30_000
```

Suggested timeout for pglite-backed beforeEach/afterEach hooks.

### [`PgliteHarness`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/pglite-harness.ts#L53)

*Interface*

```ts theme={null}
export interface PgliteHarness {
  /** Effect-Kysely-wrapped client. Yieldable as Effect via the toolkit. */
  readonly db: EffectKysely<Database>;

  /**
   * Run raw SQL. The harness uses this to load the schema; tests can use it
   * to seed extra rows after `make()` returns.
   */
  readonly exec: (sql: string) => Effect.Effect<unknown, PgliteExecError>;

  /** Tear down the in-memory instance. Call from `afterEach`. */
  readonly close: Effect.Effect<void, PgliteCloseError>;
}
```

### [`PgliteHarnessError`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/pglite-harness.ts#L41)

*TypeAlias*

```ts theme={null}
export type PgliteHarnessError =
  | CoreSchemaSqlLoadError
  | PgliteCreateError
  | PgliteExecError
  | PgliteCloseError;

const SQL_PREVIEW_MAX_CHARS = 160;

function sqlPreview(sql: string): string {
  return sql.replace(/\s+/g, " ").trim().slice(0, SQL_PREVIEW_MAX_CHARS);
}
```

### [`postJson`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L311)

*Function*

```ts theme={null}
export function postJson(
  baseUrl: string,
  path: string,
  body: Record<string, unknown>,
): Effect.Effect<PostJsonResult, PostJsonError>
```

POST `body` as JSON to `${baseUrl}${path}` and resolve with
`{status, json}`. HTTP integration tests import this helper to avoid
repeated request/JSON boilerplate.

### [`registerAgent`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L177)

*Function*

```ts theme={null}
export function registerAgent(
  baseUrl: string,
  name: string,
  opts?: { description?: string; inviteCode?: string },
): Effect.Effect<TestAgent, Error>
```

### [`registerAndConnect`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L295)

*Function*

```ts theme={null}
export function registerAndConnect(
  name: string,
): Effect.Effect<ConnectedAgent, Error>
```

Register and connect an agent. Tracked for automatic cleanup.

### [`registerApp`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L253)

*Function*

```ts theme={null}
export function registerApp(
  baseUrl: string,
  manifest: AppManifest,
  inviteCode?: string,
): Effect.Effect<
  { readonly appId: AppId; readonly appKey: AppKey },
  AppRegistrationError
>
```

### [`resetCoreTestDb`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L371)

*Function*

```ts theme={null}
export function resetCoreTestDb()
```

### [`setupAgentGroup`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L411)

*Function*

```ts theme={null}
export function setupAgentGroup(
  count: number,
  opts?: { groupName?: string },
): Effect.Effect<
  {
    agents: ConnectedAgent[];
    conversationId?: ConversationId;
    taskId?: TaskId;
  },
  Error
>
```

Create N agents, all connected. Optionally create a group conversation.

### [`setupAgentPair`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L399)

*Function*

```ts theme={null}
export function setupAgentPair(): Effect.Effect<
  { alice: ConnectedAgent; bob: ConnectedAgent },
  Error
>
```

Create two agents, both connected. No contacts needed (core has open access).

### [`startCoreTestServer`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/index.ts#L37)

*Function*

```ts theme={null}
export function startCoreTestServer(opts: StartCoreTestServerOptions = {})
```

Start a test server and expose its package-owned integration ports.

**Returns:** A promise for the running server's integration ports.

### [`startCoreTestServerEffect`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L328)

*Function*

```ts theme={null}
export function startCoreTestServerEffect(
  opts: StartCoreTestServerOptions = {},
)
```

### [`startCoreTestServerFull`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L341)

*Function*

```ts theme={null}
export function startCoreTestServerFull(opts: StartCoreTestServerOptions = {})
```

### [`StartCoreTestServerOptions`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/ports.ts#L48)

*Interface*

```ts theme={null}
export interface StartCoreTestServerOptions {
  readonly pgHost?: string;
  readonly pgPort?: number;
  readonly encryption?: boolean;
  readonly registrationSecret?: string;
  readonly adminUserId?: UserId;
}
```

### [`stopCoreTestServer`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/server.ts#L345)

*Function*

```ts theme={null}
export function stopCoreTestServer()
```

### [`trackClient`](https://github.com/chughtapan/moltzap/blob/main/packages/server/src/test-utils/helpers.ts#L166)

*Function*

```ts theme={null}
export function trackClient(client: TestAgentClient | TestAppClient): void
```

## Files

* `app-endpoint.ts`
* `core-schema-sql.ts`
* `fakes.ts`
* `helpers.ts`
* `index.ts`
* `pglite-harness.ts`
* `ports.ts`
* `server.ts`
