Files
tech-log-frontend/tests/features/reference-feature/reference-contract.test.ts
T

149 lines
4.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import {
mapReferenceOperation,
toReferenceView,
} from "../../../src/features/reference-feature/contracts/reference-mapper.ts";
import {
validateReferencePayload,
validateReferenceRequest,
} from "../../../src/features/reference-feature/contracts/reference-schemas.ts";
import {
REFERENCE_FEATURE_CONTRACT,
REFERENCE_FEATURE_ID,
REFERENCE_RESOURCE_INVALIDATION_TOPIC,
} from "../../../src/features/reference-feature/contracts/reference-feature-contract.ts";
import type { ReferenceFeatureInput } from "../../../src/features/reference-feature/application/reference-feature-api.ts";
import { createTestApplication } from "../../helpers/create-test-application.ts";
import { createReferenceFeatureInstalledInput } from "../../../src/features/reference-feature/adapters/create-reference-feature-input.ts";
describe("reference feature boundary contracts", () => {
it("propagates uncertain command effect certainty into the application failure", async () => {
const execute = vi.fn(async () => ({
kind: "CONTRACT_VIOLATION" as const,
violation: {
kind: "SUCCESS_SCHEMA_INVALID" as const,
operation: "VALIDATION" as const,
},
effect: "MAYBE_APPLIED" as const,
}));
const installed = createReferenceFeatureInstalledInput({
contractOperations: { execute },
});
await expect(
installed.input.createResource({ name: "uncertain" }),
).resolves.toMatchObject({
ok: false,
error: {
effect: "MAYBE_APPLIED",
retryable: false,
action: "contact-support",
},
});
});
it("rejects unknown search and malformed DTO before mapping", () => {
expect(
validateReferencePayload("ReferenceResourceListPayload", [
{ id: "unsafe", name: 42 },
]),
).toMatchObject({ success: false });
expect(
mapReferenceOperation("LIST_REFERENCE_RESOURCES", [
{ id: "unsafe", name: 42 },
]),
).toMatchObject({ ok: false });
});
it("normalizes request input and maps only owned domain fields", () => {
expect(
validateReferenceRequest("CreateReferenceResourceCommand", {
name: " Example ",
}),
).toMatchObject({ success: true, data: { name: "Example" } });
const model = mapReferenceOperation("CREATE_REFERENCE_RESOURCE", {
id: "reference-1",
name: "Example",
createdAt: "2026-07-26T00:00:00.000Z",
});
if (!model.ok || !("id" in model.value)) {
throw new Error("expected one model");
}
expect(toReferenceView(model.value)).toEqual({
resourceId: "reference-1",
title: "Example",
createdAt: "2026-07-26T00:00:00.000Z",
});
});
it("owns the retained API operation fixture contract", () => {
expect(Object.keys(REFERENCE_FEATURE_CONTRACT.apiOperations)).toEqual([
"LIST_REFERENCE_RESOURCES",
"CREATE_REFERENCE_RESOURCE",
"GET_REFERENCE_RESOURCE",
]);
expect(
REFERENCE_FEATURE_CONTRACT.apiOperations.GET_REFERENCE_RESOURCE,
).toMatchObject({
pathSchema: "ReferenceResourceParams",
pathParameterNames: ["resourceId"],
providerId: "PRIMARY_API",
authProfileId: "REFERENCE_EXTERNAL_BEARER",
csrfProfileId: "NO_CSRF_BEARER",
});
});
it("contributes an identity-based invalidation graph and an explicit wire version", () => {
expect(REFERENCE_FEATURE_CONTRACT.invalidation).toEqual({
topics: [REFERENCE_RESOURCE_INVALIDATION_TOPIC],
namespaces: [
{ namespaceId: "reference-resource", namespaceVersion: 1 },
],
edges: [
{
topicId: REFERENCE_RESOURCE_INVALIDATION_TOPIC,
namespace: {
namespaceId: "reference-resource",
namespaceVersion: 1,
},
},
],
});
expect(REFERENCE_FEATURE_CONTRACT.topicVersions).toEqual([
{
topicId: REFERENCE_RESOURCE_INVALIDATION_TOPIC,
topicVersion: 1,
},
]);
});
it("returns the installed input through the typed application registry", () => {
const featureInput = {
listResources: async () => ({ ok: true as const, value: [] }),
createResource: async ({ name }) => ({
ok: true as const,
value: {
resourceId: "created",
title: name,
createdAt: null,
},
}),
getResource: async (resourceId) => ({
ok: true as const,
value: {
resourceId,
title: "Reference",
createdAt: null,
},
}),
} satisfies ReferenceFeatureInput;
const application = createTestApplication({
featureInputs: { [REFERENCE_FEATURE_ID]: featureInput },
});
expect(application.features.has(REFERENCE_FEATURE_ID)).toBe(true);
expect(application.features.get(REFERENCE_FEATURE_ID)).toBe(featureInput);
});
});