mxivideo/tests/textVideoAgentAPI.test.ts

443 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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 {}