Files
mnote/wolai-frontend/src/lib/sidebar-data.test.ts
T

423 lines
12 KiB
TypeScript

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.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: [],
},
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,
},
},
],
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",
},
],
},
],
});
});
});