/*
RFC-1327 IDEMP-02 backing test for cloudflare.token.check's `idempotency:
"rerun-safe"` declaration (RFC-1326) — the command is read-only: a second
run against the same stubbed API returns byte-identical outcomes.
- RFC-1326: initial — two-run determinism over stubbed fetch.
- RFC-1326: single Cloudflare permission registry, token preflight, birth provisioning
*/
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import type { KernelCommandInput, KernelRuntimeContext } from "@warpgogol/werkstatt-engine/kernel";
import { CLOUDFLARE_PERMISSIONS } from "@warpgogol/werkstatt-shared/cloudflare/permissions";
import { runCloudflareTokenCheck } from "../cloudflare-token-check.ts";
const ACCOUNT_ID = "a".repeat(32);
const ZONE_ID = "b".repeat(32);
function makeContext(): KernelRuntimeContext {
return {
workspaceRoot: "/tmp",
logger: { info: () => {}, warn: () => {}, error: () => {}, debug: () => {}, success: () => {} },
} as unknown as KernelRuntimeContext;
}
function apiResponse(body: unknown, status = 200): Response {
return new Response(JSON.stringify(body), {
status,
headers: { "Content-Type": "application/json" },
});
}
function stubFetch(missingIds: string[] = []): void {
const missingPaths = new Set(
CLOUDFLARE_PERMISSIONS.filter((p) => missingIds.includes(p.id)).map((p) =>
p.probe!.path.replace("{accountId}", ACCOUNT_ID).replace("{zoneId}", ZONE_ID),
),
);
vi.stubGlobal(
"fetch",
vi.fn(async (url: string | URL | Request) => {
const u = String(url instanceof Request ? url.url : url);
if (u.includes("/user/tokens/verify")) {
return apiResponse({
success: true,
errors: [],
messages: [],
result: { id: "tok-123", status: "active" },
});
}
const path = u.replace("https://api.cloudflare.com/client/v4", "");
if (missingPaths.has(path)) {
return apiResponse(
{ success: false, errors: [{ code: 9109, message: "Permission denied" }], messages: [] },
403,
);
}
return apiResponse({ success: true, errors: [], messages: [], result: [] });
}),
);
}
beforeEach(() => {
process.env.CLOUDFLARE_API_TOKEN = "test-token";
process.env.CLOUDFLARE_ACCOUNT_ID = ACCOUNT_ID;
delete process.env.CLOUDFLARE_ZONE_ID;
});
afterEach(() => {
vi.unstubAllGlobals();
delete process.env.CLOUDFLARE_API_TOKEN;
delete process.env.CLOUDFLARE_ACCOUNT_ID;
delete process.env.CLOUDFLARE_ZONE_ID;
});
describe("cloudflare.token.check rerun safety (RFC-1327)", () => {
test("a second run returns identical outcomes — read-only, no state", async () => {
stubFetch(["account.vectorize.edit"]);
const input = { argv: [], flags: { zone: ZONE_ID } } as unknown as KernelCommandInput;
const first = await runCloudflareTokenCheck(input, makeContext());
const second = await runCloudflareTokenCheck(input, makeContext());
expect(second.exitCode).toBe(first.exitCode);
expect(second.summary).toBe(first.summary);
expect(JSON.stringify(second.data)).toBe(JSON.stringify(first.data));
});
});