history.test.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import React from "react";
  2. import { render } from "./test-utils";
  3. import ExcalidrawApp from "../excalidraw-app";
  4. import { UI } from "./helpers/ui";
  5. import { API } from "./helpers/api";
  6. import { getDefaultAppState } from "../appState";
  7. import { waitFor } from "@testing-library/react";
  8. import { createUndoAction, createRedoAction } from "../actions/actionHistory";
  9. import { EXPORT_DATA_TYPES } from "../constants";
  10. const { h } = window;
  11. describe("history", () => {
  12. it("initializing scene should end up with single history entry", async () => {
  13. await render(<ExcalidrawApp />, {
  14. localStorageData: {
  15. elements: [API.createElement({ type: "rectangle", id: "A" })],
  16. appState: {
  17. zenModeEnabled: true,
  18. },
  19. },
  20. });
  21. await waitFor(() => expect(h.state.zenModeEnabled).toBe(true));
  22. await waitFor(() =>
  23. expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]),
  24. );
  25. const undoAction = createUndoAction(h.history);
  26. const redoAction = createRedoAction(h.history);
  27. h.app.actionManager.executeAction(undoAction);
  28. expect(h.elements).toEqual([
  29. expect.objectContaining({ id: "A", isDeleted: false }),
  30. ]);
  31. const rectangle = UI.createElement("rectangle");
  32. expect(h.elements).toEqual([
  33. expect.objectContaining({ id: "A" }),
  34. expect.objectContaining({ id: rectangle.id }),
  35. ]);
  36. h.app.actionManager.executeAction(undoAction);
  37. expect(h.elements).toEqual([
  38. expect.objectContaining({ id: "A", isDeleted: false }),
  39. expect.objectContaining({ id: rectangle.id, isDeleted: true }),
  40. ]);
  41. // noop
  42. h.app.actionManager.executeAction(undoAction);
  43. expect(h.elements).toEqual([
  44. expect.objectContaining({ id: "A", isDeleted: false }),
  45. expect.objectContaining({ id: rectangle.id, isDeleted: true }),
  46. ]);
  47. expect(API.getStateHistory().length).toBe(1);
  48. h.app.actionManager.executeAction(redoAction);
  49. expect(h.elements).toEqual([
  50. expect.objectContaining({ id: "A", isDeleted: false }),
  51. expect.objectContaining({ id: rectangle.id, isDeleted: false }),
  52. ]);
  53. expect(API.getStateHistory().length).toBe(2);
  54. });
  55. it("scene import via drag&drop should create new history entry", async () => {
  56. await render(<ExcalidrawApp />, {
  57. localStorageData: {
  58. elements: [API.createElement({ type: "rectangle", id: "A" })],
  59. appState: {
  60. viewBackgroundColor: "#FFF",
  61. },
  62. },
  63. });
  64. await waitFor(() => expect(h.state.viewBackgroundColor).toBe("#FFF"));
  65. await waitFor(() =>
  66. expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]),
  67. );
  68. API.drop(
  69. new Blob(
  70. [
  71. JSON.stringify({
  72. type: EXPORT_DATA_TYPES.excalidraw,
  73. appState: {
  74. ...getDefaultAppState(),
  75. viewBackgroundColor: "#000",
  76. },
  77. elements: [API.createElement({ type: "rectangle", id: "B" })],
  78. }),
  79. ],
  80. { type: "application/json" },
  81. ),
  82. );
  83. await waitFor(() => expect(API.getStateHistory().length).toBe(2));
  84. expect(h.state.viewBackgroundColor).toBe("#000");
  85. expect(h.elements).toEqual([
  86. expect.objectContaining({ id: "B", isDeleted: false }),
  87. ]);
  88. const undoAction = createUndoAction(h.history);
  89. const redoAction = createRedoAction(h.history);
  90. h.app.actionManager.executeAction(undoAction);
  91. expect(h.elements).toEqual([
  92. expect.objectContaining({ id: "A", isDeleted: false }),
  93. expect.objectContaining({ id: "B", isDeleted: true }),
  94. ]);
  95. expect(h.state.viewBackgroundColor).toBe("#FFF");
  96. h.app.actionManager.executeAction(redoAction);
  97. expect(h.state.viewBackgroundColor).toBe("#000");
  98. expect(h.elements).toEqual([
  99. expect.objectContaining({ id: "B", isDeleted: false }),
  100. expect.objectContaining({ id: "A", isDeleted: true }),
  101. ]);
  102. });
  103. });