ai-chatbot/tests/routes/video-canvas-save-queue.test.ts

60 lines
2.0 KiB
TypeScript

import { test, expect } from "@playwright/test";
import { CanvasRevisionConflict, VideoCanvasSaveQueue } from "@/lib/video-canvas/save-queue";
test("coalesces edits made during a save and uses the returned revision", async () => {
let release!: (value: string) => void;
const calls: string[][] = [];
const queue = new VideoCanvasSaveQueue("initial", "r0", async (value, revision) => {
calls.push([value, revision]);
return calls.length === 1 ? new Promise<string>(resolve => { release = resolve; }) : "r2";
}, () => {});
queue.update("first");
const pending = queue.flush();
queue.update("second");
queue.update("latest");
expect(queue.flush()).toBe(pending);
release("r1");
await pending;
expect(calls).toEqual([["first", "r0"], ["latest", "r1"]]);
expect(queue.dirty).toBe(false);
});
test("failed save retains edits and retries only the latest snapshot", async () => {
const calls: string[][] = [];
const queue = new VideoCanvasSaveQueue("initial", "r0", async (value, revision) => {
calls.push([value, revision]);
if (calls.length === 1) throw new Error("offline");
return "r1";
}, () => {});
queue.update("first");
await queue.flush();
expect(queue.dirty).toBe(true);
expect(queue.failed).toBe(true);
queue.update("latest");
await queue.flush();
expect(calls).toEqual([["first", "r0"], ["latest", "r0"]]);
expect(queue.dirty).toBe(false);
});
test("revision conflict cannot be retried as an overwrite", async () => {
let calls = 0;
const queue = new VideoCanvasSaveQueue("initial", "r0", async () => {
calls++;
throw new CanvasRevisionConflict("changed elsewhere");
}, () => {});
queue.update("first");
await queue.flush();
queue.update("latest");
await queue.flush();
expect(calls).toBe(1);
expect(queue.dirty).toBe(true);
});
test("unchanged canvas does not write", async () => {
let calls = 0;
const queue = new VideoCanvasSaveQueue("initial", "r0", async () => { calls++; return "r1"; }, () => {});
queue.update("initial");
await queue.flush();
expect(calls).toBe(0);
});