78 lines
2.9 KiB
TypeScript
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);
|
|
});
|
|
});
|