bstein-dev-home/testing/frontend/unit/mermaid-card.spec.js

89 lines
2.5 KiB
JavaScript

import { afterEach, describe, expect, it, jest } from "@jest/globals";
import { flushPromises, mount } from "@vue/test-utils";
import MermaidCard from "../../../frontend/src/components/MermaidCard.vue";
import mermaid from "mermaid";
describe("MermaidCard", () => {
afterEach(() => {
jest.restoreAllMocks();
document.body.style.overflow = "";
});
it("renders diagrams and handles the fullscreen overlay lifecycle", async () => {
const initSpy = jest.spyOn(mermaid, "initialize");
const renderSpy = jest.spyOn(mermaid, "render").mockResolvedValue({
svg: "<svg><g>ok</g></svg>",
});
const wrapper = mount(MermaidCard, {
props: {
title: "Network",
description: "Topology",
diagram: "graph TD;A-->B;",
cardId: "network-card",
},
});
await flushPromises();
expect(initSpy).toHaveBeenCalledTimes(1);
expect(renderSpy).toHaveBeenCalled();
expect(wrapper.html()).toContain("<svg");
await wrapper.find(".diagram").trigger("click");
expect(wrapper.find(".overlay").exists()).toBe(true);
expect(document.body.style.overflow).toBe("hidden");
window.dispatchEvent(new KeyboardEvent("keydown", { key: "Escape" }));
await flushPromises();
expect(wrapper.find(".overlay").exists()).toBe(false);
expect(document.body.style.overflow).toBe("");
await wrapper.unmount();
});
it("renders Mermaid errors and re-renders when the diagram changes", async () => {
const renderSpy = jest
.spyOn(mermaid, "render")
.mockRejectedValueOnce(new Error("invalid diagram"))
.mockResolvedValueOnce({ svg: "<svg><text>recovered</text></svg>" });
const wrapper = mount(MermaidCard, {
props: {
title: "Pipeline",
description: "Initial",
diagram: "graph TD;BROKEN",
},
});
await flushPromises();
expect(wrapper.text()).toContain("Mermaid render error");
await wrapper.setProps({ diagram: "graph TD;X-->Y;" });
await flushPromises();
expect(renderSpy).toHaveBeenCalledTimes(2);
expect(wrapper.html()).toContain("<svg");
await wrapper.unmount();
expect(document.body.style.overflow).toBe("");
});
it("no-ops rendering when no diagram is provided", async () => {
const renderSpy = jest.spyOn(mermaid, "render");
const wrapper = mount(MermaidCard, {
props: {
title: "Empty",
description: "No diagram yet",
diagram: "",
},
});
await flushPromises();
expect(renderSpy).not.toHaveBeenCalled();
await wrapper.unmount();
});
});