feat(*): 短剧创作工作台 - 完善章节分镜、资产管理、技能运行与生成任务恢复
This commit is contained in:
87
web/test/workflow-shot-references.test.ts
Normal file
87
web/test/workflow-shot-references.test.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { canvasResourceMentionToken } from "@/lib/canvas/canvas-resource-references";
|
||||
import type { ProjectAsset, ProjectDetail } from "@/services/api/projects";
|
||||
import { buildShotAssetReferenceContext, resolveShotAssetMentionPrompt } from "@/pages/projects/detail/workflow-shot-references";
|
||||
|
||||
describe("workflow shot asset references", () => {
|
||||
test("builds ordered image references for bound media and characters", () => {
|
||||
const context = buildShotAssetReferenceContext(detail(), "shot-1");
|
||||
|
||||
expect(context.mentionReferences.map((reference) => reference.label)).toEqual(["雨夜街道", "林默"]);
|
||||
expect(context.referenceImages.map((image) => image.id)).toEqual(["asset-scene", "asset-character"]);
|
||||
expect(context.referenceImages[1]?.storageKey).toBe("resource:character-cover");
|
||||
});
|
||||
|
||||
test("resolves asset tokens to the submitted reference image order", () => {
|
||||
const context = buildShotAssetReferenceContext(detail(), "shot-1");
|
||||
const [scene, character] = context.mentionReferences;
|
||||
const prompt = `让 ${canvasResourceMentionToken(character)} 从 ${canvasResourceMentionToken(scene)} 走近镜头`;
|
||||
|
||||
expect(resolveShotAssetMentionPrompt(prompt, context)).toBe("让 图片2 从 图片1 走近镜头");
|
||||
});
|
||||
|
||||
test("rejects stale mentions after an asset is unbound", () => {
|
||||
const context = buildShotAssetReferenceContext(detail(), "shot-1");
|
||||
|
||||
expect(() => resolveShotAssetMentionPrompt("跟随 @[asset:missing]", context)).toThrow("未绑定到当前镜头");
|
||||
});
|
||||
});
|
||||
|
||||
function detail(): ProjectDetail {
|
||||
const scene = {
|
||||
id: "asset-scene",
|
||||
title: "雨夜街道",
|
||||
mediaType: "image",
|
||||
category: "environment",
|
||||
status: "confirmed",
|
||||
primaryVersionId: "version-scene",
|
||||
versionCount: 1,
|
||||
usages: [],
|
||||
position: 0,
|
||||
storageKey: "resource:scene-image",
|
||||
updatedAt: "2026-08-29T00:00:00Z",
|
||||
} satisfies ProjectAsset;
|
||||
const character = {
|
||||
id: "asset-character",
|
||||
title: "林默",
|
||||
mediaType: "entity",
|
||||
category: "character",
|
||||
status: "confirmed",
|
||||
primaryVersionId: "version-character",
|
||||
versionCount: 1,
|
||||
usages: [],
|
||||
position: 1,
|
||||
updatedAt: "2026-08-29T00:00:00Z",
|
||||
character: {
|
||||
versionId: "version-character",
|
||||
version: 1,
|
||||
definition: {},
|
||||
representations: [{ id: "representation-1", resourceId: "character-cover", mediaType: "image", role: "primary" }],
|
||||
visualStatus: "ready",
|
||||
voiceStatus: "missing",
|
||||
},
|
||||
} satisfies ProjectAsset;
|
||||
const audio = {
|
||||
id: "asset-audio",
|
||||
title: "雨声",
|
||||
mediaType: "audio",
|
||||
category: "other",
|
||||
status: "confirmed",
|
||||
primaryVersionId: "version-audio",
|
||||
versionCount: 1,
|
||||
usages: [],
|
||||
position: 2,
|
||||
storageKey: "resource:rain-audio",
|
||||
updatedAt: "2026-08-29T00:00:00Z",
|
||||
} satisfies ProjectAsset;
|
||||
return {
|
||||
assets: [scene, character, audio],
|
||||
shotReferences: [
|
||||
{ id: "reference-scene", shotId: "shot-1", assetVersionId: "version-scene", role: "reference", status: "linked", createdAt: "2026-08-29T00:00:00Z" },
|
||||
{ id: "reference-character", shotId: "shot-1", assetVersionId: "version-character", role: "reference", status: "linked", createdAt: "2026-08-29T00:00:01Z" },
|
||||
{ id: "reference-audio", shotId: "shot-1", assetVersionId: "version-audio", role: "reference", status: "linked", createdAt: "2026-08-29T00:00:02Z" },
|
||||
{ id: "reference-other-shot", shotId: "shot-2", assetVersionId: "version-scene", role: "reference", status: "linked", createdAt: "2026-08-29T00:00:03Z" },
|
||||
],
|
||||
} as ProjectDetail;
|
||||
}
|
||||
Reference in New Issue
Block a user