// @vitest-environment jsdom import React from "react"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { createRoot } from "react-dom/client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { SearchPanel } from "@/components/search/search-panel"; // Mock Sentry to avoid needing full initialization in tests vi.mock("@sentry/nextjs", () => ({ startSpan: ( _opts: { op: string; name: string }, cb: (span: { setAttribute: (k: string, v: unknown) => void }) => void, ) => cb({ setAttribute: () => {} }), })); // Basic fetch mock for search endpoint beforeEach(() => { global.fetch = vi.fn(async (input: RequestInfo | URL) => { const url = typeof input === "string" ? input : input.toString(); if (url.includes("/api/search/query")) { return { ok: true, json: async () => ({ total: 0, hits: [], tookMs: 0, }), } as unknown as Response; } return { ok: true, json: async () => ({}), } as unknown as Response; }) as unknown as typeof fetch; }); function render(ui: React.ReactElement) { const container = document.createElement("div"); document.body.appendChild(container); const root = createRoot(container); const qc = new QueryClient(); root.render({ui}); return container; } describe("SearchPanel", () => { it("renders search controls and idle state", () => { const container = render( {}} onDownloadPath={() => {}} onTagsPath={() => {}} />, ); const text = container.textContent || ""; expect(text).toContain("Semantic"); expect(text).toContain("Refresh"); expect(text).toContain("Enter a query to search."); }); });