import { describe, expect, it } from "vitest"; import type { DocumentRecord } from "@/lib/documents"; import type { WorkspaceSummary } from "@/lib/workspaces"; import type { SidebarInitialData } from "@/components/sidebar/types"; import { buildSidebarDatasetListQueryPayload, buildSidebarDatasetListQueryResult, buildSidebarInitialData, extractMindmapImageAssetIdsFromData, mapSidebarDatasetListQueryResultToInitialData, } from "@/lib/sidebar-data"; describe("extractMindmapImageAssetIdsFromData", () => { it("提取导图节点里的 asset 图片引用并去重", () => { const ids = extractMindmapImageAssetIdsFromData({ root: { data: { image: "asset:img_1" }, children: [ { image: { url: "asset:img_2" } }, { data: { image: { url: "asset:img_1" } } }, ], }, }); expect(ids).toEqual(["img_1", "img_2"]); }); }); describe("buildSidebarInitialData", () => { it("统一组装 mindmap/table/media 相关侧边栏数据", () => { const workspaces: WorkspaceSummary[] = [ { id: "ws_1", name: "工作区", type: "personal", iconUrl: null, memberCount: 1, isDefault: true, }, ]; const documents: DocumentRecord[] = [ { id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, }, ]; const trashedDocuments: SidebarInitialData["trashedDocuments"] = []; const payload = buildSidebarInitialData({ activeWorkspaceId: "ws_1", workspaces, documents, trashedDocuments, mediaAssets: [ { id: "asset_file_1", workspace_id: "ws_1", document_id: "doc_1", asset_type: "file", file_url: "/file/1", thumbnail_url: null, bucket: null, storage_path: null, file_name: "a.txt", file_size: null, mime_type: "text/plain", ocr_payload: undefined, ocr_strategy: null, ocr_text: null, ocr_status: null, signed_url: null, created_at: "2026-04-14T00:00:00Z", updated_at: "2026-04-14T00:00:00Z", }, ], trashedMediaAssets: [], mindmaps: [ { mindmap_id: "mind_1", workspace_id: "ws_1", document_id: "doc_1", data: { root: { data: { image: "asset:img_a" }, children: [{ image: { url: "asset:img_b" } }], }, }, created_at: "2026-04-14T00:00:00Z", updated_at: "2026-04-14T00:00:00Z", deleted_at: null, }, { mindmap_id: "mind_2", workspace_id: "ws_1", document_id: "doc_1", data: null, created_at: "2026-04-14T00:00:00Z", updated_at: "2026-04-14T00:00:00Z", deleted_at: "2026-04-14T01:00:00Z", deleted_by: "user_1", }, ], tables: [ { id: "table_1", workspace_id: "ws_1", document_id: "doc_1", title: "预算", created_at: "2026-04-14T00:00:00Z", updated_at: "2026-04-14T00:00:00Z", is_archived: false, }, { id: "table_2", workspace_id: "ws_1", document_id: "doc_1", title: "归档表格", created_at: "2026-04-14T00:00:00Z", updated_at: "2026-04-14T00:00:00Z", deleted_at: "2026-04-14T01:00:00Z", deleted_by: "user_1", purged_at: null, is_archived: true, }, ], }); expect(payload.activeWorkspaceId).toBe("ws_1"); expect(payload.kernelSidebarProjection?.projection).toBe("sidebar_tree"); expect(payload.kernelFileTreeProjection?.projection).toBe("file_tree"); expect(payload.kernelSidebarTree?.map((item) => item.id)).toEqual(["doc_1"]); expect(payload.mindmapDocs).toEqual(["doc_1"]); expect(payload.mindmapAssetChildren).toEqual({ mind_1: ["img_a", "img_b"], }); expect(payload.mindmapAssets?.map((item) => item.id)).toEqual(["mind_1"]); expect(payload.trashedMindmapAssets?.map((item) => item.id)).toEqual(["mind_2"]); expect(payload.tableAssets?.map((item) => item.file_name)).toEqual(["预算.luckysheet"]); expect(payload.trashedTableAssets?.map((item) => item.id)).toEqual(["table_2"]); expect(payload.mediaAssets?.map((item) => item.id)).toEqual(["asset_file_1"]); }); it("冻结 sidebar.dataset.list 的 Rust query 契约字段", () => { const queryPayload = buildSidebarDatasetListQueryPayload(" ws_1 "); expect(queryPayload).toEqual({ workspace_id: "ws_1" }); const queryResult = buildSidebarDatasetListQueryResult({ activeWorkspaceId: "ws_1", workspaces: [ { id: "ws_1", name: "工作区", type: "personal", iconUrl: null, memberCount: 1, isDefault: true, }, ], documents: [ { id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, }, ], trashedDocuments: [], mindmaps: [], mediaAssets: [], trashedMediaAssets: [], tables: [], }); expect(queryResult).toEqual({ active_workspace_id: "ws_1", workspaces: [ { id: "ws_1", name: "工作区", type: "personal", iconUrl: null, memberCount: 1, isDefault: true, }, ], documents: [ { id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, }, ], kernel_sidebar_projection: { projectionId: "kernel_projection:sidebar_tree:workspace_root", projection: "sidebar_tree", rootNodeId: null, items: [ { nodeId: "doc_1", parentNodeId: null, nodeType: "page", projectionKind: "sidebar_tree", title: "页面 1", depth: 0, position: 1, childCount: 0, expandable: false, expandedByDefault: true, capabilities: [ "open", "drag", "drop", "select", "create-child", "rename", "archive", "restore", "context-menu", "reorder", ], resourceMeta: { resourceKind: "document", documentId: "doc_1", workspaceId: "ws_1", iconHint: "page", }, iconHint: "page", }, ], edges: [], }, kernel_file_tree_projection: { projectionId: "kernel_projection:file_tree:root", projection: "file_tree", rootNodeId: null, items: [ { rowId: "doc:doc_1", rowKind: "document", nodeId: "doc_1", parentNodeId: null, nodeType: "page", projectionKind: "file_tree", title: "页面 1", depth: 0, position: 1, childCount: 1, expandable: true, expandedByDefault: true, capabilities: [ "expand", "open", "drag", "drop", "select", "create-child", "rename", "archive", "restore", "context-menu", "reorder", ], resourceMeta: { resourceKind: "document", documentId: "doc_1", workspaceId: "ws_1", iconHint: "page", }, iconHint: "page", }, { rowId: "index:doc_1", rowKind: "index", nodeId: "index:doc_1", parentNodeId: "doc_1", nodeType: "index", projectionKind: "file_tree", title: "index.md", depth: 1, position: 0, childCount: 0, expandable: false, expandedByDefault: false, capabilities: ["open", "select", "context-menu"], resourceMeta: { resourceKind: "index", documentId: "doc_1", workspaceId: "ws_1", iconHint: "index", }, iconHint: "index", }, ], edges: [ { id: "edge:doc_1:index:doc_1:parent_of", edgeType: "parent_of", workspaceId: "ws_1", fromNodeId: "doc_1", toNodeId: "index:doc_1", }, ], }, trashed_documents: [], media_assets: [], trashed_media_assets: [], mindmap_assets: [], trashed_mindmap_assets: [], table_assets: [], trashed_table_assets: [], mindmap_docs: [], mindmap_asset_children: {}, }); expect(mapSidebarDatasetListQueryResultToInitialData(queryResult)).toEqual({ activeWorkspaceId: "ws_1", workspaces: [ { id: "ws_1", name: "工作区", type: "personal", iconUrl: null, memberCount: 1, isDefault: true, }, ], documents: [ { id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, }, ], kernelSidebarProjection: { projectionId: "kernel_projection:sidebar_tree:workspace_root", projection: "sidebar_tree", rootNodeId: null, items: [ { nodeId: "doc_1", parentNodeId: null, nodeType: "page", projectionKind: "sidebar_tree", title: "页面 1", depth: 0, position: 1, childCount: 0, expandable: false, expandedByDefault: true, capabilities: [ "open", "drag", "drop", "select", "create-child", "rename", "archive", "restore", "context-menu", "reorder", ], resourceMeta: { resourceKind: "document", documentId: "doc_1", workspaceId: "ws_1", iconHint: "page", }, iconHint: "page", }, ], edges: [], }, kernelSidebarTree: [ { access_scope: "private", id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, children: [], kernel: { nodeType: "page", depth: 0, position: 1, childCount: 0, expandedByDefault: true, }, }, ], kernelFileTreeProjection: { projectionId: "kernel_projection:file_tree:root", projection: "file_tree", rootNodeId: null, items: [ { rowId: "doc:doc_1", rowKind: "document", nodeId: "doc_1", parentNodeId: null, nodeType: "page", projectionKind: "file_tree", title: "页面 1", depth: 0, position: 1, childCount: 1, expandable: true, expandedByDefault: true, capabilities: [ "expand", "open", "drag", "drop", "select", "create-child", "rename", "archive", "restore", "context-menu", "reorder", ], resourceMeta: { resourceKind: "document", documentId: "doc_1", workspaceId: "ws_1", iconHint: "page", }, iconHint: "page", }, { rowId: "index:doc_1", rowKind: "index", nodeId: "index:doc_1", parentNodeId: "doc_1", nodeType: "index", projectionKind: "file_tree", title: "index.md", depth: 1, position: 0, childCount: 0, expandable: false, expandedByDefault: false, capabilities: ["open", "select", "context-menu"], resourceMeta: { resourceKind: "index", documentId: "doc_1", workspaceId: "ws_1", iconHint: "index", }, iconHint: "index", }, ], edges: [ { id: "edge:doc_1:index:doc_1:parent_of", edgeType: "parent_of", workspaceId: "ws_1", fromNodeId: "doc_1", toNodeId: "index:doc_1", }, ], }, trashedDocuments: [], trashedMediaAssets: [], trashedMindmapAssets: [], trashedTableAssets: [], mindmapDocs: [], mindmapAssets: [], mindmapAssetChildren: {}, tableAssets: [], mediaAssets: [], }); }); it("缺少 kernel projection 时会按 documents 重建 projection 并保留层级", () => { expect( mapSidebarDatasetListQueryResultToInitialData({ active_workspace_id: "ws_1", workspaces: [], documents: [ { id: "doc_1", workspace_id: "ws_1", title: "页面 1", parent_id: null, sort_order: 1, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:00:00Z", updated_at: null, }, { id: "doc_2", workspace_id: "ws_1", title: "页面 2", parent_id: "doc_1", sort_order: 0, is_starred: false, access_scope: "private", is_template: false, created_at: "2026-04-14T00:01:00Z", updated_at: null, }, ], trashed_documents: [], media_assets: [], trashed_media_assets: [], mindmap_assets: [], trashed_mindmap_assets: [], table_assets: [], trashed_table_assets: [], mindmap_docs: [], mindmap_asset_children: {}, }), ).toMatchObject({ activeWorkspaceId: "ws_1", kernelSidebarProjection: { projectionId: "kernel_projection:sidebar_tree:workspace_root", }, kernelSidebarTree: [ { id: "doc_1", children: [ { id: "doc_2", }, ], }, ], }); }); });