Skip to content
DomainKit
Esc
↑↓navigate↵open⌘Jpreview
On this page

domainkit/testing

The fakes, the recording transport, and the conformance runners that let host tests drive the real services instead of stubbing global fetch.

import { Testing } from "domainkit/testing";
Namespace Carries
Testing provider, resolver, storage, principal, transport, fakeRecords, conformance
VERSION The installed package version, so a test can assert what it is running against

Fakes

Value Gives
Testing.provider A provider definition with a token method, optional OAuth, over in-memory zones
Testing.resolver A Resolver answering from those zones, or from a table you pass
Testing.storage Storage.layerMemory, re-exported here for discoverability
Testing.principal A fixed { ownerId, actorId } for tests that do not care which tenant
Testing.transport The whole lifecycle behind a Transport.Interface, recording every call
Testing.fakeRecords What the fake providers currently hold for a name
/**
 * A provider definition over in-memory zones, with a token method and optionally OAuth. Give each
 * test its own zone: `Testing.provider` registers zones in one process-wide table that
 * `Testing.resolver` reads.
 */
export const fake = Testing.provider({
  zones: ["plans.example.com"],
  records: [
    {
      zone: "plans.example.com",
      record: DnsRecord.txt({ name: "_acme.plans.example.com", value: "acme-verify=7f3a" }),
    },
  ],
  oauth: true,
});

Options

Option Effect
id The provider id. Default fake
name The name a customer reads. Default Fake <id>
zones Zones the fake credential reaches. Default example.com
labels The label each zone carries, keyed by zone. Default: the zone name
accountLabel What the fake calls the account it issues credentials for. Default: none, so the label is null
records Pre-existing records, to produce Noop and Conflict operations
oauth Offer OAuth beside the token method; the fake redirects to callbackUrl immediately
failWrite A predicate over the zero-based write index; a write fails when it returns true, to exercise a partial receipt
nameservers Nameservers per zone, which Testing.resolver answers NS queries from
nameserverSuffixes Suffixes the fake declares as Definition.nameservers, so Connect.discover names it as a host

The recording transport

/**
 * The whole lifecycle behind a `Transport.Interface`, over an in-memory server, recording every
 * call. Declare fewer capabilities to render a UI against a host that mounted only part of the
 * group.
 */
export const transport = Testing.transport({ capabilities: ["connection", "provisioning"] });

export const callsSoFar = () => transport.calls.map((call) => call.method);

Testing.transport mounts domainkit/server over memory storage and a fake provider, then wraps Transport.fromFetch around that handler. calls holds { method, input } for every call, oldest first, where method reads connection.inspect, provisioning.approve, and so on. There is nothing to dispose.

Conformance

Runner Checks
Testing.conformance.storage Tenant isolation and the one deliberate exception to it, apply leases, exactly-once continuations, revocation recovery, locks
Testing.conformance.provider Create and read back, exact no-op, conflict, stale plan, partial apply, cleanup, rejected token
/**
 * Register every `Storage` invariant with your test runner: tenant isolation, apply leases,
 * exactly-once continuations, revocation recovery, and lock semantics. Both shipped
 * implementations pass this suite, so a host can swap them without a behaviour change.
 */
export const registerStorageCases = (
  layer: Layer.Layer<Storage.Service, unknown>,
  it: (name: string, run: () => Promise<void>) => void,
) => Testing.conformance.storage(layer, { it });
/**
 * A provider author runs this against a real account before shipping: create and read back, exact
 * no-op, conflict, stale plan, and partial apply, all through the same services hosts use. Every
 * record it creates carries the prefix and is removed again.
 */
export const check = (definition: Provider.Definition, token: string, zone: string) =>
  Testing.conformance.provider(
    definition,
    { secret: Redacted.make(token), context: { apiKey: token } },
    zone,
    { prefix: "acme-conformance" },
  );

export const run = (definition: Provider.Definition, token: string) =>
  Effect.runPromise(check(definition, token, "example.com"));

The provider runner writes to a real account. Every record it creates carries the prefix and is removed again, so point it at a zone you own and can inspect.

The rejected-token case authenticates with every required token field set to an empty secret and expects Unauthenticated. A token method with a required non-secret field, such as a region selector, needs rejectedToken: the values the provider rejects, keyed by field name.

Last updated on

Was this page helpful?