b00a3f8057
删除资源画布顶部的生成视频、生成音效、生成背景音乐和新增 UI 设计按钮 移除仅服务于这些入口的前端 handler 与入口配置 保留 Agent 语义生成、已有资源编辑、生成动画和未完成任务恢复能力 补充顶部入口消失与画布级操作保留的定向回归测试 同步更新 AGC 配置白名单、技术方案与项目决策记录
244 lines
6.6 KiB
TypeScript
244 lines
6.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
canonicalProjectedResourceMediaType,
|
|
resolveProjectCharacterAnimationCapability,
|
|
resolveProjectResourceEditCapability,
|
|
resourceEditPromptMaxLength,
|
|
} from '../src/view/project-development/resourceEditModel';
|
|
import type { ProjectResource } from '../src/view/project-development/resourceProjectionModel';
|
|
|
|
function resource(
|
|
input: Partial<ProjectResource> &
|
|
Pick<ProjectResource, 'id' | 'category' | 'path'>,
|
|
): ProjectResource {
|
|
return {
|
|
subtype: 'task-artifact',
|
|
label: input.path,
|
|
mediaType: '',
|
|
sourceLabel: '测试来源',
|
|
taskTitle: null,
|
|
manifestAssetId: null,
|
|
producerTaskId: 'task-1',
|
|
externalResourceId: null,
|
|
referenceResourceIds: [],
|
|
dependencies: [],
|
|
dependencyDepth: 0,
|
|
...input,
|
|
};
|
|
}
|
|
|
|
describe('全类型资源编辑能力模型', () => {
|
|
it('把现役资源稳定分流到图片画布、媒体派生、文本派生和版本分支', () => {
|
|
const cases: Array<{
|
|
resource: ProjectResource;
|
|
route: 'image-canvas' | 'derive';
|
|
editKind?: string;
|
|
normalizeSource?: boolean;
|
|
}> = [
|
|
{
|
|
resource: resource({
|
|
id: 'asset:png',
|
|
category: 'art',
|
|
path: 'assets/hero.png',
|
|
mediaType: 'image/png',
|
|
manifestAssetId: 'png',
|
|
}),
|
|
route: 'image-canvas',
|
|
normalizeSource: false,
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'task:art:hero.webp',
|
|
category: 'art',
|
|
path: 'hero.webp',
|
|
mediaType: '美术产物',
|
|
}),
|
|
route: 'image-canvas',
|
|
normalizeSource: true,
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'asset:gif',
|
|
category: 'art',
|
|
path: 'assets/hero.gif',
|
|
mediaType: 'image/gif',
|
|
manifestAssetId: 'gif',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'image-reference',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'asset:svg',
|
|
category: 'art',
|
|
path: 'assets/icon.svg',
|
|
mediaType: 'image/svg+xml',
|
|
manifestAssetId: 'svg',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'svg',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'task:art:intro.mp4',
|
|
category: 'art',
|
|
path: 'assets/intro.mp4',
|
|
mediaType: '美术产物',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'video',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'asset:bgm',
|
|
category: 'audio',
|
|
path: 'audio/theme.ogg',
|
|
subtype: 'background-music',
|
|
mediaType: 'audio/ogg',
|
|
manifestAssetId: 'bgm',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'background-music',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'asset:sfx',
|
|
category: 'audio',
|
|
path: 'audio/hit.wav',
|
|
subtype: 'sound-effect',
|
|
mediaType: 'audio/wav',
|
|
manifestAssetId: 'sfx',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'sound-effect',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'task:code:main.ts',
|
|
category: 'document',
|
|
path: 'src/main.ts',
|
|
mediaType: '项目文档',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'text',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'agent-result:design:message-1',
|
|
category: 'document',
|
|
path: '专业 Agent 文本回执',
|
|
subtype: 'agent-result',
|
|
producerTaskId: null,
|
|
content: '回执',
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'agent-result',
|
|
},
|
|
{
|
|
resource: resource({
|
|
id: 'version:v1',
|
|
category: 'version',
|
|
path: '项目版本 · v1',
|
|
subtype: 'project-version',
|
|
producerTaskId: null,
|
|
version: {
|
|
versionId: 'v1',
|
|
parentVersionId: null,
|
|
projectRevision: 1,
|
|
resourceBindings: [],
|
|
createdReason: 'initial',
|
|
createdAt: 1,
|
|
label: '版本 1',
|
|
childVersionIds: [],
|
|
},
|
|
}),
|
|
route: 'derive',
|
|
editKind: 'version',
|
|
},
|
|
];
|
|
|
|
for (const expected of cases) {
|
|
const capability = resolveProjectResourceEditCapability(
|
|
expected.resource,
|
|
);
|
|
expect(capability.route, expected.resource.id).toBe(expected.route);
|
|
if (capability.route === 'derive') {
|
|
expect(capability.editKind, expected.resource.id).toBe(
|
|
expected.editKind,
|
|
);
|
|
} else {
|
|
expect(capability.normalizeSource, expected.resource.id).toBe(
|
|
expected.normalizeSource,
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
it('用路径补齐任务产物缺失的标准媒体类型', () => {
|
|
expect(
|
|
canonicalProjectedResourceMediaType(
|
|
resource({
|
|
id: 'task:art:clip.mov',
|
|
category: 'art',
|
|
path: 'assets/clip.mov',
|
|
mediaType: '美术产物',
|
|
}),
|
|
),
|
|
).toBe('video/quicktime');
|
|
expect(
|
|
canonicalProjectedResourceMediaType(
|
|
resource({
|
|
id: 'task:audio:effect.wav',
|
|
category: 'audio',
|
|
path: 'audio/effect.wav',
|
|
mediaType: '美术产物',
|
|
}),
|
|
),
|
|
).toBe('audio/wav');
|
|
expect(
|
|
canonicalProjectedResourceMediaType(
|
|
resource({
|
|
id: 'task:code:main.ts',
|
|
category: 'document',
|
|
path: 'src/main.ts',
|
|
mediaType: '项目文档',
|
|
}),
|
|
),
|
|
).toBe('text/typescript');
|
|
});
|
|
|
|
it('按现役媒体接口限制编辑提示词长度', () => {
|
|
expect(resourceEditPromptMaxLength('background-music')).toBe(140);
|
|
expect(resourceEditPromptMaxLength('sound-effect')).toBe(1_900);
|
|
expect(resourceEditPromptMaxLength('video')).toBe(4_000);
|
|
expect(resourceEditPromptMaxLength('character-animation')).toBe(4_000);
|
|
expect(resourceEditPromptMaxLength('text')).toBe(32_000);
|
|
});
|
|
|
|
it('图片资源可进入角色动画派生入口', () => {
|
|
const capability = resolveProjectCharacterAnimationCapability(
|
|
resource({
|
|
id: 'asset:hero',
|
|
category: 'art',
|
|
path: 'assets/hero.png',
|
|
mediaType: 'image/png',
|
|
manifestAssetId: 'hero',
|
|
}),
|
|
);
|
|
expect(capability?.editKind).toBe('character-animation');
|
|
expect(capability?.generationMode).toBe('derive');
|
|
expect(
|
|
resolveProjectCharacterAnimationCapability(
|
|
resource({
|
|
id: 'asset:bgm',
|
|
category: 'audio',
|
|
path: 'audio/theme.mp3',
|
|
mediaType: 'audio/mpeg',
|
|
manifestAssetId: 'bgm',
|
|
}),
|
|
),
|
|
).toBeNull();
|
|
});
|
|
});
|