1import { EnvironmentId, ThreadId } from "@t3tools/contracts";
2import { renderToStaticMarkup } from "react-dom/server";
3import { describe, expect, it, vi } from "vite-plus/test";
4
5const mocks = vi.hoisted(() => ({
6 servers: [] as Array<{
7 host: string;
8 port: number;
9 url: string;
10 requestedUrl: string;
11 processName: string | null;
12 pid: number | null;
13 terminal: null;
14 source: "scanner";
15 }>,
16}));
17
18vi.mock("./useDiscoveredLocalServers", () => ({
19 useDiscoveredLocalServers: () => mocks.servers,
20}));
21vi.mock("./PreviewFaviconIcon", () => ({
22 PreviewFaviconIcon: () => <span data-favicon-icon />,
23}));
24
25import { PreviewEmptyState } from "./PreviewEmptyState";
26
27const environmentId = EnvironmentId.make("env-1");
28const threadRef = { environmentId, threadId: ThreadId.make("thread-1") };
29
30function server(port: number) {
31 return {
32 host: "localhost",
33 port,
34 url: `http://localhost:${port}`,
35 requestedUrl: `http://localhost:${port}`,
36 processName: "node",
37 pid: 1,
38 terminal: null,
39 source: "scanner" as const,
40 };
41}
42
43function render(recentEntries: Array<{ url: string; lastVisitedAt: number; title?: string }>) {
44 return renderToStaticMarkup(
45 <PreviewEmptyState
46 threadRef={threadRef}
47 environmentId={environmentId}
48 recentEntries={recentEntries}
49 onRemoveRecent={() => undefined}
50 onOpenUrl={() => undefined}
51 />,
52 );
53}
54
55describe("PreviewEmptyState", () => {
56 it("renders a history entry in both groups when its host:port matches a live server", () => {
57 mocks.servers = [server(5173)];
58 const html = render([
59 { url: "https://myapp.test/admin#users", lastVisitedAt: Date.now(), title: "Admin" },
60 { url: "http://localhost:5173/", lastVisitedAt: Date.now(), title: "Recent Local" },
61 ]);
62 expect(html).toContain("Recently used");
63 expect(html).toContain("Local servers");
64 expect(html).toContain("myapp.test/admin#users");
65 expect(html).toContain("Admin");
66 expect(html).toContain("Recent Local");
67 expect(html).toContain("node");
68 });
69
70 it("renders only the recents group when no servers are found", () => {
71 mocks.servers = [];
72 const html = render([{ url: "https://myapp.test/", lastVisitedAt: 0 }]);
73 expect(html).toContain("Recently used");
74 expect(html).not.toContain("Local servers");
75 });
76
77 it("keeps the original empty state when both groups are empty", () => {
78 mocks.servers = [];
79 const html = render([]);
80 expect(html).toContain("No preview yet");
81 });
82
83 it("renders an out-of-range lastVisitedAt entry without throwing", () => {
84 mocks.servers = [];
85 let html = "";
86 expect(() => {
87 html = render([{ url: "https://myapp.test/", lastVisitedAt: 1e20 }]);
88 }).not.toThrow();
89 expect(html).toContain("myapp.test");
90 expect(html).toContain("Remove");
91 });
92});