fix(web): stale-closure + focus trap + 去边界强转 + a11y/性能打磨 + 类型化客户端

P1-6 useStyleLearn/useKimiOauth 修 stale-closure 依赖。
P1-7 CommandPalette/Drawer 加 focus trap(新 lib/a11y/focusTrap)。
P1-8 SSE 解析与 server.ts 去 as 强转改类型守卫/运行时校验。
P2 删冗余强转、开 noUncheckedIndexedAccess、Toast 清理+稳定 key、列表 key 稳定化、
  rel=noopener、useMemo 大文本、ConflictCard role=group、useInjection 加锁、
  client.test 真断言。
codegen 重生成 schema.d.ts + 消费 DimensionEntry/ReviewConflictView 强类型。
This commit is contained in:
Yaojia Wang
2026-06-21 19:32:49 +02:00
parent 016509c5c6
commit c6651b74b9
36 changed files with 792 additions and 140 deletions

View File

@@ -1,8 +1,45 @@
import { describe, expect, it } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
describe("api base url", () => {
it("falls back to localhost when env unset", () => {
const base = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:8000";
expect(base).toMatch(/^https?:\/\//);
// P2真正断言——mock openapi-fetch验证 client 用正确 baseUrl 初始化。
// createClient 在模块加载时被调用一次,故每个用例 resetModules + 重新 import。
const createClientMock = vi.fn(() => ({ GET: vi.fn(), POST: vi.fn() }));
vi.mock("openapi-fetch", () => ({
default: createClientMock,
}));
afterEach(() => {
vi.resetModules();
vi.unstubAllEnvs();
createClientMock.mockClear();
});
describe("api client baseUrl", () => {
it("uses NEXT_PUBLIC_API_BASE when set", async () => {
vi.stubEnv("NEXT_PUBLIC_API_BASE", "https://api.example.com");
await import("./client");
expect(createClientMock).toHaveBeenCalledTimes(1);
expect(createClientMock).toHaveBeenCalledWith({
baseUrl: "https://api.example.com",
});
});
it("falls back to localhost when env unset", async () => {
vi.stubEnv("NEXT_PUBLIC_API_BASE", undefined);
await import("./client");
expect(createClientMock).toHaveBeenCalledWith({
baseUrl: "http://localhost:8000",
});
});
it("exposes the constructed client as `api`", async () => {
const mod = await import("./client");
expect(mod.api).toBeDefined();
expect(typeof mod.api.GET).toBe("function");
});
});