import test from "node:test"; import assert from "node:assert/strict"; import { mkdir, writeFile } from "node:fs/promises"; import path from "node:path"; import { callPost, holdPublishQueue, setupOpsCorpus } from "../_testCorpus"; // Run with: // pnpm -C editor exec tsx --test "app/api/ops/deploy-hub/route.test.ts" // // The hub's deploy path refuses BEFORE a job exists, which is what lets a // runbook's `pnpm ops deploy-hub --wait` fail fast instead of queueing a deploy // that can only fail. Moved from e2e/ops-api.spec.ts (release 19, A2b), with // the publish queue held as it was there. const corpus = await setupOpsCorpus("title-filter-channel"); const deployHub = (await import("./route")).POST; const buildHub = (await import("../build-hub/route")).POST; await holdPublishQueue(); test.after(() => corpus.cleanup()); test("deploy-hub refuses no project, the homepage's project, and a bundle that is not the hub", async () => { // The fixture has no homepage.json at all: no project. const none = await callPost(deployHub, {}); assert.equal(none.status, 400); assert.equal( none.body.error, "The hub has no Cloudflare Pages project configured — set it on /sites under Hub.", ); // The homepage's project is refused by name: a hub deployed there would // replace the software's own site. const dir = path.join(corpus.transcripts, "sites", "_homepage"); await mkdir(dir, { recursive: true }); const hubFile = path.join(dir, "homepage.json"); await writeFile(hubFile, JSON.stringify({ cloudflareProject: "archilyzer" })); const homepages = await callPost(deployHub, {}); assert.equal(homepages.status, 400); assert.match(String(homepages.body.error), /"archilyzer", which is the Archilyzer homepage's/); // A real project, but no hub build: the hub's bundle is the corpus's own // .export-builds/_hub, stamped built.json. await writeFile(hubFile, JSON.stringify({ cloudflareProject: "archilyzer-hub" })); const unbuilt = await callPost(deployHub, { preview: "hub-check" }); assert.equal(unbuilt.status, 400); assert.match( String(unbuilt.body.error), /^no build of _hub in .*\.export-builds\/_hub — archilyzer publish hub$/, ); // build-hub: a preview without a deploy is a mistake, not a build. const previewOnly = await callPost(buildHub, { preview: "hub-check" }); assert.equal(previewOnly.status, 400); assert.match(String(previewOnly.body.error), /"preview" needs "deploy": true/); assert.deepEqual(await corpus.listJobIds(), []); });