theo-agent-dashboard

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Search.test.tsx (3319B)


      1 import { describe, it, expect, vi } from "vitest";
      2 import { render, screen, fireEvent } from "@testing-library/react";
      3 import { SearchBar } from "./SearchBar";
      4 import { SearchResults } from "./SearchResults";
      5 
      6 describe("SearchBar", () => {
      7   it("renders with placeholder", () => {
      8     render(<SearchBar onSearch={vi.fn()} isSearching={false} />);
      9     expect(screen.getByPlaceholderText("Search messages... (Ctrl+K)")).toBeInTheDocument();
     10   });
     11 
     12   it("calls onSearch after debounce", () => {
     13     vi.useFakeTimers();
     14     const onSearch = vi.fn();
     15     render(<SearchBar onSearch={onSearch} isSearching={false} />);
     16     const input = screen.getByPlaceholderText("Search messages... (Ctrl+K)");
     17     fireEvent.change(input, { target: { value: "hello" } });
     18     expect(onSearch).not.toHaveBeenCalled();
     19     vi.advanceTimersByTime(300);
     20     expect(onSearch).toHaveBeenCalledWith("hello");
     21     vi.useRealTimers();
     22   });
     23 
     24   it("clears query and calls onSearch with empty string", () => {
     25     const onSearch = vi.fn();
     26     render(<SearchBar onSearch={onSearch} isSearching={false} />);
     27     const input = screen.getByPlaceholderText("Search messages... (Ctrl+K)") as HTMLInputElement;
     28     fireEvent.change(input, { target: { value: "test" } });
     29     fireEvent.click(screen.getByLabelText("Clear search"));
     30     expect(input.value).toBe("");
     31     expect(onSearch).toHaveBeenCalledWith("");
     32   });
     33 
     34   it("shows searching indicator", () => {
     35     render(<SearchBar onSearch={vi.fn()} isSearching={true} />);
     36     expect(screen.getByText("Searching...")).toBeInTheDocument();
     37   });
     38 });
     39 
     40 describe("SearchResults", () => {
     41   it("shows empty message when no results", () => {
     42     render(<SearchResults results={[]} onSelectMessage={vi.fn()} onClose={vi.fn()} />);
     43     expect(screen.getByText("No results found")).toBeInTheDocument();
     44   });
     45 
     46   it("renders grouped results by session", () => {
     47     const results = [
     48       {
     49         session_id: "s1",
     50         session_name: "Test Session",
     51         messages: [
     52           { id: "m1", content: "Hello world", role: "user" },
     53           { id: "m2", content: "Hi there!", role: "assistant" },
     54         ],
     55       },
     56     ];
     57     render(<SearchResults results={results} onSelectMessage={vi.fn()} onClose={vi.fn()} />);
     58     expect(screen.getByText("Test Session")).toBeInTheDocument();
     59     expect(screen.getByText("Hello world")).toBeInTheDocument();
     60   });
     61 
     62   it("calls onSelectMessage with correct ids on click", () => {
     63     const onSelectMessage = vi.fn();
     64     const onClose = vi.fn();
     65     const results = [
     66       {
     67         session_id: "s1",
     68         session_name: "Session",
     69         messages: [{ id: "m1", content: "test", role: "user" }],
     70       },
     71     ];
     72     render(
     73       <SearchResults results={results} onSelectMessage={onSelectMessage} onClose={onClose} />,
     74     );
     75     fireEvent.click(screen.getByText("test"));
     76     expect(onSelectMessage).toHaveBeenCalledWith("s1", "m1");
     77     expect(onClose).toHaveBeenCalled();
     78   });
     79 
     80   it("truncates long messages", () => {
     81     const results = [
     82       {
     83         session_id: "s1",
     84         session_name: "S",
     85         messages: [{ id: "m1", content: "a".repeat(200), role: "user" }],
     86       },
     87     ];
     88     render(<SearchResults results={results} onSelectMessage={vi.fn()} onClose={vi.fn()} />);
     89     expect(screen.getByText(/a{120}\.\.\./)).toBeInTheDocument();
     90   });
     91 });