添加 文生图

This commit is contained in:
root
2025-07-11 13:47:27 +08:00
parent e2ffc87d53
commit fb5cf0f8f1
12 changed files with 3229 additions and 5 deletions

View File

@@ -0,0 +1,442 @@
/**
* Text Video Agent API 测试文件
*/
import { textVideoAgentAPI, TextVideoAgentAPI } from '../src/services/textVideoAgentAPI'
import { TaskType, AspectRatio, VideoDuration } from '../src/services/textVideoAgentTypes'
// Mock fetch for testing
global.fetch = jest.fn()
describe('TextVideoAgentAPI', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('基础功能测试', () => {
test('健康检查', async () => {
const mockResponse = {
status: true,
msg: 'Service is healthy'
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.healthCheck()
expect(fetch).toHaveBeenCalledWith(
expect.stringContaining('/health'),
expect.any(Object)
)
expect(result).toEqual(mockResponse)
})
test('获取示例提示词', async () => {
const mockResponse = {
status: true,
msg: 'Success',
data: {
prompts: ['示例提示词1', '示例提示词2']
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.getSamplePrompt(TaskType.VLOG)
expect(fetch).toHaveBeenCalledWith(
expect.stringContaining('/api/prompt/default?task_type=vlog'),
expect.any(Object)
)
expect(result).toEqual(mockResponse)
})
})
describe('图片生成测试', () => {
test('同步生成图片', async () => {
const mockResponse = {
status: true,
msg: 'Image generated successfully',
data: {
image_url: 'https://example.com/generated-image.jpg'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.generateImageSync({
prompt: '测试图片生成',
max_wait_time: 60
})
expect(result).toEqual(mockResponse)
expect(result.data?.image_url).toBe('https://example.com/generated-image.jpg')
})
test('异步生成图片', async () => {
const mockResponse = {
status: true,
msg: 'Task submitted',
data: {
task_id: 'test-task-123'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.generateImageAsync('测试异步图片生成')
expect(result).toEqual(mockResponse)
expect(result.data?.task_id).toBe('test-task-123')
})
test('带重试的图片生成', async () => {
// 第一次失败
;(fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'))
// 第二次成功
const mockResponse = {
status: true,
msg: 'Image generated successfully',
data: {
image_url: 'https://example.com/generated-image.jpg'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.generateImageWithRetry({
prompt: '测试重试机制',
max_wait_time: 60
}, 2)
expect(fetch).toHaveBeenCalledTimes(2)
expect(result).toEqual(mockResponse)
})
})
describe('视频生成测试', () => {
test('同步生成视频', async () => {
const mockResponse = {
status: true,
msg: 'Video generated successfully',
data: {
video_url: 'https://example.com/generated-video.mp4'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.generateVideoSync({
prompt: '测试视频生成',
img_url: 'https://example.com/base-image.jpg',
duration: '5'
})
expect(result).toEqual(mockResponse)
expect(result.data?.video_url).toBe('https://example.com/generated-video.mp4')
})
test('异步生成视频', async () => {
const mockResponse = {
status: true,
msg: 'Video task submitted',
data: {
task_id: 'video-task-456'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.generateVideoAsync({
prompt: '测试异步视频生成',
duration: '5'
})
expect(result).toEqual(mockResponse)
expect(result.data?.task_id).toBe('video-task-456')
})
})
describe('任务管理测试', () => {
test('创建任务', async () => {
const mockResponse = {
status: true,
msg: 'Task created successfully',
data: {
task_id: 'new-task-789'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.createTask({
task_type: TaskType.VLOG,
prompt: '测试任务创建',
ar: AspectRatio.PORTRAIT
})
expect(result).toEqual(mockResponse)
expect(result.data?.task_id).toBe('new-task-789')
})
test('查询任务状态', async () => {
const mockResponse = {
status: true,
msg: 'Task status retrieved',
data: {
task_id: 'test-task-123',
status: 'completed',
progress: 100,
result: {
image_url: 'https://example.com/result.jpg'
}
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.getTaskStatusAsync('test-task-123')
expect(result).toEqual(mockResponse)
expect(result.data?.status).toBe('completed')
})
})
describe('文件操作测试', () => {
test('文件上传', async () => {
const mockResponse = {
status: true,
msg: 'File uploaded successfully',
data: 'https://example.com/uploaded-file.jpg'
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' })
const result = await textVideoAgentAPI.uploadFile(mockFile)
expect(result).toEqual(mockResponse)
expect(result.data).toBe('https://example.com/uploaded-file.jpg')
})
})
describe('图片描述测试', () => {
test('通过URL描述图片', async () => {
const mockResponse = {
status: true,
msg: 'Image described successfully',
data: {
description: '这是一张美丽的风景照片'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const result = await textVideoAgentAPI.describeImageByUrl({
image_url: 'https://example.com/image.jpg'
})
expect(result).toEqual(mockResponse)
expect(result.data?.description).toBe('这是一张美丽的风景照片')
})
test('通过文件描述图片', async () => {
const mockResponse = {
status: true,
msg: 'Image described successfully',
data: {
description: '这是一张人物照片'
}
}
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => mockResponse
})
const mockFile = new File(['image content'], 'portrait.jpg', { type: 'image/jpeg' })
const result = await textVideoAgentAPI.describeImageByFile({
img_file: mockFile
})
expect(result).toEqual(mockResponse)
expect(result.data?.description).toBe('这是一张人物照片')
})
})
describe('高级功能测试', () => {
test('端到端内容生成', async () => {
// Mock 创建任务
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => ({
status: true,
data: { task_id: 'end-to-end-task' }
})
})
// Mock 图片生成
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => ({
status: true,
data: { image_url: 'https://example.com/generated.jpg' }
})
})
// Mock 视频生成
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => ({
status: true,
data: { video_url: 'https://example.com/generated.mp4' }
})
})
const result = await textVideoAgentAPI.generateContentEndToEnd(
'测试端到端生成',
{
taskType: TaskType.VLOG,
aspectRatio: AspectRatio.PORTRAIT,
videoDuration: VideoDuration.MEDIUM,
generateVideo: true
}
)
expect(result).toEqual({
imageUrl: 'https://example.com/generated.jpg',
videoUrl: 'https://example.com/generated.mp4',
taskId: 'end-to-end-task'
})
})
test('轮询任务直到完成', async () => {
// 第一次查询 - 进行中
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => ({
status: true,
data: { status: 'running', progress: 50 }
})
})
// 第二次查询 - 完成
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: true,
json: async () => ({
status: true,
data: {
status: 'completed',
progress: 100,
result: { image_url: 'https://example.com/final.jpg' }
}
})
})
const progressCallback = jest.fn()
const result = await textVideoAgentAPI.pollTaskUntilComplete(
'test-task-id',
100, // 快速轮询用于测试
5000, // 5秒超时
progressCallback
)
expect(fetch).toHaveBeenCalledTimes(2)
expect(progressCallback).toHaveBeenCalledTimes(2)
expect(result.data?.status).toBe('completed')
})
})
describe('错误处理测试', () => {
test('网络错误处理', async () => {
;(fetch as jest.Mock).mockRejectedValueOnce(new Error('Network error'))
await expect(textVideoAgentAPI.healthCheck()).rejects.toThrow('Network error')
})
test('HTTP错误处理', async () => {
;(fetch as jest.Mock).mockResolvedValueOnce({
ok: false,
status: 500,
json: async () => ({ error: 'Internal server error' })
})
await expect(textVideoAgentAPI.healthCheck()).rejects.toThrow('HTTP error! status: 500')
})
test('参数验证', async () => {
await expect(
textVideoAgentAPI.describeImageByUrl({} as any)
).rejects.toThrow('image_url is required')
await expect(
textVideoAgentAPI.describeImageByFile({} as any)
).rejects.toThrow('img_file is required')
})
})
describe('自定义配置测试', () => {
test('自定义API端点', () => {
const customAPI = new TextVideoAgentAPI('https://custom-endpoint.com')
expect(customAPI).toBeInstanceOf(TextVideoAgentAPI)
})
})
})
// 集成测试需要真实API
describe('集成测试 (需要真实API)', () => {
// 这些测试需要真实的API端点通常在CI/CD环境中跳过
const shouldRunIntegrationTests = process.env.RUN_INTEGRATION_TESTS === 'true'
test.skipIf(!shouldRunIntegrationTests)('真实健康检查', async () => {
const result = await textVideoAgentAPI.healthCheck()
expect(result.status).toBe(true)
})
test.skipIf(!shouldRunIntegrationTests)('真实图片生成', async () => {
const result = await textVideoAgentAPI.generateImageSync({
prompt: '一朵美丽的花',
max_wait_time: 60
})
expect(result.status).toBe(true)
expect(result.data?.image_url).toBeDefined()
}, 120000) // 2分钟超时
})
export {}