Skip to content

Commit becb986

Browse files
committed
test: cover budget overview with a deleted agent scope
Deletes the agent a policy points at, then reads the overview. Fails against the unfixed resolver, which threw notFound and took out the whole view rather than degrading the one affected row.
1 parent 3b1b9e1 commit becb986

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

server/src/__tests__/budgets-service.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { randomUUID } from "node:crypto";
2+
import { eq } from "drizzle-orm";
23
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
34
import {
45
agents,
@@ -637,4 +638,39 @@ describeEmbeddedPostgres("budgetService release gate enforcement", () => {
637638
});
638639
expect(overviewAfterResume.activeIncidents).toHaveLength(0);
639640
});
641+
642+
it("keeps the overview readable after the agent a policy points at is deleted", async () => {
643+
const { companyId, agentId } = await createBudgetFixture();
644+
const service = budgetService(db, { cancelWorkForScope: vi.fn().mockResolvedValue(undefined) });
645+
await db.insert(budgetPolicies).values({
646+
companyId,
647+
scopeType: "agent",
648+
scopeId: agentId,
649+
metric: "billed_cents",
650+
windowKind: "lifetime",
651+
amount: 500,
652+
warnPercent: 80,
653+
hardStopEnabled: true,
654+
notifyEnabled: false,
655+
isActive: true,
656+
});
657+
658+
// scopeId is a soft reference with no foreign key, so deleting the agent
659+
// leaves the policy pointing at a row that is gone.
660+
await db.delete(agents).where(eq(agents.id, agentId));
661+
662+
// Previously this threw notFound. The overview resolves every scope in one
663+
// pass, so one deleted agent took out the whole view instead of one row.
664+
const overview = await service.overview(companyId);
665+
666+
expect(overview.policies).toHaveLength(1);
667+
expect(overview.policies[0]).toMatchObject({
668+
scopeType: "agent",
669+
scopeId: agentId,
670+
amount: 500,
671+
paused: false,
672+
});
673+
expect(overview.policies[0]?.scopeName).toContain("deleted");
674+
});
675+
640676
});

0 commit comments

Comments
 (0)