From b6711922ec51b2244a34fa55c030e9d3cc44a874 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 4 Nov 2026 10:40:04 -0600 Subject: [PATCH] test(decisions): keep the deletion fixture reservation outstanding The deletion guard assertion requires an unresolved decision hold. Gate the test provider response until after that assertion so fast settlement cannot remove the precondition. Release the provider and identity gates in finally. Preserve the original409, agent, successful decision and cost assertions. Co-Authored-By: Paperclip --- server/src/__tests__/decision-models.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/server/src/__tests__/decision-models.test.ts b/server/src/__tests__/decision-models.test.ts index af94eec6b61..23676271fde 100644 --- a/server/src/__tests__/decision-models.test.ts +++ b/server/src/__tests__/decision-models.test.ts @@ -415,9 +415,13 @@ describe("company decision service", () => { const f = await fixture(), runId = randomUUID(); await db.insert(heartbeatRuns).values({ id: runId, companyId: f.companyId, agentId: f.agentId, status: "running", invocationSource: "on_demand", responsibleUserId: "alice" }); - let unlock!: () => void, locked!: (pid: number) => void; + let unlock!: () => void, locked!: (pid: number) => void, finishProvider!: () => void; const gate = new Promise(resolve => { unlock = resolve; }); const acquired = new Promise(resolve => { locked = resolve; }); + const providerGate = new Promise(resolve => { finishProvider = resolve; }); + // Keep the admitted reservation held while deletion checks it. A provider + // that already settled may legitimately allow deletion past this guard. + f.provider.mockImplementationOnce(async () => { await providerGate; return structuredClone(outcome); }); const blocker = db.transaction(async tx => { await tx.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, runId)).for("no key update"); const [row] = await tx.execute<{ pid: number }>(sql`select pg_backend_pid() as pid`); @@ -440,10 +444,11 @@ describe("company decision service", () => { }, { timeout: 3000 }); unlock(); await blocker; expect(await deletion).toMatchObject({ status: 409, details: { code: "agent_decision_accounting_pending" } }); + finishProvider(); expect(await pending).toMatchObject({ status: "succeeded" }); expect((await db.select().from(agents).where(eq(agents.id, f.agentId)))[0]).toBeDefined(); expect(await db.select().from(costEvents).where(eq(costEvents.companyId, f.companyId))).toHaveLength(1); - } finally { unlock(); await blocker; await deletion; await pending.catch(() => undefined); } + } finally { unlock(); finishProvider(); await blocker; await deletion; await pending.catch(() => undefined); } }); it("blocks agent deletion while an in-flight or unknown decision retains a budget hold", async () => { const f = await fixture(), runId = randomUUID();