Files
diegosouzapw--omniroute/tests/unit/quota-share-bugfixes-v388.test.ts
2026-07-13 13:39:12 +08:00

218 lines
9.4 KiB
TypeScript

/**
* tests/unit/quota-share-bugfixes-v388.test.ts
*
* Source-level assertions for the v3.8.8 Quota Share bug fixes reported from
* Local-VPS testing. Pattern mirrors quota-share-layout-v2.test.ts (source-scan
* + i18n parity) — no DOM setup required.
*
* B1 pools created "in a group" persisted with the "all" sentinel → hidden,
* uneditable, undeletable. Fix: wizard never persists "all"; page shows an
* "Ungrouped" recovery bucket for orphan pools.
* B3 one-connection-per-pool made explicit (member set + "already used" pool name).
* B4 delete-group control wired in the UI (backend already existed).
* B5a native Anthropic POST /v1/messages surfaced in the endpoints card.
* B5b endpoints card collapse/minimize toggle.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
const QS = "src/app/(dashboard)/dashboard/costs/quota-share";
const pageSrc = readFileSync(join(ROOT, QS, "QuotaSharePageClient.tsx"), "utf8");
const wizardSrc = readFileSync(join(ROOT, QS, "components/PoolWizard.tsx"), "utf8");
const endpointsSrc = readFileSync(join(ROOT, QS, "components/QuotaEndpointsCard.tsx"), "utf8");
const en = JSON.parse(readFileSync(join(ROOT, "src/i18n/messages/en.json"), "utf8")) as {
quotaShare: Record<string, string>;
};
const pt = JSON.parse(readFileSync(join(ROOT, "src/i18n/messages/pt-BR.json"), "utf8")) as {
quotaShare: Record<string, string>;
};
// ── B1 — wizard never persists the "all" sentinel as a real group ────────────
test("B1: PoolWizard resolves groupId away from 'all' before persisting", () => {
assert.ok(
wizardSrc.includes("const resolvedGroupId ="),
"wizard must compute a resolvedGroupId before saving"
);
assert.ok(
/resolvedGroupId\s*=[\s\S]*?groupId\s*!==\s*"all"/.test(wizardSrc),
"resolvedGroupId must guard against the 'all' sentinel"
);
// Both the create POST body and the edit PATCH body must send the resolved id,
// never the raw groupId state.
const groupIdSends = wizardSrc.match(/groupId:\s*resolvedGroupId/g) ?? [];
assert.ok(
groupIdSends.length >= 2,
`both create + edit bodies must send groupId: resolvedGroupId (found ${groupIdSends.length})`
);
assert.ok(
!/\n\s*groupId,\n/.test(wizardSrc),
"wizard must not send the bare groupId shorthand in a request body"
);
});
// ── B1 — page surfaces orphan pools so stuck pools stay actionable ───────────
test("B1: QuotaSharePageClient renders an Ungrouped bucket for orphan pools", () => {
assert.ok(pageSrc.includes("const orphanPools = useMemo"), "must compute orphanPools");
assert.ok(
pageSrc.includes('t("ungroupedTitle")'),
"must render the ungrouped section heading"
);
// Orphan pools must reuse the same card with edit/remove wiring.
const orphanBlock = pageSrc.slice(pageSrc.indexOf('t("ungroupedTitle")'));
assert.ok(
orphanBlock.includes("orphanPools.map") &&
orphanBlock.includes("onEdit") &&
orphanBlock.includes("onRemove"),
"orphan pools must render PoolCard with edit + remove controls"
);
});
// ── B3 — one connection per pool, made explicit ──────────────────────────────
test("B3: connection→pool membership is explicit (all members, not just primary)", () => {
assert.ok(
pageSrc.includes("const connectionPoolName = useMemo"),
"page must build a connectionId→pool-name map"
);
assert.ok(
pageSrc.includes("connectionPoolName={connectionPoolName}"),
"page must pass connectionPoolName into the wizard"
);
// existingPoolConnectionIds must include every member connection, not only the primary.
assert.ok(
pageSrc.includes("flatMap((p) => p.connectionIds ?? [p.connectionId])"),
"existingPoolConnectionIds must span all member connections"
);
assert.ok(
wizardSrc.includes("connectionPoolName[c.id]"),
"wizard must show which pool an already-used connection belongs to"
);
});
// ── B4 — delete-group control wired in the UI ────────────────────────────────
test("B4: QuotaSharePageClient wires a delete-group control (protecting the seed)", () => {
assert.ok(pageSrc.includes("const handleDeleteGroup = useCallback"), "must define handleDeleteGroup");
assert.ok(
pageSrc.includes('method: "DELETE" }') && pageSrc.includes("/api/quota/groups/"),
"handleDeleteGroup must DELETE the group via the API"
);
assert.ok(
pageSrc.includes('res.status === 409') && pageSrc.includes('t("deleteGroupHasPools")'),
"must handle the 409 (group still has pools) response"
);
assert.ok(
pageSrc.includes('selectedGroupId !== "all" && selectedGroupId !== "group-demo"'),
"delete control must be hidden for 'all' and the protected seed group"
);
});
// ── B5a — native Anthropic endpoint ──────────────────────────────────────────
test("B5a: endpoints card surfaces POST /v1/messages for Anthropic providers", () => {
assert.ok(endpointsSrc.includes("const hasAnthropic"), "must detect Anthropic providers in scope");
assert.ok(endpointsSrc.includes("POST /v1/messages"), "must show the native Anthropic endpoint");
assert.ok(
/isAnthropicProvider[\s\S]*?startsWith\("claude"\)/.test(endpointsSrc),
"Anthropic detection must cover claude* providers"
);
});
// ── B5b — collapse toggle ────────────────────────────────────────────────────
test("B5b: endpoints card has a collapse/expand toggle", () => {
assert.ok(endpointsSrc.includes("const [collapsed, setCollapsed]"), "must hold a collapsed state");
assert.ok(
endpointsSrc.includes("{!collapsed && ("),
"the card body must be hidden while collapsed"
);
assert.ok(
endpointsSrc.includes('t("endpointsCollapse")') && endpointsSrc.includes('t("endpointsExpand")'),
"toggle must use collapse/expand labels"
);
});
// ── B5 default view shows REAL combos, not model-a/b/c placeholders ──────────
test("B5: endpoints default view uses real minted qtSd combos (not placeholders)", () => {
assert.ok(
endpointsSrc.includes('fetch("/api/combos")'),
"card must fetch real combos for the default view"
);
assert.ok(
endpointsSrc.includes("isQuotaModelName") && endpointsSrc.includes("parseQuotaModelName"),
"must filter+parse real qtSd combo names"
);
assert.ok(
endpointsSrc.includes("const realByGroup") &&
endpointsSrc.includes("realByGroup ?? defaultByGroup") &&
endpointsSrc.includes("viewByGroup.map"),
"default view must prefer real combos (realByGroup) over the placeholder map"
);
});
// ── Responses API endpoint in the card ──────────────────────────────────────
test("endpoints card surfaces POST /v1/responses for codex/github providers", () => {
assert.ok(endpointsSrc.includes("const hasResponses"), "must detect Responses providers in scope");
assert.ok(endpointsSrc.includes("POST /v1/responses"), "must show the Responses endpoint");
assert.ok(
/isResponsesProvider[\s\S]*?"codex"[\s\S]*?"github"/.test(endpointsSrc),
"Responses detection must cover canonical codex + github slugs"
);
});
// ── planRegistry defaults for no-balance-API providers ───────────────────────
test("planRegistry seeds xiaomi-mimo (4.1B lite cap) and kimi-coding for manual fair-share", async () => {
const { getKnownPlan } = await import("../../src/lib/quota/planRegistry.ts");
const xiaomi = getKnownPlan("xiaomi-mimo");
assert.ok(xiaomi, "xiaomi-mimo must have a known plan so the wizard pre-fills");
assert.ok(
xiaomi!.dimensions.some((d) => d.unit === "tokens" && d.window === "monthly" && d.limit === 4_100_000_000),
"xiaomi-mimo must seed the 4.1B-token monthly lite cap"
);
const kimiCoding = getKnownPlan("kimi-coding");
assert.ok(kimiCoding, "kimi-coding (the coding-plan slug) must have a known plan entry");
// claude (Claude Code) is percent-based like codex.
const claude = getKnownPlan("claude");
assert.ok(
claude && claude.dimensions.some((d) => d.unit === "percent"),
"claude must seed a percent plan preset"
);
// deepseek is prepaid USD → set the fair-share limit by USD value.
const deepseek = getKnownPlan("deepseek");
assert.ok(
deepseek && deepseek.dimensions.some((d) => d.unit === "usd"),
"deepseek must seed a usd (dollar-value) plan preset"
);
});
// ── i18n parity for every new key ────────────────────────────────────────────
test("i18n: new quotaShare keys exist in both en and pt-BR", () => {
const keys = [
"deleteGroup",
"deleteGroupConfirm",
"deleteGroupHasPools",
"ungroupedTitle",
"ungroupedHint",
"endpointsCollapse",
"endpointsExpand",
"endpointsAnthropicNote",
"endpointsResponsesNote",
];
for (const k of keys) {
assert.ok(en.quotaShare[k], `en.json quotaShare.${k} must exist`);
assert.ok(pt.quotaShare[k], `pt-BR.json quotaShare.${k} must exist`);
}
});