85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
/**
|
|
* Regression for #3268 (TUI aggregate path, command-controller.ts).
|
|
*
|
|
* Two contracts that the CLI `formatUsageBreakdown` test cannot cover, because
|
|
* the bug lives in the TUI cross-account grouping renderer `renderUsageReports`:
|
|
*
|
|
* 1. Provider-wide `UsageReport.notes` render ONCE above the per-account
|
|
* sections, not once per account/window.
|
|
* 2. Identical per-limit notes from multiple accounts that fall in the same
|
|
* `label|windowId` group are de-duplicated (the `[...new Set(...)]` at the
|
|
* per-group note line). Without the dedup the note is bullet-joined N times.
|
|
*/
|
|
|
|
import { beforeAll, describe, expect, it } from "bun:test";
|
|
import { stripVTControlCharacters } from "node:util";
|
|
import type { UsageReport } from "@oh-my-pi/pi-ai";
|
|
import { renderUsageReports } from "@oh-my-pi/pi-coding-agent/modes/controllers/command-controller";
|
|
import { initTheme, theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
|
|
const HOUR = 3_600_000;
|
|
|
|
beforeAll(async () => {
|
|
await initTheme();
|
|
});
|
|
|
|
function limit(label: string, windowId: string, durationMs: number, frac: number, notes?: string[]) {
|
|
return {
|
|
id: windowId,
|
|
label,
|
|
scope: { provider: "github-copilot", windowId },
|
|
window: { id: windowId, label, durationMs },
|
|
amount: { unit: "percent", usedFraction: frac },
|
|
status: frac >= 0.8 ? "warning" : "ok",
|
|
...(notes ? { notes } : {}),
|
|
} satisfies UsageReport["limits"][number];
|
|
}
|
|
|
|
function report(provider: string, email: string, limits: UsageReport["limits"], notes?: string[]) {
|
|
return {
|
|
provider,
|
|
fetchedAt: Date.now(),
|
|
limits,
|
|
...(notes ? { notes } : {}),
|
|
metadata: { email },
|
|
} satisfies UsageReport;
|
|
}
|
|
|
|
describe("renderUsageReports (#3268 TUI aggregate)", () => {
|
|
it("renders provider-wide UsageReport.notes exactly once for multiple accounts", () => {
|
|
const disclaimer = "OMP-observed spend only; OpenCode usage outside OMP is not included.";
|
|
const reports: UsageReport[] = [
|
|
report(
|
|
"opencode-go",
|
|
"acct-a@example.test",
|
|
[limit("5 Hour limit", "rolling-5h", 5 * HOUR, 0.3)],
|
|
[disclaimer],
|
|
),
|
|
report(
|
|
"opencode-go",
|
|
"acct-b@example.test",
|
|
[limit("5 Hour limit", "rolling-5h", 5 * HOUR, 0.6)],
|
|
[disclaimer],
|
|
),
|
|
];
|
|
const text = stripVTControlCharacters(renderUsageReports(reports, theme, Date.now(), 120));
|
|
const occurrences = text.split(disclaimer).length - 1;
|
|
expect(occurrences).toBe(1);
|
|
});
|
|
|
|
it("deduplicates identical per-limit notes when accounts share one window group", () => {
|
|
// Both accounts report the SAME label+windowId, so their limits land in
|
|
// one aggregate group; both carry an identical per-limit note.
|
|
const note = "Overage requests: 5";
|
|
const reports: UsageReport[] = [
|
|
report("github-copilot", "acct-a@example.test", [limit("Copilot", "monthly", 30 * 24 * HOUR, 0.8, [note])]),
|
|
report("github-copilot", "acct-b@example.test", [limit("Copilot", "monthly", 30 * 24 * HOUR, 0.9, [note])]),
|
|
];
|
|
const text = stripVTControlCharacters(renderUsageReports(reports, theme, Date.now(), 120));
|
|
const occurrences = text.split(note).length - 1;
|
|
// Deduped: appears once on the group note line. Pre-fix `flatMap(...).join`
|
|
// would bullet-join it twice (one per account in the group).
|
|
expect(occurrences).toBe(1);
|
|
});
|
|
});
|