import { expect, test } from "@playwright/test"; import { buildVideoPromptStructureInstructions, injectVideoPromptStructure, normalizeVideoPromptMentions, resolveVideoPromptStructure, type VideoPromptToolMark, type VideoPromptToolReference, } from "@/lib/video-canvas/prompt-structure"; const references: VideoPromptToolReference[] = [ { id: "ref-1", index: 1, label: "图片 1", mediaType: "image", offset: 0 }, { id: "ref-2", index: 2, label: "图片 2", mediaType: "image", offset: 4 }, ]; const marks: VideoPromptToolMark[] = [{ id: "mark-1", label: "人物" }]; test.describe("video prompt structure", () => { test("normalizes persisted mentions defensively", () => { expect( normalizeVideoPromptMentions([ { id: "mention 1", index: 99, label: "图片 1", mediaType: "unknown", offset: -8, sourceNodeId: "image-1", url: "https://example.com/image.png", }, ]) ).toEqual([ { id: "mention-1", index: 10, label: "图片 1", mediaType: "image", offset: 0, sourceNodeId: "image-1", url: "https://example.com/image.png", }, ]); }); test("injects reference tokens at offsets and appends mark tokens", () => { expect(injectVideoPromptStructure("甲乙丙丁戊", references, marks)).toBe( "[[REF:ref-1]]甲乙丙丁[[REF:ref-2]]戊 [[MARK:mark-1]]" ); expect(buildVideoPromptStructureInstructions(references, marks)).toContain( "[[REF:ref-2]] = @2「图片 2」image素材" ); }); test("restores token offsets for translation and flattens optimization output", () => { const translated = resolveVideoPromptStructure( "Start [[REF:ref-1]]middle [[REF:ref-2]]end [[MARK:mark-1]]", references, marks, { flatten: false } ); expect(translated).toEqual({ mentionOffsets: { "ref-1": 6, "ref-2": 13 }, preservedMarkIds: ["mark-1"], text: "Start middle end", }); expect( resolveVideoPromptStructure( "使用[[REF:ref-1]]中的[[MARK:mark-1]]", references, marks, { flatten: true } ).text ).toBe("使用图片 1中的人物"); }); });