Files
ThothII/frontend/src/viewers/ResultsPanel.test.tsx
T

146 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { http, HttpResponse } from "msw";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { server } from "../test/msw";
import { ResultsPanel } from "./ResultsPanel";
const BASE = "/api";
function makeClient() {
return new QueryClient({
defaultOptions: { queries: { retry: false } },
});
}
function wrap(ui: React.ReactElement) {
return (
<QueryClientProvider client={makeClient()}>{ui}</QueryClientProvider>
);
}
// (a) 2-col × 2-row preview → AGGrid renders cell values
test("(a) renders grid cells for a 2×2 preview result", async () => {
server.use(
http.post(`${BASE}/sessions/sess-1/sql/preview`, () =>
HttpResponse.json({
columns: ["name", "age"],
rows: [
["Alice", 30],
["Bob", 25],
],
execution_ms: 5,
truncated: true,
limit: 10,
offset: 0,
})
)
);
render(wrap(<ResultsPanel sessionId="sess-1" />));
// Wait for data to load; check known cell values
await screen.findByText("Alice");
expect(screen.getByText("Bob")).toBeInTheDocument();
expect(screen.getByText("30")).toBeInTheDocument();
expect(screen.getByText("25")).toBeInTheDocument();
// Grid must be present, not bold scalar
expect(screen.queryByTestId("scalar-value")).not.toBeInTheDocument();
// truncated:true → show the "results truncated" indicator
expect(screen.getByText(/results truncated/i)).toBeInTheDocument();
});
// (b) 1×1 preview → bold scalar shown, no grid
test("(b) renders bold scalar for a 1×1 result", async () => {
server.use(
http.post(`${BASE}/sessions/sess-2/sql/preview`, () =>
HttpResponse.json({
columns: ["count"],
rows: [[42]],
execution_ms: 2,
truncated: false,
limit: 10,
offset: 0,
})
)
);
render(wrap(<ResultsPanel sessionId="sess-2" />));
// Should show the scalar value in bold
const bold = await screen.findByTestId("scalar-value");
expect(bold).toHaveTextContent("42");
// No grid
expect(screen.queryByRole("treegrid")).not.toBeInTheDocument();
expect(screen.queryByRole("grid")).not.toBeInTheDocument();
});
// (c) clicking "Esporta CSV" calls the export endpoint
test("(c) Esporta CSV button calls the export endpoint", async () => {
let exportCalled = false;
server.use(
http.post(`${BASE}/sessions/sess-3/sql/preview`, () =>
HttpResponse.json({
columns: ["id"],
rows: [[1], [2]],
execution_ms: 3,
truncated: false,
limit: 10,
offset: 0,
})
),
http.post(`${BASE}/sessions/sess-3/sql/export`, () => {
exportCalled = true;
return HttpResponse.json({ path: "/tmp/export.csv" });
})
);
const user = userEvent.setup();
render(wrap(<ResultsPanel sessionId="sess-3" />));
// Wait for preview to load (use role to avoid ambiguity with paging panel)
await waitFor(() => expect(screen.getAllByRole("gridcell")).not.toHaveLength(0));
const btn = screen.getByRole("button", { name: /export csv/i });
await user.click(btn);
await waitFor(() => expect(exportCalled).toBe(true));
});
// (d) selecting "tutti" drives sqlPreview with the large/unlimited limit
test("(d) selecting tutti re-fetches preview with the large limit", async () => {
const limits: unknown[] = [];
server.use(
http.post(`${BASE}/sessions/sess-4/sql/preview`, async ({ request }) => {
const body = (await request.json()) as { limit?: number };
limits.push(body.limit);
return HttpResponse.json({
columns: ["id"],
rows: [[1], [2]],
execution_ms: 3,
truncated: false,
limit: body.limit ?? 10,
offset: 0,
});
})
);
const user = userEvent.setup();
render(wrap(<ResultsPanel sessionId="sess-4" />));
// Initial fetch uses limit 10
await waitFor(() => expect(limits).toContain(10));
// Select "all"
const select = screen.getByLabelText(/rows to display/i);
await user.selectOptions(select, "all");
// A re-fetch with the large/unlimited limit must occur
await waitFor(() => expect(limits.some((l) => (l as number) > 10)).toBe(true));
});