# zidane-ui/extensions/testing/contract

Import: `import { … } from 'zidane-ui/extensions/testing/contract'`. Source: [ui/src/extensions/testing/contract.ts](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts).

## Functions

### `describeExtensionsHostContract`

Function.

Declares the shared `ExtensionsHost` suite for one implementation.

```ts
function describeExtensionsHostContract(
  name: string,
  makeHarness: ExtensionsHostHarnessFactory,
  capabilities: readonly ExtensionsHostCapability[],
): void
```

**Parameters**

- `name` (`string`): The implementation's name, shown in the suite title.
- `makeHarness` (`ExtensionsHostHarnessFactory`): Builds a fresh host over a backend that does what it is given, once per test.
- `capabilities` (`readonly ExtensionsHostCapability[]`): The optional members the host offers. Every other optional member must be undefined.

Source: [ui/src/extensions/testing/contract.ts:187](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L187)

## Constants

### `CONTRACT_GOOD_KEY`

Constant.

The API key the backend's integrations accept.

```ts
const CONTRACT_GOOD_KEY = 'good-key'
```

Source: [ui/src/extensions/testing/contract.ts:105](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L105)

### `CONTRACT_STORE`

Constant.

The store the storage tests read and write.

```ts
const CONTRACT_STORE: ExtensionStoreRef
```

Source: [ui/src/extensions/testing/contract.ts:103](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L103)

## Interfaces

### `ExtensionsHostContractBackend`

Interface.

What the backend behind the host holds and does.

```ts
interface ExtensionsHostContractBackend
```

**Properties**

- `callbacks` (`{ 'badge.menu'?: (args: { target: BadgeTarget }) => readonly BadgeMenuItem[]; 'badge.run'?: (args: { actionId: string; cwd?: string; sessionId?: string; source: string; target: BadgeTarget }) => BadgeActionEffect; 'panel.action'?: (args: { actionId: string; context?: unknown; cwd: string; panelId: string; payload?: unknown }) => boolean; 'panel.load'?: (args: { context?: unknown; cwd: string; panelId: string }) => PanelContent; 'reference.resolve'?: (args: { key: string; providerId: string }) => ExtensionReferenceView | null; 'setting.action'?: (args: { key: string; pageId: string }) => { message?: string; patch?: Readonly<Record<string, string | number | boolean | readonly string[]>>; tone?: 'error' | 'success' | 'warn' | 'info' } | undefined; 'setting.status'?: (args: { key: string; pageId: string }) => { text: string; tone?: 'error' | 'muted' | 'success' | 'warn' } | undefined }`): What each callback answers. A callback that throws answers `failed` with its message.
- `commands` (`readonly ExtensionCommandWire[]`): The commands. Running an unknown id answers `false`.
- `integrations` (`readonly ExtensionIntegrationWire[]`): The integrations. `connect` with the key [`CONTRACT_GOOD_KEY`](https://zidane.si/docs/reference/ui-extensions-testing-contract.md#CONTRACT_GOOD_KEY) adds the account `demo` (the first
  connection becomes the default); any other key is refused (`refused` / `invalid`). `disconnect` removes
  one account, or all with none named; `setDefault` moves an account first and makes it the default. The
  list keeps the default first, the only one with `isDefault`, also as `connection`.
- `items` (`readonly ExtensionItem<keyof ExtensionWireMap>[]`): The items there at the start.
- `rpc` (`Readonly<Record<string, Readonly<Record<string, ContractRpcMethod>>>>`): RPC methods, by contract then method.
- `settings` (`ExtensionSettingsWire`): The settings. The backend refuses a write to a locked key (`refused` / `locked`).
- `storeValue` (`unknown`): The stored value of [`CONTRACT_STORE`](https://zidane.si/docs/reference/ui-extensions-testing-contract.md#CONTRACT_STORE).

Source: [ui/src/extensions/testing/contract.ts:44](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L44)

### `ExtensionsHostContractControl`

Interface.

Drives the backend from outside.

```ts
interface ExtensionsHostContractControl
```

**Properties**

- `dialog` (`(request: DialogRequest, ctx: { extensionId: string; sessionId?: string; signal?: AbortSignal }) => Promise<unknown>`): An extension asked for a dialog routed to this client; resolves with the answer.
- `effect` (`(effect: ExtensionUiEffect) => Promise<ExtensionUiEffectResult>`): An extension's `ctx.ui` / `ctx.composer` call routed to this client; resolves with what the app settled.
- `ran` (`() => readonly { args?: string; id: string; sessionId?: string }[]`): The commands the backend ran.
- `readStore` (`() => unknown`): [`CONTRACT_STORE`](https://zidane.si/docs/reference/ui-extensions-testing-contract.md#CONTRACT_STORE)'s value in the backend now.
- `remove` (`(key: string) => void`): An extension withdrew an item.
- `upsert` (`(entry: ExtensionItem) => void`): An extension added or changed an item.
- `writeStore` (`(value: unknown) => void`): Another client wrote [`CONTRACT_STORE`](https://zidane.si/docs/reference/ui-extensions-testing-contract.md#CONTRACT_STORE).

Source: [ui/src/extensions/testing/contract.ts:67](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L67)

### `ExtensionsHostHarness`

Interface.

A host built over a backend, the backend's control, and how to tear them down.

```ts
interface ExtensionsHostHarness
```

**Properties**

- `control` (`ExtensionsHostContractControl`): Drives the backend the host talks to.
- `host` (`ExtensionsHost`): The host under test.
- `dispose?` (`() => void`): Tears the host and its backend down after the test.

Source: [ui/src/extensions/testing/contract.ts:88](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L88)

## Types

### `ContractRpcMethod`

Type.

A scripted RPC method: returns its output, or throws `{ type, message, data? }` to answer that error.

```ts
type ContractRpcMethod = (input: unknown) => unknown
```

Source: [ui/src/extensions/testing/contract.ts:41](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L41)

### `ExtensionsHostCapability`

Type.

An optional `ExtensionsHost` member. `settings.set` is the settings' write.

```ts
type ExtensionsHostCapability =
  | 'invoke'
  | 'dialogs'
  | 'effects'
  | 'rpc'
  | 'storage'
  | 'settings'
  | 'settings.set'
  | 'integrations'
  | 'commands'
```

Source: [ui/src/extensions/testing/contract.ts:35](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L35)

### `ExtensionsHostHarnessFactory`

Type.

Builds a fresh host (and its backend) for one test.

```ts
type ExtensionsHostHarnessFactory = (backend: ExtensionsHostContractBackend) => ExtensionsHostHarness | Promise<ExtensionsHostHarness>
```

Source: [ui/src/extensions/testing/contract.ts:98](https://github.com/Tahul/zidane/blob/main/ui/src/extensions/testing/contract.ts#L98)
