|
@@ -0,0 +1,127 @@
|
|
|
+import React from "react";
|
|
|
+import { render, GlobalTestState } from "./test-utils";
|
|
|
+import App from "../components/App";
|
|
|
+import { UI } from "./helpers/ui";
|
|
|
+import { API } from "./helpers/api";
|
|
|
+import { getDefaultAppState } from "../appState";
|
|
|
+import { waitFor, fireEvent, createEvent } from "@testing-library/react";
|
|
|
+import { createUndoAction, createRedoAction } from "../actions/actionHistory";
|
|
|
+
|
|
|
+const { h } = window;
|
|
|
+
|
|
|
+describe("history", () => {
|
|
|
+ it("initializing scene should end up with single history entry", async () => {
|
|
|
+ render(
|
|
|
+ <App
|
|
|
+ initialData={{
|
|
|
+ appState: {
|
|
|
+ ...getDefaultAppState(),
|
|
|
+ zenModeEnabled: true,
|
|
|
+ },
|
|
|
+ elements: [API.createElement({ type: "rectangle", id: "A" })],
|
|
|
+ }}
|
|
|
+ />,
|
|
|
+ );
|
|
|
+
|
|
|
+ await waitFor(() => expect(h.state.zenModeEnabled).toBe(true));
|
|
|
+ await waitFor(() =>
|
|
|
+ expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]),
|
|
|
+ );
|
|
|
+ const undoAction = createUndoAction(h.history);
|
|
|
+ const redoAction = createRedoAction(h.history);
|
|
|
+ h.app.actionManager.executeAction(undoAction);
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: false }),
|
|
|
+ ]);
|
|
|
+ const rectangle = UI.createElement("rectangle");
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A" }),
|
|
|
+ expect.objectContaining({ id: rectangle.id }),
|
|
|
+ ]);
|
|
|
+ h.app.actionManager.executeAction(undoAction);
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: false }),
|
|
|
+ expect.objectContaining({ id: rectangle.id, isDeleted: true }),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // noop
|
|
|
+ h.app.actionManager.executeAction(undoAction);
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: false }),
|
|
|
+ expect.objectContaining({ id: rectangle.id, isDeleted: true }),
|
|
|
+ ]);
|
|
|
+ expect(API.getStateHistory().length).toBe(1);
|
|
|
+
|
|
|
+ h.app.actionManager.executeAction(redoAction);
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: false }),
|
|
|
+ expect.objectContaining({ id: rectangle.id, isDeleted: false }),
|
|
|
+ ]);
|
|
|
+ expect(API.getStateHistory().length).toBe(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ it("scene import via drag&drop should create new history entry", async () => {
|
|
|
+ render(
|
|
|
+ <App
|
|
|
+ initialData={{
|
|
|
+ appState: {
|
|
|
+ ...getDefaultAppState(),
|
|
|
+ viewBackgroundColor: "#FFF",
|
|
|
+ },
|
|
|
+ elements: [API.createElement({ type: "rectangle", id: "A" })],
|
|
|
+ }}
|
|
|
+ />,
|
|
|
+ );
|
|
|
+
|
|
|
+ await waitFor(() => expect(h.state.viewBackgroundColor).toBe("#FFF"));
|
|
|
+ await waitFor(() =>
|
|
|
+ expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]),
|
|
|
+ );
|
|
|
+ const fileDropEvent = createEvent.drop(GlobalTestState.canvas);
|
|
|
+ const file = new Blob(
|
|
|
+ [
|
|
|
+ JSON.stringify({
|
|
|
+ type: "excalidraw",
|
|
|
+ appState: {
|
|
|
+ ...getDefaultAppState(),
|
|
|
+ viewBackgroundColor: "#000",
|
|
|
+ },
|
|
|
+ elements: [API.createElement({ type: "rectangle", id: "B" })],
|
|
|
+ }),
|
|
|
+ ],
|
|
|
+ {
|
|
|
+ type: "application/json",
|
|
|
+ },
|
|
|
+ );
|
|
|
+ Object.defineProperty(fileDropEvent, "dataTransfer", {
|
|
|
+ value: {
|
|
|
+ files: [file],
|
|
|
+ getData: (_type: string) => {
|
|
|
+ return "";
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+ fireEvent(GlobalTestState.canvas, fileDropEvent);
|
|
|
+
|
|
|
+ await waitFor(() => expect(API.getStateHistory().length).toBe(2));
|
|
|
+ expect(h.state.viewBackgroundColor).toBe("#000");
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "B", isDeleted: false }),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ const undoAction = createUndoAction(h.history);
|
|
|
+ const redoAction = createRedoAction(h.history);
|
|
|
+ h.app.actionManager.executeAction(undoAction);
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: false }),
|
|
|
+ expect.objectContaining({ id: "B", isDeleted: true }),
|
|
|
+ ]);
|
|
|
+ expect(h.state.viewBackgroundColor).toBe("#FFF");
|
|
|
+ h.app.actionManager.executeAction(redoAction);
|
|
|
+ expect(h.state.viewBackgroundColor).toBe("#000");
|
|
|
+ expect(h.elements).toEqual([
|
|
|
+ expect.objectContaining({ id: "B", isDeleted: false }),
|
|
|
+ expect.objectContaining({ id: "A", isDeleted: true }),
|
|
|
+ ]);
|
|
|
+ });
|
|
|
+});
|