forked from 77media/video-flow
修复问题
This commit is contained in:
parent
15e2db2ebc
commit
b1de9fd656
@ -651,6 +651,8 @@ export const getProjectScript = async (request: {
|
||||
export const saveScript = async (request: {
|
||||
/** 项目ID */
|
||||
project_id: string;
|
||||
/**用户id */
|
||||
user_id:string;
|
||||
/** 剧本文本 */
|
||||
generated_script: string;
|
||||
}): Promise<ApiResponse<any>> => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
import { RoleEntity, TagEntity, AITextEntity, VideoSegmentEntity } from '../domain/Entities';
|
||||
import { RoleItem, TagItem, TextItem, ShotItem } from '../domain/Item';
|
||||
import { RoleItem, TagItem, TextItem } from '../domain/Item';
|
||||
import { RoleEditUseCase } from '../usecase/RoleEditUseCase';
|
||||
import { TagEditUseCase } from '../usecase/TagEditUseCase';
|
||||
import { TextEditUseCase } from '../usecase/TextEditUseCase';
|
||||
|
||||
@ -1,821 +1,3 @@
|
||||
import { getRoleList, getRoleData, updateText, updateTag, regenerateRole, getUserRoleLibrary, replaceRole, getRoleShots, applyRoleToShots } from '@/api/video_flow';
|
||||
import { RoleEditUseCase } from '../usecase/RoleEditUseCase';
|
||||
import { TextEditUseCase } from '../usecase/TextEditUseCase';
|
||||
import { TagEditUseCase } from '../usecase/TagEditUseCase';
|
||||
import { RoleItem, TextItem, TagItem } from '../domain/Item';
|
||||
import { RoleEntity, AITextEntity, TagEntity, VideoSegmentEntity, ShotStatus } from '../domain/Entities';
|
||||
|
||||
// Mock API模块
|
||||
jest.mock('@/api/video_flow', () => ({
|
||||
getRoleList: jest.fn(),
|
||||
getRoleData: jest.fn(),
|
||||
updateText: jest.fn(),
|
||||
updateTag: jest.fn(),
|
||||
regenerateRole: jest.fn(),
|
||||
getUserRoleLibrary: jest.fn(),
|
||||
replaceRole: jest.fn(),
|
||||
getRoleShots: jest.fn(),
|
||||
applyRoleToShots: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock UseCase模块
|
||||
jest.mock('../usecase/RoleEditUseCase');
|
||||
jest.mock('../usecase/TextEditUseCase');
|
||||
jest.mock('../usecase/TagEditUseCase');
|
||||
|
||||
// Mock Domain模块
|
||||
jest.mock('../domain/Item', () => ({
|
||||
RoleItem: jest.fn(),
|
||||
TextItem: jest.fn(),
|
||||
TagItem: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('RoleService 业务逻辑测试', () => {
|
||||
let mockRoleEditUseCase: jest.Mocked<RoleEditUseCase>;
|
||||
let mockTextEditUseCase: jest.Mocked<TextEditUseCase>;
|
||||
let mockTagEditUseCase: jest.Mocked<TagEditUseCase>;
|
||||
|
||||
// 测试数据
|
||||
const mockRoleEntity: RoleEntity = {
|
||||
id: 'role1',
|
||||
name: '测试角色',
|
||||
generateTextId: 'text1',
|
||||
tagIds: ['tag1', 'tag2'],
|
||||
imageUrl: 'http://example.com/role1.jpg',
|
||||
updatedAt: Date.now(),
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
isStored: true,
|
||||
};
|
||||
|
||||
const mockTextEntity: AITextEntity = {
|
||||
id: 'text1',
|
||||
content: '这是AI生成的文本内容',
|
||||
updatedAt: Date.now(),
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
};
|
||||
|
||||
const mockTagEntity1: TagEntity = {
|
||||
id: 'tag1',
|
||||
name: '标签1',
|
||||
content: '标签内容1',
|
||||
updatedAt: Date.now(),
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
};
|
||||
|
||||
|
||||
const mockShotEntity: VideoSegmentEntity = {
|
||||
id: 'shot1',
|
||||
name: '分镜1',
|
||||
sketchUrl: 'http://example.com/sketch1.jpg',
|
||||
videoUrl: ['http://example.com/video1.mp4'],
|
||||
roleList: [],
|
||||
sceneList: [],
|
||||
status: ShotStatus.sketchLoading,
|
||||
scriptId: 'script1',
|
||||
content: [],
|
||||
shot: [],
|
||||
updatedAt: Date.now(),
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
// 设置Mock UseCase实例
|
||||
mockRoleEditUseCase = {
|
||||
AIgenerateRole: jest.fn(),
|
||||
applyRole: jest.fn(),
|
||||
} as any;
|
||||
|
||||
mockTextEditUseCase = {
|
||||
getOptimizedContent: jest.fn(),
|
||||
updateText: jest.fn(),
|
||||
} as any;
|
||||
|
||||
mockTagEditUseCase = {
|
||||
updateTag: jest.fn(),
|
||||
} as any;
|
||||
|
||||
// 设置Mock构造函数
|
||||
(RoleEditUseCase as jest.MockedClass<typeof RoleEditUseCase>).mockImplementation(() => mockRoleEditUseCase);
|
||||
(TextEditUseCase as jest.MockedClass<typeof TextEditUseCase>).mockImplementation(() => mockTextEditUseCase);
|
||||
(TagEditUseCase as jest.MockedClass<typeof TagEditUseCase>).mockImplementation(() => mockTagEditUseCase);
|
||||
|
||||
// 设置Mock Item构造函数
|
||||
(RoleItem as jest.MockedClass<typeof RoleItem>).mockImplementation((entity) => ({
|
||||
entity,
|
||||
metadata: {},
|
||||
disableEdit: entity.disableEdit,
|
||||
type: 1,
|
||||
} as any));
|
||||
|
||||
(TextItem as jest.MockedClass<typeof TextItem>).mockImplementation((entity) => ({
|
||||
entity,
|
||||
metadata: {},
|
||||
disableEdit: entity.disableEdit,
|
||||
type: 0,
|
||||
} as any));
|
||||
|
||||
(TagItem as jest.MockedClass<typeof TagItem>).mockImplementation((entity) => ({
|
||||
entity,
|
||||
metadata: {},
|
||||
disableEdit: entity.disableEdit,
|
||||
type: 2,
|
||||
} as any));
|
||||
});
|
||||
|
||||
describe('数据初始化测试', () => {
|
||||
it('应该成功获取角色列表', async () => {
|
||||
const mockRoles = [mockRoleEntity];
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: mockRoles,
|
||||
message: 'success',
|
||||
});
|
||||
|
||||
const result = await getRoleList({ projectId: 'project1' });
|
||||
|
||||
expect(getRoleList).toHaveBeenCalledWith({ projectId: 'project1' });
|
||||
expect(result.successful).toBe(true);
|
||||
expect(result.data).toEqual(mockRoles);
|
||||
});
|
||||
|
||||
it('获取角色列表失败时应该返回错误信息', async () => {
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '获取失败',
|
||||
});
|
||||
|
||||
const result = await getRoleList({ projectId: 'project1' });
|
||||
|
||||
expect(result.successful).toBe(false);
|
||||
expect(result.message).toBe('获取失败');
|
||||
});
|
||||
});
|
||||
|
||||
describe('修改文本和标签测试', () => {
|
||||
it('应该成功修改AI文本', async () => {
|
||||
const updatedTextEntity = { ...mockTextEntity, content: '更新后的文本' };
|
||||
(updateText as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: updatedTextEntity,
|
||||
});
|
||||
|
||||
const result = await updateText({
|
||||
textId: 'text1',
|
||||
content: '新的文本内容'
|
||||
});
|
||||
|
||||
expect(updateText).toHaveBeenCalledWith({
|
||||
textId: 'text1',
|
||||
content: '新的文本内容'
|
||||
});
|
||||
expect(result.successful).toBe(true);
|
||||
expect(result.data.content).toBe('更新后的文本');
|
||||
});
|
||||
|
||||
it('应该成功修改标签内容', async () => {
|
||||
const updatedTagEntity = { ...mockTagEntity1, content: '更新后的标签' };
|
||||
(updateTag as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: updatedTagEntity,
|
||||
});
|
||||
|
||||
const result = await updateTag({
|
||||
tagId: 'tag1',
|
||||
content: '新的标签内容'
|
||||
});
|
||||
|
||||
expect(updateTag).toHaveBeenCalledWith({
|
||||
tagId: 'tag1',
|
||||
content: '新的标签内容'
|
||||
});
|
||||
expect(result.successful).toBe(true);
|
||||
expect(result.data.content).toBe('更新后的标签');
|
||||
});
|
||||
});
|
||||
|
||||
describe('文本AI优化测试', () => {
|
||||
it('应该成功优化AI文本', async () => {
|
||||
const optimizedContent = '优化后的文本内容';
|
||||
const updatedTextEntity = { ...mockTextEntity, content: optimizedContent };
|
||||
|
||||
mockTextEditUseCase.getOptimizedContent.mockResolvedValue(optimizedContent);
|
||||
mockTextEditUseCase.updateText.mockResolvedValue({
|
||||
entity: updatedTextEntity,
|
||||
metadata: {},
|
||||
disableEdit: false,
|
||||
type: 0,
|
||||
} as any);
|
||||
|
||||
(updateText as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: updatedTextEntity,
|
||||
});
|
||||
|
||||
// 模拟优化流程
|
||||
const optimizedContentResult = await mockTextEditUseCase.getOptimizedContent();
|
||||
const updateResult = await mockTextEditUseCase.updateText(optimizedContentResult);
|
||||
|
||||
expect(mockTextEditUseCase.getOptimizedContent).toHaveBeenCalled();
|
||||
expect(mockTextEditUseCase.updateText).toHaveBeenCalledWith(optimizedContent);
|
||||
expect(updateResult.entity.content).toBe(optimizedContent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('重新生成角色形象测试', () => {
|
||||
it('应该成功重新生成角色', async () => {
|
||||
const newRoleEntity = { ...mockRoleEntity, id: 'role2', name: '新角色' };
|
||||
(regenerateRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: newRoleEntity,
|
||||
});
|
||||
|
||||
mockRoleEditUseCase.AIgenerateRole.mockResolvedValue(newRoleEntity);
|
||||
|
||||
const result = await regenerateRole({
|
||||
prompt: '重新生成角色',
|
||||
tagTypes: ['tag1', 'tag2'],
|
||||
roleId: 'role1'
|
||||
});
|
||||
|
||||
expect(regenerateRole).toHaveBeenCalledWith({
|
||||
prompt: '重新生成角色',
|
||||
tagTypes: ['tag1', 'tag2'],
|
||||
roleId: 'role1'
|
||||
});
|
||||
expect(result.successful).toBe(true);
|
||||
expect(result.data.id).toBe('role2');
|
||||
expect(result.data.name).toBe('新角色');
|
||||
});
|
||||
});
|
||||
|
||||
describe('角色业务流程测试', () => {
|
||||
it('应该完成完整的角色编辑流程:获取列表→选择角色→修改提示词→智能优化→修改标签→重新生成→角色库替换→应用角色', async () => {
|
||||
// 1. 用户操作:获取角色列表
|
||||
const mockRoles = [mockRoleEntity];
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: mockRoles,
|
||||
message: 'success',
|
||||
});
|
||||
|
||||
const roleListResult = await getRoleList({ projectId: 'project1' });
|
||||
expect(roleListResult.successful).toBe(true);
|
||||
expect(roleListResult.data).toEqual(mockRoles);
|
||||
|
||||
// 2. 用户操作:选择角色并获取角色数据
|
||||
(getRoleData as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: {
|
||||
text: mockTextEntity,
|
||||
tags: [mockTagEntity1],
|
||||
},
|
||||
});
|
||||
|
||||
const roleDataResult = await getRoleData({ roleId: 'role1' });
|
||||
expect(roleDataResult.successful).toBe(true);
|
||||
expect(roleDataResult.data.text).toEqual(mockTextEntity);
|
||||
expect(roleDataResult.data.tags).toEqual([mockTagEntity1]);
|
||||
|
||||
// 3. 用户操作:修改角色提示词
|
||||
const updatedTextEntity = { ...mockTextEntity, content: '修改后的角色提示词' };
|
||||
(updateText as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: updatedTextEntity,
|
||||
});
|
||||
|
||||
const updateTextResult = await updateText({
|
||||
textId: 'text1',
|
||||
content: '修改后的角色提示词'
|
||||
});
|
||||
expect(updateTextResult.successful).toBe(true);
|
||||
expect(updateTextResult.data.content).toBe('修改后的角色提示词');
|
||||
|
||||
// 4. 用户操作:智能优化文本
|
||||
const optimizedContent = '智能优化后的角色文本';
|
||||
mockTextEditUseCase.getOptimizedContent.mockResolvedValue(optimizedContent);
|
||||
mockTextEditUseCase.updateText.mockResolvedValue({
|
||||
entity: { ...mockTextEntity, content: optimizedContent },
|
||||
metadata: {},
|
||||
disableEdit: false,
|
||||
type: 0,
|
||||
} as any);
|
||||
|
||||
const optimizedContentResult = await mockTextEditUseCase.getOptimizedContent();
|
||||
expect(optimizedContentResult).toBe(optimizedContent);
|
||||
|
||||
// 5. 用户操作:修改标签
|
||||
const updatedTagEntity = { ...mockTagEntity1, content: '修改后的标签内容' };
|
||||
(updateTag as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: updatedTagEntity,
|
||||
});
|
||||
|
||||
const updateTagResult = await updateTag({
|
||||
tagId: 'tag1',
|
||||
content: '修改后的标签内容'
|
||||
});
|
||||
expect(updateTagResult.successful).toBe(true);
|
||||
expect(updateTagResult.data.content).toBe('修改后的标签内容');
|
||||
|
||||
// 6. 用户操作:使用新的提示词和标签重新生成角色
|
||||
const newRoleEntity = { ...mockRoleEntity, id: 'role2', name: '重新生成的角色' };
|
||||
(regenerateRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: newRoleEntity,
|
||||
});
|
||||
|
||||
mockRoleEditUseCase.AIgenerateRole.mockResolvedValue(newRoleEntity);
|
||||
|
||||
const regenerateResult = await regenerateRole({
|
||||
prompt: '使用新的提示词重新生成角色',
|
||||
tagTypes: ['tag1'],
|
||||
roleId: 'role1'
|
||||
});
|
||||
expect(regenerateResult.successful).toBe(true);
|
||||
expect(regenerateResult.data.name).toBe('重新生成的角色');
|
||||
|
||||
// 7. 用户操作:获取角色库
|
||||
const mockLibraryRoles = [
|
||||
{ ...mockRoleEntity, id: 'libraryRole1', name: '库角色1' },
|
||||
{ ...mockRoleEntity, id: 'libraryRole2', name: '库角色2' }
|
||||
];
|
||||
(getUserRoleLibrary as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: mockLibraryRoles,
|
||||
});
|
||||
|
||||
const libraryResult = await getUserRoleLibrary();
|
||||
expect(libraryResult.successful).toBe(true);
|
||||
expect(libraryResult.data).toEqual(mockLibraryRoles);
|
||||
|
||||
// 8. 用户操作:从角色库中选择角色替换当前角色
|
||||
const selectedLibraryRole = mockLibraryRoles[0];
|
||||
(replaceRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
const replaceResult = await replaceRole({
|
||||
currentRoleId: 'role1',
|
||||
replaceRoleId: 'libraryRole1'
|
||||
});
|
||||
expect(replaceResult.successful).toBe(true);
|
||||
|
||||
// 9. 用户操作:获取角色应用到的分镜列表
|
||||
const mockShots = [mockShotEntity];
|
||||
(getRoleShots as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: {
|
||||
shots: mockShots,
|
||||
appliedShotIds: [],
|
||||
},
|
||||
});
|
||||
|
||||
const shotsResult = await getRoleShots({ roleId: 'role1' });
|
||||
expect(shotsResult.successful).toBe(true);
|
||||
expect(shotsResult.data.shots).toEqual(mockShots);
|
||||
|
||||
// 10. 用户操作:选择分镜并应用角色
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
mockRoleEditUseCase.applyRole.mockResolvedValue({} as any);
|
||||
|
||||
const applyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1', 'shot2']
|
||||
});
|
||||
expect(applyResult.successful).toBe(true);
|
||||
});
|
||||
|
||||
it('应该验证角色库替换时只保留ID,其他数据都被替换', async () => {
|
||||
// 当前角色
|
||||
const currentRole = {
|
||||
id: 'currentRoleId',
|
||||
name: '当前角色',
|
||||
generateTextId: 'currentTextId',
|
||||
tagIds: ['currentTag1'],
|
||||
imageUrl: 'http://example.com/current.jpg',
|
||||
updatedAt: Date.now(),
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
isStored: false,
|
||||
};
|
||||
|
||||
// 角色库中的角色
|
||||
const libraryRole = {
|
||||
id: 'libraryRoleId',
|
||||
name: '库角色',
|
||||
generateTextId: 'libraryTextId',
|
||||
tagIds: ['libraryTag1', 'libraryTag2'],
|
||||
imageUrl: 'http://example.com/library.jpg',
|
||||
updatedAt: Date.now() + 1000,
|
||||
loadingProgress: 100,
|
||||
disableEdit: false,
|
||||
isStored: true,
|
||||
};
|
||||
|
||||
// 模拟替换操作
|
||||
(replaceRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
const replaceResult = await replaceRole({
|
||||
currentRoleId: currentRole.id,
|
||||
replaceRoleId: libraryRole.id
|
||||
});
|
||||
expect(replaceResult.successful).toBe(true);
|
||||
|
||||
// 验证替换后的角色数据:ID保持不变,其他数据来自库角色
|
||||
const replacedRole = {
|
||||
...libraryRole,
|
||||
id: currentRole.id, // 只有ID保持不变
|
||||
};
|
||||
|
||||
expect(replacedRole.id).toBe(currentRole.id); // ID不变
|
||||
expect(replacedRole.name).toBe(libraryRole.name); // 其他数据来自库角色
|
||||
expect(replacedRole.generateTextId).toBe(libraryRole.generateTextId);
|
||||
expect(replacedRole.tagIds).toEqual(libraryRole.tagIds);
|
||||
expect(replacedRole.imageUrl).toBe(libraryRole.imageUrl);
|
||||
expect(replacedRole.isStored).toBe(libraryRole.isStored);
|
||||
});
|
||||
|
||||
it('应该模拟用户选择角色并修改提示词的完整流程', async () => {
|
||||
// 用户操作:获取项目中的角色列表
|
||||
const mockRoles = [
|
||||
{ ...mockRoleEntity, id: 'role1', name: '角色1' },
|
||||
{ ...mockRoleEntity, id: 'role2', name: '角色2' }
|
||||
];
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: mockRoles,
|
||||
});
|
||||
|
||||
const roleList = await getRoleList({ projectId: 'project1' });
|
||||
expect(roleList.data).toHaveLength(2);
|
||||
|
||||
// 用户操作:选择第一个角色
|
||||
const selectedRoleId = 'role1';
|
||||
(getRoleData as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: {
|
||||
text: mockTextEntity,
|
||||
tags: [mockTagEntity1],
|
||||
},
|
||||
});
|
||||
|
||||
const selectedRoleData = await getRoleData({ roleId: selectedRoleId });
|
||||
expect(selectedRoleData.data.text.id).toBe('text1');
|
||||
|
||||
// 用户操作:修改角色提示词
|
||||
const newPrompt = '我想要一个更加勇敢的角色';
|
||||
(updateText as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { ...mockTextEntity, content: newPrompt },
|
||||
});
|
||||
|
||||
const updatedText = await updateText({
|
||||
textId: 'text1',
|
||||
content: newPrompt
|
||||
});
|
||||
expect(updatedText.data.content).toBe(newPrompt);
|
||||
|
||||
// 用户操作:使用新提示词重新生成角色
|
||||
const regeneratedRole = { ...mockRoleEntity, name: '勇敢的角色' };
|
||||
(regenerateRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: regeneratedRole,
|
||||
});
|
||||
|
||||
const regenerationResult = await regenerateRole({
|
||||
prompt: newPrompt,
|
||||
tagTypes: ['tag1'],
|
||||
roleId: selectedRoleId
|
||||
});
|
||||
expect(regenerationResult.data.name).toBe('勇敢的角色');
|
||||
});
|
||||
|
||||
it('应该处理角色编辑流程中的错误情况', async () => {
|
||||
// 模拟获取角色列表失败
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '获取角色列表失败',
|
||||
});
|
||||
|
||||
const roleListResult = await getRoleList({ projectId: 'project1' });
|
||||
expect(roleListResult.successful).toBe(false);
|
||||
expect(roleListResult.message).toBe('获取角色列表失败');
|
||||
|
||||
// 模拟修改文本失败
|
||||
(updateText as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '修改文本失败',
|
||||
});
|
||||
|
||||
const updateTextResult = await updateText({
|
||||
textId: 'text1',
|
||||
content: '新的文本内容'
|
||||
});
|
||||
expect(updateTextResult.successful).toBe(false);
|
||||
expect(updateTextResult.message).toBe('修改文本失败');
|
||||
|
||||
// 模拟重新生成角色失败
|
||||
(regenerateRole as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '重新生成角色失败',
|
||||
});
|
||||
|
||||
const regenerateResult = await regenerateRole({
|
||||
prompt: '重新生成角色',
|
||||
tagTypes: ['tag1'],
|
||||
roleId: 'role1'
|
||||
});
|
||||
expect(regenerateResult.successful).toBe(false);
|
||||
expect(regenerateResult.message).toBe('重新生成角色失败');
|
||||
|
||||
// 模拟替换角色失败
|
||||
(replaceRole as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '替换角色失败',
|
||||
});
|
||||
|
||||
const replaceResult = await replaceRole({
|
||||
currentRoleId: 'role1',
|
||||
replaceRoleId: 'newRoleId'
|
||||
});
|
||||
expect(replaceResult.successful).toBe(false);
|
||||
expect(replaceResult.message).toBe('替换角色失败');
|
||||
|
||||
// 模拟应用角色失败
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '应用角色失败',
|
||||
});
|
||||
|
||||
const applyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1']
|
||||
});
|
||||
expect(applyResult.successful).toBe(false);
|
||||
expect(applyResult.message).toBe('应用角色失败');
|
||||
});
|
||||
});
|
||||
|
||||
describe('角色库业务流程测试', () => {
|
||||
it('应该完成角色库选择和使用流程:获取角色库→选择角色→替换当前角色→验证数据替换', async () => {
|
||||
// 1. 用户操作:获取用户角色库
|
||||
const mockLibraryRoles = [
|
||||
{ ...mockRoleEntity, id: 'libraryRole1', name: '库角色1', isStored: true },
|
||||
{ ...mockRoleEntity, id: 'libraryRole2', name: '库角色2', isStored: true }
|
||||
];
|
||||
(getUserRoleLibrary as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: mockLibraryRoles,
|
||||
});
|
||||
|
||||
const libraryResult = await getUserRoleLibrary();
|
||||
expect(libraryResult.successful).toBe(true);
|
||||
expect(libraryResult.data).toEqual(mockLibraryRoles);
|
||||
|
||||
// 2. 用户操作:从角色库中选择角色
|
||||
const selectedLibraryRole = mockLibraryRoles[0];
|
||||
expect(selectedLibraryRole.isStored).toBe(true); // 验证是库中的角色
|
||||
|
||||
// 3. 用户操作:替换当前角色
|
||||
(replaceRole as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
const replaceResult = await replaceRole({
|
||||
currentRoleId: 'role1',
|
||||
replaceRoleId: selectedLibraryRole.id
|
||||
});
|
||||
expect(replaceResult.successful).toBe(true);
|
||||
|
||||
// 4. 验证替换后的角色数据:ID保持不变,其他数据来自库角色
|
||||
const currentRoleId = 'role1';
|
||||
const replacedRole = {
|
||||
...selectedLibraryRole,
|
||||
id: currentRoleId, // 只有ID保持不变
|
||||
};
|
||||
|
||||
expect(replacedRole.id).toBe(currentRoleId); // ID不变
|
||||
expect(replacedRole.name).toBe(selectedLibraryRole.name); // 其他数据来自库角色
|
||||
expect(replacedRole.generateTextId).toBe(selectedLibraryRole.generateTextId);
|
||||
expect(replacedRole.tagIds).toEqual(selectedLibraryRole.tagIds);
|
||||
expect(replacedRole.imageUrl).toBe(selectedLibraryRole.imageUrl);
|
||||
expect(replacedRole.isStored).toBe(selectedLibraryRole.isStored);
|
||||
});
|
||||
|
||||
it('应该验证角色库替换的边界情况', async () => {
|
||||
// 测试空角色库
|
||||
(getUserRoleLibrary as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: [],
|
||||
});
|
||||
|
||||
const emptyLibraryResult = await getUserRoleLibrary();
|
||||
expect(emptyLibraryResult.data).toHaveLength(0);
|
||||
|
||||
// 测试替换不存在的角色
|
||||
(replaceRole as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '角色不存在',
|
||||
});
|
||||
|
||||
const invalidReplaceResult = await replaceRole({
|
||||
currentRoleId: 'nonexistentRole',
|
||||
replaceRoleId: 'libraryRole1'
|
||||
});
|
||||
expect(invalidReplaceResult.successful).toBe(false);
|
||||
expect(invalidReplaceResult.message).toBe('角色不存在');
|
||||
});
|
||||
});
|
||||
|
||||
describe('角色应用到分镜业务流程测试', () => {
|
||||
it('应该完成角色应用到分镜的完整流程:获取分镜列表→选择分镜→应用角色→验证应用状态', async () => {
|
||||
// 1. 用户操作:获取角色应用到的分镜列表
|
||||
const mockShots = [
|
||||
{ ...mockShotEntity, id: 'shot1', name: '分镜1' },
|
||||
{ ...mockShotEntity, id: 'shot2', name: '分镜2' },
|
||||
{ ...mockShotEntity, id: 'shot3', name: '分镜3' }
|
||||
];
|
||||
(getRoleShots as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: {
|
||||
shots: mockShots,
|
||||
appliedShotIds: ['shot1'], // 分镜1已经应用了角色
|
||||
},
|
||||
});
|
||||
|
||||
const shotsResult = await getRoleShots({ roleId: 'role1' });
|
||||
expect(shotsResult.successful).toBe(true);
|
||||
expect(shotsResult.data.shots).toEqual(mockShots);
|
||||
expect(shotsResult.data.appliedShotIds).toEqual(['shot1']);
|
||||
|
||||
// 2. 用户操作:选择未应用的分镜
|
||||
const unappliedShots = mockShots.filter(shot => !shotsResult.data.appliedShotIds.includes(shot.id));
|
||||
expect(unappliedShots).toHaveLength(2); // shot2, shot3 未应用
|
||||
|
||||
// 3. 用户操作:应用角色到选中的分镜
|
||||
const selectedShotIds = ['shot2', 'shot3'];
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
mockRoleEditUseCase.applyRole.mockResolvedValue({} as any);
|
||||
|
||||
const applyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: selectedShotIds
|
||||
});
|
||||
expect(applyResult.successful).toBe(true);
|
||||
|
||||
// 4. 验证应用后的状态
|
||||
const updatedAppliedShotIds = ['shot1', 'shot2', 'shot3']; // 所有分镜都已应用
|
||||
expect(updatedAppliedShotIds).toContain('shot1'); // 原来已应用的
|
||||
expect(updatedAppliedShotIds).toContain('shot2'); // 新应用的
|
||||
expect(updatedAppliedShotIds).toContain('shot3'); // 新应用的
|
||||
});
|
||||
|
||||
it('应该处理分镜应用的各种情况', async () => {
|
||||
// 测试应用空分镜列表
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: true,
|
||||
data: { success: true },
|
||||
});
|
||||
|
||||
const emptyApplyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: []
|
||||
});
|
||||
expect(emptyApplyResult.successful).toBe(true);
|
||||
|
||||
// 测试应用单个分镜
|
||||
const singleApplyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1']
|
||||
});
|
||||
expect(singleApplyResult.successful).toBe(true);
|
||||
|
||||
// 测试应用多个分镜
|
||||
const multipleApplyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1', 'shot2', 'shot3']
|
||||
});
|
||||
expect(multipleApplyResult.successful).toBe(true);
|
||||
});
|
||||
|
||||
it('应该处理分镜应用失败的情况', async () => {
|
||||
// 测试应用失败
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '应用角色失败',
|
||||
});
|
||||
|
||||
const failedApplyResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1']
|
||||
});
|
||||
expect(failedApplyResult.successful).toBe(false);
|
||||
expect(failedApplyResult.message).toBe('应用角色失败');
|
||||
|
||||
// 测试部分分镜应用失败
|
||||
(applyRoleToShots as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '部分分镜应用失败',
|
||||
});
|
||||
|
||||
const partialFailedResult = await applyRoleToShots({
|
||||
roleId: 'role1',
|
||||
shotIds: ['shot1', 'shot2']
|
||||
});
|
||||
expect(partialFailedResult.successful).toBe(false);
|
||||
expect(partialFailedResult.message).toBe('部分分镜应用失败');
|
||||
});
|
||||
});
|
||||
|
||||
describe('UseCase业务逻辑测试', () => {
|
||||
it('RoleEditUseCase应该正确初始化', () => {
|
||||
const roleItem = new RoleItem(mockRoleEntity);
|
||||
const useCase = new RoleEditUseCase(roleItem);
|
||||
|
||||
expect(RoleEditUseCase).toHaveBeenCalledWith(roleItem);
|
||||
expect(useCase).toBeDefined();
|
||||
});
|
||||
|
||||
it('TextEditUseCase应该正确初始化', () => {
|
||||
const textItem = new TextItem(mockTextEntity);
|
||||
const useCase = new TextEditUseCase(textItem);
|
||||
|
||||
expect(TextEditUseCase).toHaveBeenCalledWith(textItem);
|
||||
expect(useCase).toBeDefined();
|
||||
});
|
||||
|
||||
it('TagEditUseCase应该正确初始化', () => {
|
||||
const tagItem = new TagItem(mockTagEntity1);
|
||||
const useCase = new TagEditUseCase(tagItem);
|
||||
|
||||
expect(TagEditUseCase).toHaveBeenCalledWith(tagItem);
|
||||
expect(useCase).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Domain实体测试', () => {
|
||||
it('RoleItem应该正确包装RoleEntity', () => {
|
||||
const roleItem = new RoleItem(mockRoleEntity);
|
||||
|
||||
expect(RoleItem).toHaveBeenCalledWith(mockRoleEntity);
|
||||
expect(roleItem.entity).toEqual(mockRoleEntity);
|
||||
expect(roleItem.disableEdit).toBe(false);
|
||||
});
|
||||
|
||||
it('TextItem应该正确包装AITextEntity', () => {
|
||||
const textItem = new TextItem(mockTextEntity);
|
||||
|
||||
expect(TextItem).toHaveBeenCalledWith(mockTextEntity);
|
||||
expect(textItem.entity).toEqual(mockTextEntity);
|
||||
expect(textItem.disableEdit).toBe(false);
|
||||
});
|
||||
|
||||
it('TagItem应该正确包装TagEntity', () => {
|
||||
const tagItem = new TagItem(mockTagEntity1);
|
||||
|
||||
expect(TagItem).toHaveBeenCalledWith(mockTagEntity1);
|
||||
expect(tagItem.entity).toEqual(mockTagEntity1);
|
||||
expect(tagItem.disableEdit).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('错误处理测试', () => {
|
||||
it('API调用失败时应该正确处理错误', async () => {
|
||||
(getRoleList as jest.Mock).mockRejectedValue(new Error('网络错误'));
|
||||
|
||||
await expect(getRoleList({ projectId: 'project1' })).rejects.toThrow('网络错误');
|
||||
});
|
||||
|
||||
it('API返回失败状态时应该正确处理', async () => {
|
||||
(getRoleList as jest.Mock).mockResolvedValue({
|
||||
successful: false,
|
||||
message: '服务器错误',
|
||||
});
|
||||
|
||||
const result = await getRoleList({ projectId: 'project1' });
|
||||
|
||||
expect(result.successful).toBe(false);
|
||||
expect(result.message).toBe('服务器错误');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
@ -163,11 +163,12 @@ export class ScriptEditUseCase {
|
||||
|
||||
// 获取当前剧本文本
|
||||
const scriptText = this.scriptValueObject.toString();
|
||||
|
||||
const User = JSON.parse(localStorage.getItem("currentUser") || "{}");
|
||||
// 调用保存剧本API
|
||||
const response = await saveScript({
|
||||
project_id: projectId,
|
||||
generated_script: scriptText,
|
||||
user_id: User?.id || "",
|
||||
});
|
||||
|
||||
if (!response.successful) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user