From 72703d9b66c805d1c6e4ad08d08991588385908c Mon Sep 17 00:00:00 2001 From: ddCat <2695092045@qq.com> Date: Thu, 24 Sep 2026 00:06:09 +0800 Subject: [PATCH] =?UTF-8?q?test(canvas):=20=E7=B4=A0=E6=9D=90=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20-=20=E8=A6=86=E7=9B=96=E5=A4=B1=E6=95=88=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/test/canvas-asset-repair.test.ts | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/web/test/canvas-asset-repair.test.ts b/web/test/canvas-asset-repair.test.ts index 57f905fc9..1d517bb41 100644 --- a/web/test/canvas-asset-repair.test.ts +++ b/web/test/canvas-asset-repair.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, test } from "bun:test"; -import { collectCanvasMediaAssetIds, rebindInconsistentCanvasAssets, repairMissingCanvasAssets } from "@/services/canvas-asset-repair"; +import { collectCanvasMediaAssetIds, rebindInconsistentCanvasAssets, repairMissingCanvasAssets, repairMissingCanvasVideoPreviews } from "@/services/canvas-asset-repair"; +import { ApiError } from "@/services/api/request"; import { useAssetStore, type Asset } from "@/stores/use-asset-store"; import { useCanvasStore, type CanvasProject } from "@/stores/canvas/use-canvas-store"; import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas"; @@ -137,3 +138,29 @@ describe("collectCanvasMediaAssetIds", () => { expect(collectCanvasMediaAssetIds(projects)).toEqual(new Set(["asset-a", "asset-b"])); }); }); + +describe("repairMissingCanvasVideoPreviews", () => { + test("only clears confirmed missing preview resources, not network failures", async () => { + const node = { ...videoNode("node-1", "asset-1", "resource:video-1"), metadata: { ...videoNode("node-1", "asset-1", "resource:video-1").metadata, videoPreview: { storageKey: "resource:poster-1" } } }; + useCanvasStore.setState({ projects: [project("canvas-1", [node])] }); + + await expect(repairMissingCanvasVideoPreviews(undefined, async () => { throw new Error("offline"); })).rejects.toThrow("offline"); + expect(useCanvasStore.getState().projects[0].nodes[0].metadata?.videoPreview).toBeDefined(); + + const result = await repairMissingCanvasVideoPreviews(undefined, async () => { throw new ApiError("missing", { status: 404 }); }); + expect(result).toEqual({ clearedPreviews: 1, updatedProjects: 1 }); + expect(useCanvasStore.getState().projects[0].nodes[0].metadata?.videoPreview).toBeUndefined(); + }); + + test("preserves edits made while resource lookup is pending", async () => { + const node = { ...videoNode("node-1", "asset-1", "resource:video-1"), metadata: { ...videoNode("node-1", "asset-1", "resource:video-1").metadata, videoPreview: { storageKey: "resource:poster-1" } } }; + useCanvasStore.setState({ projects: [project("canvas-1", [node])] }); + let rejectLookup!: (error: unknown) => void; + const repair = repairMissingCanvasVideoPreviews(undefined, () => new Promise((_, reject) => { rejectLookup = reject; })); + useCanvasStore.getState().updateProject("canvas-1", { title: "user edit" }); + rejectLookup(new ApiError("missing", { status: 404 })); + await repair; + expect(useCanvasStore.getState().projects[0].title).toBe("user edit"); + expect(useCanvasStore.getState().projects[0].nodes[0].metadata?.videoPreview).toBeUndefined(); + }); +});