Skip to content
File

Blob: tests/client/sites/entrypoints/browser.dom.test.ts

typescript78 lines
1import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2 
3const hydrateRoot = vi.fn();
4 
5vi.mock("react-dom/client", () => ({
6 hydrateRoot,
7}));
8 
9describe("Sites entry bootstrap", () => {
10 beforeEach(() => {
11 document.body.innerHTML = "";
12 hydrateRoot.mockReset();
13 vi.resetModules();
14 });
15 
16 afterEach(() => {
17 document.body.innerHTML = "";
18 vi.restoreAllMocks();
19 });
20 
21 it("hydrates each known island host", async () => {
22 document.body.innerHTML = `
23 <div data-island="sites-image">
24 <template data-island-props>${JSON.stringify({ src: "/_assets/1/x" })}</template>
25 <div data-island-root></div>
26 </div>
27 <div data-island="copy-code">
28 <template data-island-props>{}</template>
29 <div data-island-root></div>
30 </div>
31 <div data-island="site-outline-controller">
32 <template data-island-props>${JSON.stringify({ items: [] })}</template>
33 <div data-island-root></div>
34 </div>
35 `;
36 
37 const { bootstrapIslands } = await import("@/client/sites/hydrate");
38 await bootstrapIslands();
39 
40 expect(hydrateRoot).toHaveBeenCalledTimes(3);
41 
42 for (const host of document.querySelectorAll<HTMLElement>("[data-island]")) {
43 expect(host.dataset.islandHydrated).toBe("true");
44 }
45 });
46 
47 it("skips hosts already marked as hydrated", async () => {
48 document.body.innerHTML = `
49 <div data-island="copy-code" data-island-hydrated="true">
50 <template data-island-props>{}</template>
51 <div data-island-root></div>
52 </div>
53 `;
54 
55 const { bootstrapIslands } = await import("@/client/sites/hydrate");
56 await bootstrapIslands();
57 
58 expect(hydrateRoot).not.toHaveBeenCalled();
59 });
60 
61 it("ignores unknown island names and malformed props without throwing", async () => {
62 document.body.innerHTML = `
63 <div data-island="not-an-island">
64 <template data-island-props>{}</template>
65 <div data-island-root></div>
66 </div>
67 <div data-island="sites-image">
68 <template data-island-props>{not valid json}</template>
69 <div data-island-root></div>
70 </div>
71 `;
72 
73 const { bootstrapIslands } = await import("@/client/sites/hydrate");
74 await expect(bootstrapIslands()).resolves.toBeUndefined();
75 expect(hydrateRoot).not.toHaveBeenCalled();
76 });
77});