import { act, fireEvent, render, screen } from "@testing-library/react"; import type { LiveQueryEvent } from "@/lib/types"; import { FakeEventSource } from "./fakeEventSource"; import LiveLogPage from "./LiveLogPage"; function frame(ts: number, domain: string, overrides: Partial = {}): { data: string } { const payload: LiveQueryEvent = { ts, domain, client_ip: "192.0.2.10", qtype: 1, blocked: false, block_reason: "", response_time_us: 500, cache_hit: true, upstream: "", ...overrides, }; return { data: JSON.stringify(payload) }; } function renderPage() { const sources: FakeEventSource[] = []; const createEventSource = (url: string) => { const es = new FakeEventSource(url); sources.push(es); return es; }; render(); return sources; } test("streams rows, flags blocked ones, and freezes the display", () => { const sources = renderPage(); expect(screen.getByText("Connecting…")).toBeTruthy(); act(() => sources[0]!.emit("open")); expect(screen.getByRole("status", { name: "Live" })).toBeTruthy(); expect(screen.getByText("Waiting for queries…")).toBeTruthy(); act(() => { sources[0]!.emit("query", frame(1000, "ok.example")); sources[0]!.emit( "query", frame(1001, "ads.example", { blocked: true, block_reason: "blocklist:stevenblack", qtype: 28 }), ); }); expect(screen.getByText("ok.example")).toBeTruthy(); expect(screen.getByText("Blocked")).toBeTruthy(); expect(screen.getByText("blocklist:stevenblack")).toBeTruthy(); expect(screen.getByText("AAAA")).toBeTruthy(); const blockedRow = screen.getByText("ads.example").closest("tr"); expect(blockedRow?.className).toContain("bg-red-50"); const freeze = screen.getByRole("button", { name: "Freeze" }); fireEvent.click(freeze); expect(freeze.getAttribute("aria-pressed")).toBe("true"); act(() => sources[0]!.emit("query", frame(1002, "later.example"))); expect(screen.queryByText("later.example")).toBeNull(); expect(screen.getByText(/3 in buffer/)).toBeTruthy(); fireEvent.click(screen.getByRole("button", { name: "Resume" })); expect(screen.getByText("later.example")).toBeTruthy(); }); test("repeated connection failures show the viewer-cap state with a retry button", () => { const sources = renderPage(); act(() => { sources[0]!.emit("error"); sources[0]!.emit("error"); sources[0]!.emit("error"); }); expect(screen.getByRole("alert").textContent).toContain("too many live viewers"); fireEvent.click(screen.getByRole("button", { name: "Retry" })); expect(sources).toHaveLength(2); expect(screen.getByText("Connecting…")).toBeTruthy(); });