Files
clean-architecture-frontend…/tests/unit/external-contract-runtime.test.ts
T
2026-08-01 19:39:59 +09:00

86 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
ContractContributionError,
composeContractContributions,
type InstalledContractContribution,
} from "../../src/contracts/external-contract-runtime.ts";
import { REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION } from "../../src/features/reference-feature/contracts/reference-feature-contract-contribution.ts";
function contribution(
contributionId: string,
http: InstalledContractContribution["http"],
): InstalledContractContribution & Readonly<{ contributionId: string }> {
return Object.freeze({
...REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION,
contributionId,
http: Object.freeze([...http]),
});
}
function captureContributionError(operation: () => unknown): ContractContributionError {
try {
operation();
} catch (error) {
expect(error).toBeInstanceOf(ContractContributionError);
return error as ContractContributionError;
}
throw new Error("Expected contract composition to fail.");
}
describe("external contract contribution composition", () => {
it("allows one feature to install multiple uniquely identified contributions", () => {
const operations = REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION.http;
const composed = composeContractContributions([
contribution("reference-read-contracts", operations.slice(0, 2)),
contribution("reference-command-contracts", operations.slice(2)),
]);
expect(composed.contributions).toHaveLength(2);
expect(composed.httpByOperationId.size).toBe(3);
});
it("rejects duplicate contribution identities even across different feature entries", () => {
const first = contribution(
"reference-contracts",
REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION.http.slice(0, 1),
);
const second = contribution(
"reference-contracts",
REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION.http.slice(1),
);
const error = captureContributionError(() =>
composeContractContributions([first, second]),
);
expect(error.reason).toContain("duplicate contributionId");
});
it("maps malformed source values to the closed composition error", () => {
const malformed = {
...contribution("malformed-source", []),
source: null,
} as unknown as InstalledContractContribution;
const error = captureContributionError(() =>
composeContractContributions([malformed]),
);
expect(error.reason).toContain("source");
});
it("rejects method and body vocabulary outside the runtime protocol", () => {
const installed = REFERENCE_FEATURE_TEMPLATE_CONTRIBUTION.http[0]!;
const malformedOperation = {
...installed,
contract: { ...installed.contract, method: "TRACE" },
} as unknown as InstalledContractContribution["http"][number];
const error = captureContributionError(() =>
composeContractContributions([
contribution("invalid-http-vocabulary", [malformedOperation]),
]),
);
expect(error.reason).toContain("method");
});
});