Files
clean-architecture-frontend…/tests/features/reference-feature/reference-http-gateway.test.ts
T

106 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { Result } from "../../../src/contracts/result.ts";
import { createFailure, type ApiFailure } from "../../../src/contracts/errors.ts";
import {
createReferenceHttpGateway,
type ReferenceHttpBinding,
} from "../../../src/features/reference-feature/adapters/reference-http-gateway.ts";
import type { ReferenceResource } from "../../../src/features/reference-feature/domain/reference-resource.ts";
const resources = Object.freeze({
first: Object.freeze({
id: "reference-1",
displayName: "First",
createdAt: null,
}),
created: Object.freeze({
id: "reference-2",
displayName: "Created",
createdAt: "2026-07-26T00:00:00.000Z",
}),
}) satisfies Readonly<Record<string, ReferenceResource>>;
type ScriptedResult = Result<
ReferenceResource | readonly ReferenceResource[],
ApiFailure
>;
function scriptedBinding(results: ScriptedResult[]) {
const calls: Array<
readonly [operationId: string, input: unknown, context: unknown]
> = [];
let index = 0;
const execute = (async (
operationId: string,
input: unknown,
context?: unknown,
) => {
calls.push([operationId, input, context]);
const result = results[index];
index += 1;
if (!result) throw new Error("Missing scripted result");
return result;
}) as ReferenceHttpBinding["execute"];
return {
binding: Object.freeze({ execute }) satisfies ReferenceHttpBinding,
calls,
};
}
describe("reference HTTP operation gateway", () => {
it("delegates exact typed feature inputs to the capability binding", async () => {
const scripted = scriptedBinding([
{ ok: true, value: [resources.first] },
{ ok: true, value: resources.created },
{ ok: true, value: resources.first },
]);
const gateway = createReferenceHttpGateway(scripted.binding);
const signal = new AbortController().signal;
await expect(
gateway.list({ cursor: "next", limit: 20, tags: ["active"] }, { signal }),
).resolves.toEqual({ ok: true, value: [resources.first] });
await expect(
gateway.create({ name: "Created", note: "safe note" }),
).resolves.toEqual({ ok: true, value: resources.created });
await expect(
gateway.get("reference-1", { signal }),
).resolves.toEqual({ ok: true, value: resources.first });
expect(scripted.calls).toEqual([
[
"LIST_REFERENCE_RESOURCES",
{ cursor: "next", limit: 20, tags: ["active"] },
{ signal },
],
[
"CREATE_REFERENCE_RESOURCE",
{ name: "Created", note: "safe note" },
undefined,
],
[
"GET_REFERENCE_RESOURCE",
{ resourceId: "reference-1" },
{ signal },
],
]);
});
it("preserves a capability-normalized failure across the feature gateway", async () => {
const failure = createFailure(
"SCHEMA_MISMATCH",
"GET_REFERENCE_RESOURCE",
0,
);
const scripted = scriptedBinding([{ ok: false, error: failure }]);
const gateway = createReferenceHttpGateway(scripted.binding);
await expect(gateway.get("invalid")).resolves.toEqual({
ok: false,
error: failure,
});
});
});