Files
mnote/wolai-frontend/src/lib/mindmap/leptos-mindmap-adapter.test.ts
T
2026-05-13 22:43:16 +08:00

111 lines
3.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import {
createMindmapAdapterProjectionEndpoint,
createMindmapCommandApplyEndpoint,
executeMindmapCommandApply,
executeMindmapCommandApplyAndRefreshProjection,
executeMindmapDataPutAndRefreshProjection,
isMindmapAdapterProjection,
requestMindmapAdapterProjection,
} from "./leptos-mindmap-adapter";
import { createFallbackMindmapAdapterProjection } from "./simple-mind-map-bridge";
describe("leptos-mindmap adapter projection", () => {
it("识别 adapter projection contract", () => {
const projection = createFallbackMindmapAdapterProjection({ mindmapId: "mind_1" });
expect(isMindmapAdapterProjection(projection)).toBe(true);
expect(isMindmapAdapterProjection({ ...projection, runtime: "other" })).toBe(false);
});
it("构建 simple_mind_map_scene 查询 endpoint", () => {
expect(createMindmapAdapterProjectionEndpoint("doc 1", "mind/1")).toBe(
"/api/mindmap/doc%201/mind%2F1?view=simple_mind_map_scene&queryName=mindmap.simple_mind_map_scene.get",
);
expect(createMindmapCommandApplyEndpoint("doc 1", "mind/1")).toBe(
"/api/mindmap/doc%201/mind%2F1",
);
});
it("从 result wrapper 中读取 projection", async () => {
const projection = createFallbackMindmapAdapterProjection({ mindmapId: "mind_1" });
const fetcher = vi.fn(async () => ({
ok: true,
json: async () => ({ result: projection }),
})) as unknown as typeof fetch;
await expect(
requestMindmapAdapterProjection({
documentId: "doc_1",
mindmapId: "mind_1",
fetcher,
}),
).resolves.toEqual(projection);
});
it("command apply 成功后可刷新 adapter projection", async () => {
const projection = createFallbackMindmapAdapterProjection({ mindmapId: "mind_1", kernelRevision: 12 });
const fetcher = vi
.fn()
.mockResolvedValueOnce({
ok: true,
json: async () => ({ ok: true, kernelRevision: 11 }),
})
.mockResolvedValueOnce({
ok: true,
json: async () => ({ result: projection }),
}) as unknown as typeof fetch;
await expect(
executeMindmapCommandApplyAndRefreshProjection({
documentId: "doc_1",
mindmapId: "mind_1",
commands: [{ type: "updateText", mindmapId: "mind_1", nodeId: "root", text: "新标题" }],
projectionRevision: 10,
fetcher,
}),
).resolves.toEqual(projection);
expect(fetcher).toHaveBeenNthCalledWith(
1,
"/api/mindmap/doc_1/mind_1",
expect.objectContaining({
method: "POST",
body: expect.stringContaining('"commandName":"mindmap.command.apply"'),
}),
);
});
it("command apply 失败时抛出可定位 command_failed 错误", async () => {
const fetcher = vi.fn(async () => ({
ok: false,
status: 409,
json: async () => ({ error: "revision_conflict" }),
})) as unknown as typeof fetch;
await expect(
executeMindmapCommandApply({
documentId: "doc_1",
mindmapId: "mind_1",
commands: [{ type: "deleteNode", mindmapId: "mind_1", nodeId: "node_1" }],
fetcher,
}),
).rejects.toMatchObject({ code: "command_failed", status: 409, message: "command_failed:409:revision_conflict" });
});
it("data put 失败时透出 route 错误细节", async () => {
const fetcher = vi.fn(async () => ({
ok: false,
status: 400,
json: async () => ({ error: "mindmap_put_failed", details: ["missing_root_uid"] }),
})) as unknown as typeof fetch;
await expect(
executeMindmapDataPutAndRefreshProjection({
documentId: "doc_1",
mindmapId: "mind_1",
data: { data: { text: "中心主题" }, children: [] },
fetcher,
}),
).rejects.toMatchObject({ code: "command_failed", status: 400, message: "command_failed:400:mindmap_put_failed" });
});
});