Add tests

zsviczian-mermaid-store-diagram
Aakansha Doshi 1 year ago
parent 17accffee3
commit 7f6789780d

@ -15,7 +15,7 @@ import Spinner from "./Spinner";
import "./MermaidToExcalidraw.scss";
import { MermaidToExcalidrawResult } from "@excalidraw/mermaid-to-excalidraw/dist/interfaces";
import { MermaidOptions } from "@excalidraw/mermaid-to-excalidraw";
import type { MermaidOptions } from "@excalidraw/mermaid-to-excalidraw";
import { t } from "../i18n";
import Trans from "./Trans";
@ -49,6 +49,7 @@ const importMermaidDataFromStorage = () => {
const ErrorComp = ({ error }: { error: string }) => {
return (
<div
data-testid="mermaid-error"
style={{
color: "red",
fontWeight: 800,
@ -185,6 +186,7 @@ const MermaidToExcalidraw = () => {
return (
<Dialog
className="dialog-mermaid"
onCloseRequest={onClose}
title={
<>

@ -0,0 +1,178 @@
import {
act,
fireEvent,
getTextEditor,
render,
updateTextEditor,
} from "./test-utils";
import { Excalidraw } from "../packages/excalidraw/index";
import React from "react";
import { expect, vi } from "vitest";
import * as MermaidToExcalidraw from "@excalidraw/mermaid-to-excalidraw";
vi.mock("@excalidraw/mermaid-to-excalidraw", async (importActual) => {
const module = (await importActual()) as any;
return {
__esModule: true,
...module,
};
});
const parseMermaidToExcalidrawSpy = vi.spyOn(
MermaidToExcalidraw,
"parseMermaidToExcalidraw",
);
parseMermaidToExcalidrawSpy.mockImplementation(
async (
definition: string,
options?: MermaidToExcalidraw.MermaidOptions | undefined,
) => {
const firstLine = definition.split("\n")[0];
return new Promise((resolve, reject) => {
if (firstLine === "flowchart TD") {
resolve({
elements: [
{
id: "Start",
type: "rectangle",
groupIds: [],
x: 0,
y: 0,
width: 69.703125,
height: 44,
strokeWidth: 2,
label: {
groupIds: [],
text: "Start",
fontSize: 20,
},
link: null,
},
{
id: "Stop",
type: "rectangle",
groupIds: [],
x: 2.7109375,
y: 94,
width: 64.28125,
height: 44,
strokeWidth: 2,
label: {
groupIds: [],
text: "Stop",
fontSize: 20,
},
link: null,
},
{
id: "Start_Stop",
type: "arrow",
groupIds: [],
x: 34.852,
y: 44,
strokeWidth: 2,
points: [
[0, 0],
[0, 50],
],
roundness: {
type: 2,
},
start: {
id: "Start",
},
end: {
id: "Stop",
},
},
],
});
} else {
reject(new Error("ERROR"));
}
});
},
);
vi.spyOn(React, "useRef").mockReturnValue({
current: {
parseMermaidToExcalidraw: parseMermaidToExcalidrawSpy,
},
});
describe("Test <MermaidToExcalidraw/>", () => {
beforeEach(async () => {
await render(
<Excalidraw
initialData={{
appState: {
activeTool: {
type: "mermaid",
lastActiveTool: null,
locked: false,
customType: null,
},
},
}}
/>,
);
});
it("should open mermaid popup when active tool is mermaid", async () => {
const dialog = document.querySelector(".dialog-mermaid")!;
expect(dialog.outerHTML).toMatchSnapshot();
});
it("should close the popup and set the tool to selection when close button clicked", () => {
const dialog = document.querySelector(".dialog-mermaid")!;
const closeBtn = dialog.querySelector(".Dialog__close")!;
fireEvent.click(closeBtn);
expect(document.querySelector(".dialog-mermaid")).toBe(null);
expect(window.h.state.activeTool).toStrictEqual({
customType: null,
lastActiveTool: null,
locked: false,
type: "selection",
});
});
it("should show error in preview when mermaid library throws error", async () => {
const dialog = document.querySelector(".dialog-mermaid")!;
const selector = ".mermaid-to-excalidraw-wrapper-text textarea";
const editor = getTextEditor(selector);
expect(dialog.querySelector('[data-testid="mermaid-error"]')).toBeNull();
expect(editor.textContent).toMatchInlineSnapshot(`
"flowchart TD
A[Christmas] -->|Get money| B(Go shopping)
B --> C{Let me think}
C -->|One| D[Laptop]
C -->|Two| E[iPhone]
C -->|Three| F[test]"
`);
await act(async () => {
updateTextEditor(editor, "flowchart TD1");
await new Promise((cb) => setTimeout(cb, 0));
});
expect(getTextEditor(selector).textContent).toBe("flowchart TD1");
expect(dialog.querySelector('[data-testid="mermaid-error"]'))
.toMatchInlineSnapshot(`
<div
data-testid="mermaid-error"
style="color: red; font-weight: 800; font-size: 30px; word-break: break-word; overflow: auto; max-height: 100%; text-align: center;"
>
Error!
<p
style="font-size: 18px; font-weight: 600;"
>
ERROR
</p>
</div>
`);
});
});

@ -0,0 +1,10 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`Test <MermaidToExcalidraw/> > should open mermaid popup when active tool is mermaid 1`] = `
"<div class=\\"Modal Dialog dialog-mermaid\\" role=\\"dialog\\" aria-modal=\\"true\\" aria-labelledby=\\"dialog-title\\" data-prevent-outside-click=\\"true\\"><div class=\\"Modal__background\\"></div><div class=\\"Modal__content\\" style=\\"--max-width: 800px;\\" tabindex=\\"0\\"><div class=\\"Island\\"><h2 id=\\"test-id-dialog-title\\" class=\\"Dialog__title\\"><span class=\\"Dialog__titleContent\\"><p style=\\"margin-bottom: 5px; margin-top: 2px;\\">Mermaid to Excalidraw</p><span style=\\"font-size: 15px; font-style: italic; font-weight: 500;\\">Currently only <a href=\\"https://mermaid.js.org/syntax/flowchart.html\\">flowcharts</a> are supported. The other types will be rendered as image in Excalidraw.<br></span></span></h2><button class=\\"Dialog__close\\" title=\\"Close\\" aria-label=\\"Close\\"><svg aria-hidden=\\"true\\" focusable=\\"false\\" role=\\"img\\" viewBox=\\"0 0 20 20\\" class=\\"\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"><g clip-path=\\"url(#a)\\" stroke=\\"currentColor\\" stroke-width=\\"1.25\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"><path d=\\"M15 5 5 15M5 5l10 10\\"></path></g><defs><clipPath id=\\"a\\"><path fill=\\"#fff\\" d=\\"M0 0h20v20H0z\\"></path></clipPath></defs></svg></button><div class=\\"Dialog__content\\"><div class=\\"mermaid-to-excalidraw-wrapper\\"><div class=\\"mermaid-to-excalidraw-wrapper-text\\" style=\\"display: flex; flex-direction: column;\\"><label>Mermaid Syntax</label><textarea style=\\"padding: 0.85rem; border-radius: 8px; border: 1px solid #e4e4eb; white-space: pre-wrap;\\">flowchart TD
A[Christmas] --&gt;|Get money| B(Go shopping)
B --&gt; C{Let me think}
C --&gt;|One| D[Laptop]
C --&gt;|Two| E[iPhone]
C --&gt;|Three| F[test]</textarea></div><div class=\\"mermaid-to-excalidraw-wrapper-preview\\" style=\\"display: flex; flex-direction: column;\\"><label>Preview</label><div class=\\"mermaid-to-excalidraw-wrapper-preview-canvas\\"><div></div></div><button type=\\"button\\" class=\\"excalidraw-button mermaid-to-excalidraw-wrapper-preview-insert\\">Insert<span style=\\"padding-left: 8px; display: flex;\\"><svg aria-hidden=\\"true\\" focusable=\\"false\\" role=\\"img\\" viewBox=\\"0 0 20 20\\" class=\\"\\"><path d=\\"M4.16602 10H15.8327\\" stroke=\\"white\\" stroke-width=\\"1.25\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"></path><path d=\\"M12.5 13.3333L15.8333 10\\" stroke=\\"white\\" stroke-width=\\"1.25\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"></path><path d=\\"M12.5 6.66666L15.8333 9.99999\\" stroke=\\"white\\" stroke-width=\\"1.25\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"></path></svg></span></button></div></div></div></div></div></div>"
`;

@ -265,3 +265,15 @@ expect.extend({
};
},
});
export const updateTextEditor = (
editor: HTMLTextAreaElement,
value: string,
) => {
fireEvent.change(editor, { target: { value } });
editor.dispatchEvent(new Event("input"));
};
export const getTextEditor = (selector: string) => {
return document.querySelector(selector) as HTMLTextAreaElement;
};

Loading…
Cancel
Save