import { describe, expect, test, vi } from "bun:test"; import { fireEvent, screen, waitFor } from "@testing-library/react"; import { createElement } from "react"; import type { Conversation } from "../../../src/shared/api"; import { ConversationList } from "../../../src/web/features/chat/components/ConversationList"; import { renderWithProviders } from "../test-utils"; const CONVERSATIONS: Conversation[] = [ { createdAt: "2026-06-03T00:00:00.000Z", id: "conv-1", modelId: "model-1", projectId: "proj-1", title: "今天对话", updatedAt: "2026-06-03T00:00:00.000Z", }, { createdAt: "2026-06-02T00:00:00.000Z", id: "conv-2", modelId: "model-1", projectId: "proj-1", title: "昨天对话", updatedAt: "2026-06-02T00:00:00.000Z", }, { createdAt: "2026-05-01T00:00:00.000Z", id: "conv-3", modelId: "model-1", projectId: "proj-1", title: "更早对话", updatedAt: "2026-05-01T00:00:00.000Z", }, ]; describe("ConversationList", () => { test("列表为空时显示暂无对话", () => { renderWithProviders( createElement(ConversationList, { conversations: [], loading: false, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); expect(screen.getByText("暂无对话")).not.toBeNull(); }); test("渲染对话列表并按日期分组", () => { renderWithProviders( createElement(ConversationList, { conversations: CONVERSATIONS, loading: false, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); expect(screen.getByText("今天对话")).not.toBeNull(); expect(screen.getByText("昨天对话")).not.toBeNull(); expect(screen.getByText("更早对话")).not.toBeNull(); }); test("加载中显示 Skeleton", () => { renderWithProviders( createElement(ConversationList, { conversations: [], loading: true, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); expect(document.querySelector(".ant-skeleton")).not.toBeNull(); }); test("点击新对话按钮触发 onAddClick", () => { const onAddClick = vi.fn(); renderWithProviders( createElement(ConversationList, { conversations: [], loading: false, onAddClick, onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); screen.getByText("新对话").click(); expect(onAddClick).toHaveBeenCalledTimes(1); }); test("点击搜索按钮过滤对话标题", async () => { renderWithProviders( createElement(ConversationList, { conversations: CONVERSATIONS, loading: false, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); const searchInput = screen.getByPlaceholderText("搜索对话"); fireEvent.change(searchInput, { target: { value: "今天" } }); expect(screen.getByText("昨天对话")).not.toBeNull(); fireEvent.keyDown(searchInput, { key: "Enter" }); await waitFor(() => { expect(screen.getByText("今天对话")).not.toBeNull(); expect(screen.queryByText("昨天对话")).toBeNull(); expect(screen.queryByText("更早对话")).toBeNull(); }); }); test("输入文字未点击搜索时不触发过滤", () => { renderWithProviders( createElement(ConversationList, { conversations: CONVERSATIONS, loading: false, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); const searchInput = screen.getByPlaceholderText("搜索对话"); fireEvent.change(searchInput, { target: { value: "今天" } }); expect(screen.getByText("今天对话")).not.toBeNull(); expect(screen.getByText("昨天对话")).not.toBeNull(); expect(screen.getByText("更早对话")).not.toBeNull(); }); test("搜索无匹配结果时显示无匹配对话", async () => { renderWithProviders( createElement(ConversationList, { conversations: CONVERSATIONS, loading: false, onAddClick: vi.fn(), onDelete: vi.fn(), onSelect: vi.fn(), selectedId: null, }), ); const searchInput = screen.getByPlaceholderText("搜索对话"); fireEvent.change(searchInput, { target: { value: "不存在的对话" } }); fireEvent.keyDown(searchInput, { key: "Enter" }); await waitFor(() => { expect(screen.getByText("无匹配对话")).not.toBeNull(); }); }); });