import { describe, it, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import { PacketPathLine } from "../../../src/features/packets/PacketPathLine"; import type { PacketSummary } from "../../../src/types/api"; const pkt = (over: Partial = {}): PacketSummary => ({ packetHash: "AA11", payloadType: 1, payloadTypeName: "ADVERT", routeType: 1, routeTypeName: "FLOOD", firstHeardAt: 0, lastHeardAt: 0, observationCount: 1, ...over, }); describe("PacketPathLine", () => { it("renders a single n/a when there is nothing to show", () => { render(); expect(screen.getByText("n/a")).toBeInTheDocument(); }); it("renders hop label, hex chips and the overflow count", () => { render(); expect(screen.getByText("14 hops")).toBeInTheDocument(); expect(screen.getByText("00")).toBeInTheDocument(); expect(screen.getByText("+9 more")).toBeInTheDocument(); }); it("tints an ambiguous hop with the warn token", () => { render(); expect(screen.getByText("Raven").className).toContain("text-warn"); }); it("tints a high-confidence hop with the green token", () => { render(); expect(screen.getByText("Falcon").className).toContain("text-green"); }); it("renders both endpoints with the arrow glyph between them", () => { render(); expect(screen.getByText("SrcNode")).toBeInTheDocument(); expect(screen.getByText("DstNode")).toBeInTheDocument(); expect(screen.getByText("→")).toBeInTheDocument(); }); it("shows n/a for a missing endpoint while the present one still renders", () => { render(); expect(screen.getByText("SrcNode")).toBeInTheDocument(); expect(screen.getByText("n/a")).toBeInTheDocument(); }); it("omits the endpoint block entirely when both endpoints are absent", () => { render(); expect(screen.queryByText("→")).not.toBeInTheDocument(); }); it("renders a bare ? for a single unresolved hop", () => { render(); expect(screen.getByText("?")).toBeInTheDocument(); }); it("collapses a run of unresolved hops into a single ?×N chip", () => { render(); expect(screen.getByText("?×3")).toBeInTheDocument(); }); });