Files
lemonspace_app/components/canvas/__tests__/use-canvas-sync-engine.test.ts

78 lines
2.9 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import type { Id } from "@/convex/_generated/dataModel";
import { createCanvasSyncEngineController } from "@/components/canvas/use-canvas-sync-engine";
const asCanvasId = (id: string): Id<"canvases"> => id as Id<"canvases">;
const asNodeId = (id: string): Id<"nodes"> => id as Id<"nodes">;
describe("useCanvasSyncEngine", () => {
it("hands off an optimistic create to the real node id before replaying a deferred move", async () => {
const enqueueSyncMutation = vi.fn(async () => undefined);
const runBatchRemoveNodes = vi.fn(async () => undefined);
const runSplitEdgeAtExistingNode = vi.fn(async () => undefined);
const controller = createCanvasSyncEngineController({
canvasId: asCanvasId("canvas-1"),
isSyncOnline: true,
enqueueSyncMutation,
runBatchRemoveNodes,
runSplitEdgeAtExistingNode,
});
controller.pendingMoveAfterCreateRef.current.set("req-1", {
positionX: 320,
positionY: 180,
});
await controller.syncPendingMoveForClientRequest("req-1", asNodeId("node-real"));
expect(enqueueSyncMutation).toHaveBeenCalledWith("moveNode", {
nodeId: asNodeId("node-real"),
positionX: 320,
positionY: 180,
});
expect(
controller.pendingLocalPositionUntilConvexMatchesRef.current.get("node-real"),
).toEqual({ x: 320, y: 180 });
expect(controller.resolvedRealIdByClientRequestRef.current.get("req-1")).toBe(
asNodeId("node-real"),
);
expect(controller.pendingMoveAfterCreateRef.current.has("req-1")).toBe(false);
expect(runBatchRemoveNodes).not.toHaveBeenCalled();
expect(runSplitEdgeAtExistingNode).not.toHaveBeenCalled();
});
it("defers resize and data updates for an optimistic node until the real id is known", async () => {
const enqueueSyncMutation = vi.fn(async () => undefined);
const controller = createCanvasSyncEngineController({
canvasId: asCanvasId("canvas-1"),
isSyncOnline: true,
enqueueSyncMutation,
runBatchRemoveNodes: vi.fn(async () => undefined),
runSplitEdgeAtExistingNode: vi.fn(async () => undefined),
});
await controller.queueNodeResize({
nodeId: asNodeId("optimistic_req-2"),
width: 640,
height: 360,
});
await controller.queueNodeDataUpdate({
nodeId: asNodeId("optimistic_req-2"),
data: { label: "Updated" },
});
expect(enqueueSyncMutation).not.toHaveBeenCalled();
await controller.syncPendingMoveForClientRequest("req-2", asNodeId("node-2"));
expect(enqueueSyncMutation.mock.calls).toEqual([
["resizeNode", { nodeId: asNodeId("node-2"), width: 640, height: 360 }],
["updateData", { nodeId: asNodeId("node-2"), data: { label: "Updated" } }],
]);
expect(controller.pendingResizeAfterCreateRef.current.has("req-2")).toBe(false);
expect(controller.pendingDataAfterCreateRef.current.has("req-2")).toBe(false);
});
});