Files
OmniRoute/tests/unit/volcengine-plan-cookie-field.test.ts
Bob.Hou 171421439d fix(dashboard): expose Volcano console cookie field and unwrap error objects (#13107)
Both halves are real. A quota fetcher that needs console cookies with no way to enter them is unusable on any headless or remote install, and `new Error($'{'}object{'}'}` rendering `[object Object]` in a toast is exactly what makes a route-guard rejection unreadable.

---

Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the other 19 PRs of this batch. Two in-batch conflicts, both additive and resolved by keeping each side: the `ENVIRONMENT.md` table (#13035 + #13011) and the `chatHelpers.ts` import block (#12975 on the tip + #13017).

- `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, within baseline); `check:changelog-integrity` OK; `check:docs-counts` migrations ✓
- complexity 2816 / baseline 3218 and cognitive-complexity 1271 / baseline 1437 — both under baseline
- 531 of 532 focused assertions green across the batch's 46 test files
- `check-file-size` rebaselined for the batch's real growth (annotation `_rebaseline_2026_09_11_mergebatch_v3851_houminxi`, landed on #13038), attributed per PR

The single red is **not this batch**: `tests/unit/combo/quota-weighted-strategy.test.ts` → "A/B isolation: 7 hard-empty + 2 at 0.5% + 1 at 40%, floor=1" asserts an order between two connections of identical weight and flakes on the pure tip too — 2 failures in 4 runs at `origin/release/v3.8.51` with nothing from this batch applied.

⚠️ base-red inherited: #12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, untouched here).

Thanks @HouMinXi — the live evidence on these (X500 logs, `storage.sqlite` state, real `/v1/models` probes, the 36-minute outage write-up) is what let a 20-PR batch be reviewed as a unit.
2026-09-11 19:28:17 -03:00

101 lines
3.5 KiB
TypeScript

/**
* volcengine-plan-cookie-field.test.ts — Volcano Ark Coding/Agent Plan
* quota fetchers are cookie-authenticated (API keys cannot query the console
* quota API). Expose volcConsoleCookie in QuotaScrapingFields so users can
* paste their console cookie from the dashboard without needing local browser automation.
*/
import test from "node:test";
import assert from "node:assert/strict";
import {
EMPTY_QUOTA_SCRAPING_FIELDS,
assignQuotaScrapingProviderData,
} from "../../src/app/(dashboard)/dashboard/providers/[id]/components/modals/quotaScrapingFieldValues.ts";
import { extractErrorMessage } from "../../src/shared/utils/upstreamError.ts";
const { updateProviderConnectionSchema } = await import("../../src/shared/validation/schemas.ts");
test("volcengine-coding-plan and volcengine-agent-plan persist the console cookie", () => {
for (const provider of ["volcengine-coding-plan", "volcengine-agent-plan"]) {
const target: Record<string, unknown> = {};
assignQuotaScrapingProviderData(
provider,
{
...EMPTY_QUOTA_SCRAPING_FIELDS,
volcConsoleCookie: " session=volc-123; AccountID=acc-456 ",
},
target
);
assert.equal(
target.volcConsoleCookie,
"session=volc-123; AccountID=acc-456",
`cookie must be stored trimmed for ${provider}`
);
}
});
test("a blank volcConsoleCookie does not overwrite the stored one", () => {
for (const provider of ["volcengine-coding-plan", "volcengine-agent-plan"]) {
const target: Record<string, unknown> = {};
assignQuotaScrapingProviderData(
provider,
{ ...EMPTY_QUOTA_SCRAPING_FIELDS, volcConsoleCookie: " " },
target
);
assert.equal(
Object.hasOwn(target, "volcConsoleCookie"),
false,
"blank input must leave the stored cookie untouched"
);
}
});
test("a form object without volcConsoleCookie does not throw", () => {
const target: Record<string, unknown> = {};
const partial = { ...EMPTY_QUOTA_SCRAPING_FIELDS } as Record<string, string>;
delete partial.volcConsoleCookie;
for (const provider of ["volcengine-coding-plan", "volcengine-agent-plan"]) {
assert.doesNotThrow(() =>
assignQuotaScrapingProviderData(
provider,
partial as unknown as typeof EMPTY_QUOTA_SCRAPING_FIELDS,
target
)
);
}
assert.equal(Object.hasOwn(target, "volcConsoleCookie"), false);
});
test("providerSpecificData validation guards the volcConsoleCookie field", () => {
const ok = updateProviderConnectionSchema.safeParse({
providerSpecificData: { volcConsoleCookie: "session=volc-abc" },
});
assert.equal(ok.success, true, JSON.stringify(ok.error?.issues));
const wrongType = updateProviderConnectionSchema.safeParse({
providerSpecificData: { volcConsoleCookie: 42 },
});
assert.equal(wrongType.success, false, "non-string cookie must be rejected");
const tooLong = updateProviderConnectionSchema.safeParse({
providerSpecificData: { volcConsoleCookie: "x".repeat(10_001) },
});
assert.equal(tooLong.success, false, "oversized cookie must be rejected");
});
test("extractErrorMessage extracts message from structured error objects instead of [object Object]", () => {
const localOnlyError = {
code: "LOCAL_ONLY",
message: "This endpoint requires localhost access",
};
const extracted = extractErrorMessage(localOnlyError);
assert.equal(extracted, "This endpoint requires localhost access");
const stringError = "Failed to start Volcano login";
assert.equal(extractErrorMessage(stringError), null);
});