test(ui): assert what collaborators are called with, not merely that they were

A bare toHaveBeenCalled() passes no matter what the caller passed, so the CSV
export could serialize the wrong rows, write the wrong content type, and name
the file wrong while its test stayed green.

Strengthens the load-bearing cases in three files onto the arguments that carry
the behaviour: the rows handed to the CSV serializer, the blob content type, the
anchor that gets attached and cleaned up, and the specific message each
validation failure shows the user. Two of the discount and margin tests
previously asserted the same bare call for different validation failures, so
neither could tell the two apart.

Each rewrite was proven by mutating the source it covers and confirming the test
goes red where the bare assertion stayed green.
This commit is contained in:
Yuneng Jiang 2026-08-15 02:31:08 -07:00 committed by yuneng-jiang
parent 0d3dd8b4e1
commit 6db82c0d15
3 changed files with 27 additions and 13 deletions

View file

@ -84,7 +84,9 @@ describe("useDiscountConfig", () => {
});
expect(success!).toBe(false);
expect(NotificationsManager.fromBackend).toHaveBeenCalled();
expect(NotificationsManager.fromBackend).toHaveBeenCalledWith(
"Please select a provider and enter discount percentage",
);
});
it("should return false and notify when no discount is provided", async () => {
@ -96,7 +98,9 @@ describe("useDiscountConfig", () => {
});
expect(success!).toBe(false);
expect(NotificationsManager.fromBackend).toHaveBeenCalled();
expect(NotificationsManager.fromBackend).toHaveBeenCalledWith(
"Please select a provider and enter discount percentage",
);
});
it("should return false and notify when the discount exceeds 100", async () => {
@ -152,7 +156,7 @@ describe("useDiscountConfig", () => {
});
expect(success!).toBe(true);
expect(NotificationsManager.success).toHaveBeenCalled();
expect(NotificationsManager.success).toHaveBeenCalledWith("Discount configuration updated successfully");
});
});

View file

@ -89,7 +89,7 @@ describe("useMarginConfig", () => {
});
expect(success!).toBe(false);
expect(NotificationsManager.fromBackend).toHaveBeenCalled();
expect(NotificationsManager.fromBackend).toHaveBeenCalledWith("Please select a provider");
});
it("should return false and notify when percentage is out of range", async () => {
@ -160,7 +160,7 @@ describe("useMarginConfig", () => {
});
expect(success!).toBe(true);
expect(NotificationsManager.success).toHaveBeenCalled();
expect(NotificationsManager.success).toHaveBeenCalledWith("Margin configuration updated successfully");
});
it("should save a fixed amount margin and return true for a valid new provider", async () => {
@ -189,7 +189,7 @@ describe("useMarginConfig", () => {
});
expect(success!).toBe(true);
expect(NotificationsManager.success).toHaveBeenCalled();
expect(NotificationsManager.success).toHaveBeenCalledWith("Margin configuration updated successfully");
});
it("should accept the global provider without provider_map lookup", async () => {

View file

@ -1964,11 +1964,18 @@ describe("EntityUsageExport utils", () => {
handleExportCSV(mockSpendData, "daily", "Team", "team", mockTeamAliasMap);
expect(Papa.unparse).toHaveBeenCalled();
expect(createObjectURLSpy).toHaveBeenCalled();
const unparsedRows = vi.mocked(Papa.unparse).mock.calls[0][0] as Record<string, unknown>[];
expect(unparsedRows).toHaveLength(3);
const day1Team1 = unparsedRows.find((r) => r["Date"] === "2025-01-01" && r["Team ID"] === "team-1");
expect(day1Team1?.["Cache Read Input Tokens"]).toBe(50);
const exportedBlob = createObjectURLSpy.mock.calls[0][0] as Blob;
expect(exportedBlob.type).toBe("text/csv;charset=utf-8;");
expect(createElementSpy).toHaveBeenCalledWith("a");
expect(appendChildSpy).toHaveBeenCalled();
expect(removeChildSpy).toHaveBeenCalled();
const attached = appendChildSpy.mock.calls[0][0] as HTMLAnchorElement;
expect(attached.download).toMatch(/^team_usage_daily_.*\.csv$/);
expect(removeChildSpy).toHaveBeenCalledWith(attached);
});
it("should generate correct filename", () => {
@ -2028,10 +2035,13 @@ describe("EntityUsageExport utils", () => {
handleExportJSON(mockSpendData, "daily", "Team", "team", mockDateRange, [], mockTeamAliasMap);
expect(createObjectURLSpy).toHaveBeenCalled();
const exportedBlob = createObjectURLSpy.mock.calls[0][0] as Blob;
expect(exportedBlob.type).toBe("application/json");
expect(createElementSpy).toHaveBeenCalledWith("a");
expect(appendChildSpy).toHaveBeenCalled();
expect(removeChildSpy).toHaveBeenCalled();
const attached = appendChildSpy.mock.calls[0][0] as HTMLAnchorElement;
expect(attached.download).toMatch(/^team_usage_daily_.*\.json$/);
expect(removeChildSpy).toHaveBeenCalledWith(attached);
});
it("should generate correct filename", () => {