63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
// @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(<QueryClientProvider client={qc}>{ui}</QueryClientProvider>);
|
|
return container;
|
|
}
|
|
|
|
describe("SearchPanel", () => {
|
|
it("renders search controls and idle state", () => {
|
|
const container = render(
|
|
<SearchPanel
|
|
onOpenPath={() => {}}
|
|
onDownloadPath={() => {}}
|
|
onTagsPath={() => {}}
|
|
/>,
|
|
);
|
|
|
|
const text = container.textContent || "";
|
|
expect(text).toContain("Semantic");
|
|
expect(text).toContain("Refresh");
|
|
expect(text).toContain("Enter a query to search.");
|
|
});
|
|
});
|