Files
llm-wiki/workbench/web/test/sidebar.test.tsx
T
2026-07-12 21:26:08 +08:00

111 lines
4.3 KiB
TypeScript

import { describe, it } from "node:test";
import assert from "node:assert/strict";
import React from "react";
import { Sidebar } from "../src/components/Sidebar";
import { TooltipProvider } from "../src/components/ui/tooltip";
import { click, render, screen } from "./render";
describe("Sidebar", () => {
it("renders V2 expanded sidebar sections and footer actions", async () => {
const events = makeSidebarEvents();
renderSidebar(false, events);
assert.equal(Boolean(screen.queryByTitle("刷新")), false, "expanded sidebar should not render refresh");
assert.equal(Boolean(screen.queryByLabelText("设置")), false, "expanded sidebar should not render top settings");
assert.equal(Boolean(screen.queryByText("llm-wiki-agent")), false, "expanded sidebar should not repeat the topbar brand");
assert.ok(screen.getByLabelText("折叠侧栏"));
assert.ok(screen.getByText("笔记本"));
assert.ok(screen.getByText("会话"));
assert.ok(screen.getByRole("button", { name: "图谱活地图" }));
assert.ok(screen.getByRole("button", { name: "设置" }));
assert.ok(screen.getByRole("button", { name: "新建知识库" }));
assert.equal(Boolean(screen.queryByText("添加现有库")), false, "sidebar should rename add-existing flow");
assert.equal(Boolean(document.querySelector(".main-view-switch")), false, "expanded sidebar should not render old view switch");
await click(screen.getByRole("button", { name: "图谱活地图" }));
await click(screen.getByRole("button", { name: "设置" }));
await click(screen.getByRole("button", { name: "新建知识库" }));
assert.deepEqual(events.views, ["graph"]);
assert.equal(events.settings, 1);
assert.ok(await screen.findByRole("heading", { name: "新建知识库" }));
});
it("renders conversations outside the knowledge-base tree", () => {
renderSidebar(false);
const notebookSection = screen.getByText("笔记本").closest(".sidebar-section");
const conversationSection = screen.getByText("会话").closest(".sidebar-section");
assert.ok(notebookSection);
assert.ok(conversationSection);
assert.equal(notebookSection?.contains(screen.getByText("Transformer vs Mamba")), false);
assert.equal(conversationSection?.contains(screen.getByText("Transformer vs Mamba")), true);
assert.equal(Boolean(document.querySelector(".kb-children")), false, "conversations should not be nested under knowledge bases");
});
it("keeps the collapsed rail aligned with V2 actions", async () => {
const events = makeSidebarEvents();
renderSidebar(true, events);
assert.ok(screen.getByLabelText("展开侧栏"));
assert.ok(screen.getByLabelText("当前知识库:AI学习知识库"));
assert.ok(screen.getByLabelText("对话"));
assert.ok(screen.getByLabelText("图谱活地图"));
assert.ok(screen.queryByLabelText("设置"));
assert.ok(screen.getByLabelText("新建知识库"));
assert.equal(Boolean(screen.queryByLabelText("刷新")), false, "collapsed rail should not render refresh");
assert.equal(Boolean(screen.queryByLabelText("添加现有库")), false, "collapsed rail should not render add-existing");
await click(screen.getByLabelText("新建知识库"));
assert.ok(await screen.findByRole("heading", { name: "新建知识库" }));
});
});
function makeSidebarEvents() {
return {
views: [] as string[],
settings: 0,
};
}
function renderSidebar(collapsed: boolean, events = makeSidebarEvents()) {
return render(
<TooltipProvider>
<Sidebar
knowledgeBases={[
{ path: "/kb", name: "AI学习知识库", origin: "default", valid: true },
{ path: "/external", name: "设计灵感库", origin: "external", valid: true },
]}
currentKbPath="/kb"
conversations={[
{
id: "c1",
path: "/kb/.llm-wiki/conversations/c1.jsonl",
firstMessage: "Transformer vs Mamba",
modifiedAt: Date.parse("2026-06-20T10:00:00.000Z"),
},
]}
currentConversationId="c1"
error={null}
collapsed={collapsed}
activeView="chat"
onSelectKb={noop}
onSelectConversation={(item) => {
events.views.push(`conversation:${item.id}`);
}}
onSelectView={(view) => events.views.push(view)}
onNewConversation={noop}
onOpenSettings={() => {
events.settings += 1;
}}
onToggleCollapsed={noop}
onAddExternal={asyncNoop}
/>
</TooltipProvider>,
);
}
function noop() {}
async function asyncNoop() {}