import { render, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { App } from "../../src/App"; async function renderReady() { vi.stubGlobal( "fetch", vi.fn(async () => new Response("Not found", { status: 404 })), ); render(); await screen.findByText(/Parsed as JSON/iu, {}, { timeout: 2_000 }); } describe("Data Tools workbench", () => { it("renders the local shell and exact JSON summary", async () => { await renderReady(); expect(screen.getAllByRole("heading", { name: "Data Tools" })).toHaveLength( 2, ); expect(screen.getByText("Browser-local")).toBeVisible(); expect(screen.getByText("native")).toBeVisible(); }); it("keeps the previous model while a replacement is invalid", async () => { await renderReady(); const user = userEvent.setup(); const editor = screen.getByTestId("source-editor"); await user.clear(editor); await user.type(editor, '{{"broken":'); await screen.findByText( /Unexpected|invalid|property/iu, {}, { timeout: 2_000 }, ); await user.click(screen.getByRole("tab", { name: /Tree/iu })); expect(screen.getByText("project")).toBeVisible(); }); it("runs safe wildcard queries", async () => { await renderReady(); const user = userEvent.setup(); await user.click(screen.getByRole("tab", { name: /Query/iu })); await user.selectOptions(screen.getByLabelText("Query syntax"), "path"); expect(screen.getByText("4 matches")).toBeVisible(); expect(screen.getByText("detect")).toBeVisible(); }); it("converts to CSV and displays disclosure", async () => { await renderReady(); const user = userEvent.setup(); await user.click(screen.getByRole("tab", { name: /Convert/iu })); await user.selectOptions(screen.getByLabelText("Output format"), "csv"); await waitFor(() => expect( (screen.getByTestId("conversion-output") as HTMLTextAreaElement).value, ).toContain("Key,Value"), ); expect( screen.getByRole("heading", { name: "Conversion report" }), ).toBeVisible(); }); });