103 lines
2.7 KiB
TypeScript
103 lines
2.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { ApiError, toErrorMessage } from "./api";
|
|
import {
|
|
decodeAction,
|
|
decodeDashboard,
|
|
decodeDeviceLogin,
|
|
decodeGeneral,
|
|
decodeTelegram,
|
|
} from "./types";
|
|
|
|
describe("API decoders", () => {
|
|
it("保留 Dashboard 的 null 与 optional 摘要", () => {
|
|
const value = decodeDashboard({
|
|
accountId: 2,
|
|
displayName: "Team",
|
|
account: { email: null, planType: null, connected: false },
|
|
limits: [],
|
|
summary: { lifetimeTokens: null },
|
|
usage: [],
|
|
fetchedAt: 0,
|
|
stale: true,
|
|
});
|
|
expect(value.summary.lifetimeTokens).toBeNull();
|
|
expect(value.account.email).toBeNull();
|
|
});
|
|
|
|
it("解码当前重置周期 Token 合计", () => {
|
|
const value = decodeDashboard({
|
|
accountId: 1,
|
|
displayName: "个人账号",
|
|
account: { email: "user@example.com", planType: "plus", connected: true },
|
|
limits: [],
|
|
currentCycle: {
|
|
limitId: "codex",
|
|
windowType: "secondary",
|
|
windowDurationMinutes: 10080,
|
|
startedAt: 1_900_000_000,
|
|
resetsAt: 1_900_604_800,
|
|
totalTokens: 123_456,
|
|
},
|
|
summary: {},
|
|
usage: [],
|
|
fetchedAt: 1_900_000_000,
|
|
stale: false,
|
|
});
|
|
expect(value.currentCycle?.windowType).toBe("secondary");
|
|
expect(value.currentCycle?.totalTokens).toBe(123_456);
|
|
});
|
|
|
|
it("拒绝未知主题", () => {
|
|
expect(() =>
|
|
decodeGeneral({
|
|
timezone: "UTC",
|
|
theme: "blue",
|
|
syncMinutes: 5,
|
|
retentionDays: 90,
|
|
beforeMinutes: 30,
|
|
notifyBefore: true,
|
|
notifyAfter: true,
|
|
}),
|
|
).toThrow("theme格式无效");
|
|
});
|
|
|
|
it("只接受 HTTPS 设备授权地址", () => {
|
|
expect(() =>
|
|
decodeDeviceLogin({
|
|
verificationUrl: "http://example.com",
|
|
userCode: "ABC",
|
|
}),
|
|
).toThrow("HTTPS");
|
|
expect(
|
|
decodeDeviceLogin({
|
|
verificationUrl: "https://example.com",
|
|
userCode: "ABC",
|
|
}).userCode,
|
|
).toBe("ABC");
|
|
});
|
|
|
|
it("保留 Telegram 操作警告", () => {
|
|
expect(
|
|
decodeTelegram({
|
|
chatId: 1,
|
|
enabled: false,
|
|
menuEnabled: false,
|
|
configured: true,
|
|
warning: "菜单同步失败",
|
|
}).warning,
|
|
).toBe("菜单同步失败");
|
|
expect(decodeAction({ ok: true, warning: "键盘清理失败" }).warning).toBe(
|
|
"键盘清理失败",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("errors", () => {
|
|
it("保留结构化 API 错误", () => {
|
|
const error = new ApiError("未登录", "http", 401);
|
|
expect(error.status).toBe(401);
|
|
expect(toErrorMessage(error)).toBe("未登录");
|
|
expect(toErrorMessage("bad")).toBe("发生未知错误");
|
|
});
|
|
});
|