From a30e901526ffbd1f04a959dbc11d35aa1855e0c9 Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Sat, 24 Oct 2026 23:27:36 -0400 Subject: [PATCH] test: verify published content estimate command contracts --- __tests__/fixtures/published-guide/README.md | 10 ++++++---- .../fixtures/published-guide/intercept.cjs | 4 +++- __tests__/publishedCommands.test.ts | 20 +++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/__tests__/fixtures/published-guide/README.md b/__tests__/fixtures/published-guide/README.md index 2daca5c..480630e 100644 --- a/__tests__/fixtures/published-guide/README.md +++ b/__tests__/fixtures/published-guide/README.md @@ -1,9 +1,11 @@ # Published command fixture `cli.mdx` is the complete, unmodified Marketing guide at the immutable source in -`provenance.json`. The test extracts its email/song examples and chat-link flag, +`provenance.json`. The test extracts its email/song/cost-estimate examples and chat-link flag, then runs the built CLI with synthetic credentials and intercepted native fetch. -No endpoint is contacted. Request records omit headers. +No endpoint is contacted. Request records preserve query strings and omit headers. +Estimate checks require GET without a body and exact default/explicit query flags; +they do not verify pricing or invoke content creation. Run `pnpm build` then `pnpm exec vitest run __tests__/publishedCommands.test.ts`. Documentation owners can set `RECOUP_CLI_REFERENCE_PATH` to an absolute candidate @@ -12,5 +14,5 @@ Markdown path to run the same parser/request assertions before publishing. When these examples intentionally change, copy the complete guide from its owning commit, update provenance and SHA256, and review the expected requests together. The default check protects this pinned guide; it does not monitor future live docs -or establish installed npm package behavior. Coverage is limited to email/song -examples and the retired email flag, not every CLI command or authorization rule. +or establish installed npm package behavior. Coverage is limited to email/song/ +cost-estimate examples and the retired email flag, not every CLI command or authorization rule. diff --git a/__tests__/fixtures/published-guide/intercept.cjs b/__tests__/fixtures/published-guide/intercept.cjs index 5573ab8..b2775f0 100644 --- a/__tests__/fixtures/published-guide/intercept.cjs +++ b/__tests__/fixtures/published-guide/intercept.cjs @@ -7,7 +7,7 @@ globalThis.fetch = async (input, options = {}) => { } appendFileSync(process.env.CLI_FIXTURE_REQUEST_LOG, JSON.stringify({ method: options.method, - path: url.pathname, + path: url.pathname + url.search, body: options.body ? JSON.parse(options.body) : null, }) + "\n"); return new Response(JSON.stringify({ @@ -15,5 +15,7 @@ globalThis.fetch = async (input, options = {}) => { response: "Synthetic analysis response", elapsed_seconds: 0, presets: [], + per_video_estimate_usd: 1, + total_estimate_usd: 2, }), { status: 200, headers: { "Content-Type": "application/json" } }); }; diff --git a/__tests__/publishedCommands.test.ts b/__tests__/publishedCommands.test.ts index ff5f1e4..ac07618 100644 --- a/__tests__/publishedCommands.test.ts +++ b/__tests__/publishedCommands.test.ts @@ -106,4 +106,24 @@ describe("published command contract (built CLI, intercepted requests)", () => { expect(result.requests).toEqual([expected[index]]); }); }); + + it("runs every cost estimate example as GET with the documented query flags", () => { + const commands = examples("Estimate cost"); + expect(commands).toHaveLength(2); + const expectedQueries = [ + { lipsync: "false", batch: "1", compare: "false" }, + { lipsync: "true", batch: "2", compare: "true" }, + ]; + commands.forEach((command, index) => { + const result = run(command); + expect(result.status).toBe(0); + expect(result.requests).toHaveLength(1); + const request = result.requests[0]; + expect(request).toMatchObject({ method: "GET", body: null }); + const url = new URL(request.path, "https://cli-fixture.invalid"); + expect(url.pathname).toBe("/api/content/estimate"); + expect([...url.searchParams]).toHaveLength(3); + expect(Object.fromEntries(url.searchParams)).toEqual(expectedQueries[index]); + }); + }); });