import { describe, it, expect, vi } from "vitest"; import { render, screen, fireEvent, within } from "@testing-library/react"; import { PacketTableRow } from "../../../src/features/packets/PacketTableRow"; import type { PacketSummary } from "../../../src/types/api"; const pkt = (over: Partial = {}): PacketSummary => ({ packetHash: "AA11BB22", payloadType: 1, payloadTypeName: "ADVERT", routeType: 1, routeTypeName: "FLOOD", firstHeardAt: 1700000000, lastHeardAt: 1700000000, observationCount: 3, ...over, }); describe("PacketTableRow", () => { it("exposes one button carrying the expansion state", () => { render( {}} />); const btn = screen.getByRole("button"); expect(btn).toHaveAttribute("aria-expanded", "false"); }); it("toggles on click", () => { const onToggle = vi.fn(); render(); fireEvent.click(screen.getByRole("button")); expect(onToggle).toHaveBeenCalledOnce(); }); it("renders line 2 even when there is no path data, so row height is constant", () => { render( {}} />); expect(screen.getAllByText("n/a")).toHaveLength(3); }); it("falls back to n/a in the observer and IATA cells when there is no observer", () => { render( {}} />); const line1 = within(screen.getByRole("button")); expect(line1.getAllByText("n/a")).toHaveLength(2); }); it("falls back to the observer id when there is no display name", () => { render( {}} />); expect(screen.getByText("abcdef12")).toBeInTheDocument(); expect(screen.getByText("YVR")).toBeInTheDocument(); }); it("prefers the observer display name over the id", () => { render( {}} />); expect(screen.getByText("Cypress Peak")).toBeInTheDocument(); expect(screen.queryByText("abcdef12")).not.toBeInTheDocument(); }); it("reflects the expanded state on the button and chevron", () => { render( {}} />); expect(screen.getByRole("button")).toHaveAttribute("aria-expanded", "true"); expect(screen.getByText("›")).toHaveClass("rotate-90"); }); it("marks a fresh row with the pulse class", () => { const { container } = render( {}} />); expect(container.querySelector(".packet-fresh")).toBeInTheDocument(); }); it("renders a scope tag when the packet has a scope", () => { render( {}} />); expect(screen.getByText("#bc")).toBeInTheDocument(); }); it("falls back to the raw payload type name for an unrecognized payload type", () => { render( {}} />); expect(screen.getByText("CUSTOM_99")).toBeInTheDocument(); }); it("falls back to Unknown when routeTypeName is empty", () => { render( {}} />); expect(screen.getByText("Unknown")).toBeInTheDocument(); }); });