From 857c016592d89e360859435e0e272e87989a5852 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 10:45:50 +0000 Subject: [PATCH] test(rest): fail the late-cancel control loudly when its wait for the worker's results write runs out The all-failed late-cancel control waited up to 400 x 5 ms for the worker's final patch (the only write of `results`) and then asserted the job row. If the wait ran out, the cancel route's own `cancelled` write and the progress flush could pass those checks without the final patch ever landing. Assert the results read reached 3 rows after the wait. Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_016WV4cyGcBtnptfcfKE14ZS --- packages/rest/src/import-job-integration.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/rest/src/import-job-integration.test.ts b/packages/rest/src/import-job-integration.test.ts index ee193b1354e..a11f0931a75 100644 --- a/packages/rest/src/import-job-integration.test.ts +++ b/packages/rest/src/import-job-integration.test.ts @@ -618,11 +618,16 @@ describe('async import job — a job whose every row failed ends failed', () => await waitForTerminal(slowCtx.progress, jobId); // The cancel route writes `cancelled` first; wait until the worker's own // final patch has landed (it is the only write of `results`), then read the row. + let reported = 0; for (let i = 0; i < 400; i++) { const r = await callJob(slowCtx.results, jobId); - if ((r._json?.results ?? []).length === 3) break; + reported = (r._json?.results ?? []).length; + if (reported === 3) break; await new Promise((rr) => setTimeout(rr, 5)); } + // An exhausted wait must fail here: without the worker's final patch, the + // cancel route's write and the progress flush alone could pass the checks below. + expect(reported).toBe(3); const after = await callJob(slowCtx.progress, jobId); expect(after._json.status).toBe('cancelled'); expect(after._json).toMatchObject({ processed: 3, created: 0, updated: 0, skipped: 0, errors: 3 });