/*
RFC-0292: determinism + shape tests for the Fleet Agent Catalog builder.
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-0292: initial builder tests.
*/
import { test, expect } from "vitest";
import {
buildFleetAgentCatalog,
computeFleetCatalogContentHash,
FLEET_AGENT_CATALOG_SCHEMA,
} from "../fleet-catalog.ts";
const sampleDoc = {
surfaceVersion: "1.0.0",
site: "warpgogol-com",
baseUrl: "https://warpgogol.com",
contentHash: "abc123",
knowledge: [
{ domain: "offer", url: "/api/agent/v1/offer.json", schema: "gogol.agent.knowledge/offer@1" },
],
actions: [
{
id: "lead.submit",
url: "/api/agent/v1/actions/lead.submit",
title: { de: "Anfrage" },
inputSchemaRef: "#/x",
entitlement: "agent.actions",
},
],
interfaces: {
llms: "/llms.txt",
twins: { pattern: "/**.md" },
openapi: "/.well-known/agent.openapi.json",
mcp: { url: "/api/agent/mcp", protocolVersion: "1" },
},
proof: null,
};
test("buildFleetAgentCatalog: missing doc ⇒ enabled: false entry", () => {
const catalog = buildFleetAgentCatalog([{ site: "alpha", doc: null }]);
expect(catalog.sites).toHaveLength(1);
expect(catalog.sites[0]!.enabled).toBe(false);
expect(catalog.sites[0]!.signed).toBe(false);
expect(catalog.sites[0]!.knowledgeDomains).toEqual([]);
expect(catalog.sites[0]!.actions).toEqual([]);
expect(catalog.sites[0]!.baseUrl).toBe("");
});
test("buildFleetAgentCatalog: populated doc ⇒ enabled: true with extracted fields", () => {
const catalog = buildFleetAgentCatalog([{ site: "alpha", doc: sampleDoc }]);
const entry = catalog.sites[0]!;
expect(entry.enabled).toBe(true);
expect(entry.signed).toBe(false);
expect(entry.baseUrl).toBe("https://warpgogol.com");
expect(entry.surfaceVersion).toBe("1.0.0");
expect(entry.contentHash).toBe("abc123");
expect(entry.knowledgeDomains).toEqual(["offer"]);
expect(entry.actions).toEqual(["lead.submit"]);
expect(entry.interfaces).toEqual({ openapi: true, mcp: true });
});
test("buildFleetAgentCatalog: proof present ⇒ signed: true", () => {
const catalog = buildFleetAgentCatalog([
{
site: "alpha",
doc: {
...sampleDoc,
proof: { type: "Ed25519Signature2020", verificationMethod: "k", proofValue: "v" },
},
},
]);
expect(catalog.sites[0]!.signed).toBe(true);
});
test("buildFleetAgentCatalog: sorts sites by site id", () => {
const catalog = buildFleetAgentCatalog([
{ site: "zeta", doc: null },
{ site: "alpha", doc: null },
{ site: "mid", doc: null },
]);
expect(catalog.sites.map((s) => s.site)).toEqual(["alpha", "mid", "zeta"]);
});
test("buildFleetAgentCatalog: is deterministic across repeated calls (byte-identical)", () => {
const input = [
{ site: "alpha", doc: sampleDoc },
{ site: "beta", doc: null },
];
const a = buildFleetAgentCatalog(input);
const b = buildFleetAgentCatalog(input);
expect(JSON.stringify(a)).toBe(JSON.stringify(b));
expect(a.contentHash).toBe(b.contentHash);
});
test("buildFleetAgentCatalog: empty input ⇒ valid catalog with empty sites", () => {
const catalog = buildFleetAgentCatalog([]);
expect(catalog.sites).toEqual([]);
expect(catalog.schema).toBe(FLEET_AGENT_CATALOG_SCHEMA);
expect(catalog.contentHash).toMatch(/^[0-9a-f]{64}$/);
});
test("buildFleetAgentCatalog: contentHash is a 64-char lowercase hex sha256", () => {
const catalog = buildFleetAgentCatalog([{ site: "alpha", doc: sampleDoc }]);
expect(catalog.contentHash).toMatch(/^[0-9a-f]{64}$/);
});
test("computeFleetCatalogContentHash: matches the builder's hash for the same sites", () => {
const catalog = buildFleetAgentCatalog([
{ site: "alpha", doc: sampleDoc },
{ site: "beta", doc: null },
]);
const recomputed = computeFleetCatalogContentHash(catalog.sites);
expect(recomputed).toBe(catalog.contentHash);
});
test("buildFleetAgentCatalog: input array order does not affect output (sorted)", () => {
const a = buildFleetAgentCatalog([
{ site: "alpha", doc: sampleDoc },
{ site: "beta", doc: null },
]);
const b = buildFleetAgentCatalog([
{ site: "beta", doc: null },
{ site: "alpha", doc: sampleDoc },
]);
expect(JSON.stringify(a)).toBe(JSON.stringify(b));
});