1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
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(<DrawioView xml="<mxfile/>" />);
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(<DrawioView xml="<mxfile><diagram/></mxfile>" timeoutMs={60000} />);
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: "<mxfile><diagram/></mxfile>",
autosave: 0,
});
expect(screen.queryByText("loading viewer…")).toBeNull();
expect(frame.hidden).toBe(false);
});
it("ignores messages from other windows", () => {
render(<DrawioView xml="<mxfile/>" timeoutMs={60000} />);
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(<DrawioView xml="<mxfile/>" timeoutMs={20} />);
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);
});
});
|