From ceab389a4183dc027a63cb7ab22eb5bdd26deca6 Mon Sep 17 00:00:00 2001 From: "Aaron K. Clark" Date: Tue, 19 May 2026 11:36:42 -0500 Subject: [PATCH] test(openapi): pin Idempotency-Replay on every single-create POST 201 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 16-PR #245 sweep added the \`Idempotency-Replay\` response-header declaration on every \`/v1/*\` single-create POST 201. The existing regression-pin only asserted /v1/customer — a future contributor reverting any of the other 15 entities' declarations would not trip CI. Convert the single-target assertion into a sweep-wide loop over all 16 target paths. Same shape as the existing "single-create POSTs document the Idempotency-Key header" test above it, just for the response side. No new test count (the assertion is in one \`test()\` block iterating the array). 761 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/api/openapi.test.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/api/openapi.test.js b/tests/api/openapi.test.js index f9ccda8..baa1f70 100644 --- a/tests/api/openapi.test.js +++ b/tests/api/openapi.test.js @@ -166,18 +166,32 @@ describe('OpenAPI spec', () => { expect(replay.schema.enum).toContain('true'); }); - test('single-create POST /v1/customer declares Idempotency-Replay on the 201', async () => { + test('every single-create POST declares Idempotency-Replay on the 201', async () => { // Single-create POSTs flow through the same idempotency // middleware as the bulk endpoints. Without the response-header // declaration on the 201, SDKs generated from the spec can't // surface the replay flag for non-bulk creates. + // + // #245 sweep (#246–#288) ensured the declaration on every + // entity's single-create POST. Pin all 16 here so a future + // regression on any one of them fails CI — not just on + // /v1/customer. const res = await request(app).get('/openapi.json'); - const customer = res.body.paths['/v1/customer']; - const r201 = customer.post.responses['201']; - expect(r201.headers, 'POST /v1/customer 201 should declare headers').toBeDefined(); - const replay = r201.headers['Idempotency-Replay']; - expect(replay, 'Idempotency-Replay should appear on POST /v1/customer 201').toBeDefined(); - expect(replay.schema.enum).toContain('true'); + const targets = [ + '/v1/customer', '/v1/timeentry', '/v1/worker', '/v1/billingtype', + '/v1/inventoryitem', '/v1/company', '/v1/job', '/v1/invoice', + '/v1/customerpayment', '/v1/invoicejob', '/v1/productentry', + '/v1/versioninfo', '/v1/purchaseordervendor', + '/v1/purchaseorderheader', '/v1/purchaseorderline', + '/v1/inventorytransaction', + ]; + for (const path of targets) { + const r201 = res.body.paths[path].post.responses['201']; + expect(r201.headers, `${path} POST 201 should declare headers`).toBeDefined(); + const replay = r201.headers['Idempotency-Replay']; + expect(replay, `Idempotency-Replay should appear on ${path} POST 201`).toBeDefined(); + expect(replay.schema.enum, `${path} replay schema should enum 'true'`).toContain('true'); + } }); test('/metrics endpoint is documented', async () => {