collab.test.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { vi } from "vitest";
  2. import {
  3. render,
  4. updateSceneData,
  5. waitFor,
  6. } from "../../packages/excalidraw/tests/test-utils";
  7. import ExcalidrawApp from "../App";
  8. import { API } from "../../packages/excalidraw/tests/helpers/api";
  9. import { createUndoAction } from "../../packages/excalidraw/actions/actionHistory";
  10. const { h } = window;
  11. Object.defineProperty(window, "crypto", {
  12. value: {
  13. getRandomValues: (arr: number[]) =>
  14. arr.forEach((v, i) => (arr[i] = Math.floor(Math.random() * 256))),
  15. subtle: {
  16. generateKey: () => {},
  17. exportKey: () => ({ k: "sTdLvMC_M3V8_vGa3UVRDg" }),
  18. },
  19. },
  20. });
  21. vi.mock("../../excalidraw-app/data/index.ts", async (importActual) => {
  22. const module = (await importActual()) as any;
  23. return {
  24. __esmodule: true,
  25. ...module,
  26. getCollabServer: vi.fn(() => ({
  27. url: /* doesn't really matter */ "http://localhost:3002",
  28. })),
  29. };
  30. });
  31. vi.mock("../../excalidraw-app/data/firebase.ts", () => {
  32. const loadFromFirebase = async () => null;
  33. const saveToFirebase = () => {};
  34. const isSavedToFirebase = () => true;
  35. const loadFilesFromFirebase = async () => ({
  36. loadedFiles: [],
  37. erroredFiles: [],
  38. });
  39. const saveFilesToFirebase = async () => ({
  40. savedFiles: new Map(),
  41. erroredFiles: new Map(),
  42. });
  43. return {
  44. loadFromFirebase,
  45. saveToFirebase,
  46. isSavedToFirebase,
  47. loadFilesFromFirebase,
  48. saveFilesToFirebase,
  49. };
  50. });
  51. vi.mock("socket.io-client", () => {
  52. return {
  53. default: () => {
  54. return {
  55. close: () => {},
  56. on: () => {},
  57. once: () => {},
  58. off: () => {},
  59. emit: () => {},
  60. };
  61. },
  62. };
  63. });
  64. describe("collaboration", () => {
  65. it("creating room should reset deleted elements", async () => {
  66. await render(<ExcalidrawApp />);
  67. // To update the scene with deleted elements before starting collab
  68. updateSceneData({
  69. elements: [
  70. API.createElement({ type: "rectangle", id: "A" }),
  71. API.createElement({
  72. type: "rectangle",
  73. id: "B",
  74. isDeleted: true,
  75. }),
  76. ],
  77. });
  78. await waitFor(() => {
  79. expect(h.elements).toEqual([
  80. expect.objectContaining({ id: "A" }),
  81. expect.objectContaining({ id: "B", isDeleted: true }),
  82. ]);
  83. expect(API.getStateHistory().length).toBe(1);
  84. });
  85. window.collab.startCollaboration(null);
  86. await waitFor(() => {
  87. expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]);
  88. expect(API.getStateHistory().length).toBe(1);
  89. });
  90. const undoAction = createUndoAction(h.history);
  91. // noop
  92. h.app.actionManager.executeAction(undoAction);
  93. await waitFor(() => {
  94. expect(h.elements).toEqual([expect.objectContaining({ id: "A" })]);
  95. expect(API.getStateHistory().length).toBe(1);
  96. });
  97. });
  98. });