import { act, render, screen } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { DRAWIO_EMBED_URL, DrawioView } from "./DrawioView"; /** viewerSays simulates one postMessage frame coming from the iframe. */ function viewerSays(frame: HTMLIFrameElement, payload: unknown) { act(() => { window.dispatchEvent( new MessageEvent("message", { data: typeof payload === "string" ? payload : JSON.stringify(payload), source: frame.contentWindow, }), ); }); } describe("DrawioView", () => { it("points the iframe at the read-only embed viewer", () => { render(); const frame = screen.getByTitle("draw.io diagram") as HTMLIFrameElement; expect(frame.getAttribute("src")).toBe(DRAWIO_EMBED_URL); expect(DRAWIO_EMBED_URL).toContain("embed.diagrams.net"); expect(DRAWIO_EMBED_URL).toContain("proto=json"); expect(screen.getByText("loading viewer…")).toBeDefined(); }); it("answers the viewer's init with a load action carrying the XML", () => { render(); const frame = screen.getByTitle("draw.io diagram") as HTMLIFrameElement; const target = frame.contentWindow; if (!target) { throw new Error("jsdom iframe has no contentWindow"); } const posted = vi.spyOn(target, "postMessage"); viewerSays(frame, "not json"); expect(posted).not.toHaveBeenCalled(); viewerSays(frame, { event: "init" }); expect(posted).toHaveBeenCalledTimes(1); expect(JSON.parse(String(posted.mock.calls[0][0]))).toEqual({ action: "load", xml: "", autosave: 0, }); expect(screen.queryByText("loading viewer…")).toBeNull(); expect(frame.hidden).toBe(false); }); it("ignores messages from other windows", () => { render(); act(() => { window.dispatchEvent( new MessageEvent("message", { data: JSON.stringify({ event: "init" }), source: window, }), ); }); expect(screen.getByText("loading viewer…")).toBeDefined(); }); it("falls back to a notice when the viewer never answers", async () => { render(); await act(async () => { await new Promise((resolve) => setTimeout(resolve, 60)); }); expect(screen.getByText(/is not reachable/)).toBeDefined(); expect( (screen.getByTitle("draw.io diagram") as HTMLIFrameElement).hidden, ).toBe(true); }); });