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);
});
});