/** * 测试数据工厂 * 提供创建/清理测试数据的统一方法 */ import { apiPost, apiDelete, apiGet, apiPut } from './api-client'; /** 已创建的测试资源追踪(测试结束后统一清理) */ const createdResources: { type: string; id: string | number; cleanup: () => Promise }[] = []; /** 注册需要清理的资源 */ export function trackResource(type: string, id: string | number, cleanup: () => Promise) { createdResources.push({ type, id, cleanup }); } /** 获取所有待清理资源数量 */ export function getTrackedCount(): number { return createdResources.length; } /** 清理所有已追踪的资源(倒序清理,先删子资源) */ export async function cleanupAllResources() { console.log(` [cleanup] 清理 ${createdResources.length} 个测试资源...`); // 倒序清理 const reversed = [...createdResources].reverse(); for (const resource of reversed) { try { await resource.cleanup(); } catch (e: any) { console.warn(` [cleanup] 清理失败 ${resource.type}#${resource.id}: ${e.message}`); } } createdResources.length = 0; } // ============ 用户相关 ============ /** 测试手机号计数器 */ let phoneCounter = 13800000000; /** 获取一个唯一的测试手机号 */ function nextPhone(): string { phoneCounter++; return String(phoneCounter); } /** 注册并登录一个测试用户,返回 token */ export async function createTestUser(): Promise<{ token: string; userId: string; phone: string }> { const phone = nextPhone(); // 发送验证码 const codeRes = await apiPost('/api/auth/send-code', { phone }); const code = codeRes.data?.code || '123456'; // 登录 const loginRes = await apiPost('/api/auth/login', { phone, code }); const token = loginRes.data?.token; const userId = loginRes.data?.user?.id || loginRes.data?.userId; if (!token) throw new Error(`创建测试用户失败: ${JSON.stringify(loginRes)}`); trackResource('user', userId, async () => { // 用户通常不直接删除,由数据库清理 }); return { token, userId: String(userId), phone }; } // ============ 书籍相关 ============ /** 创建测试书籍 */ export async function createTestBook(token?: string): Promise<{ bookId: number }> { const res = await apiPost('/api/book-generator/langgraph/books', { title: `[自动化测试] 测试书籍 ${Date.now()}`, description: '由自动化测试创建的临时书籍', }); const bookId = res.data?.id || res.data?.book?.id; if (!bookId) throw new Error(`创建测试书籍失败: ${JSON.stringify(res)}`); trackResource('book', bookId, async () => { await apiDelete(`/api/book-generator/langgraph/books/${bookId}`); }); return { bookId }; } // ============ 音频相关 ============ /** 创建测试音频记录(不实际生成音频) */ export async function createTestAudio(text?: string): Promise<{ audioId: string }> { const res = await apiPost('/api/tts/generate', { text: text || '[自动化测试] 测试文本', voiceId: 'Cherry', voiceParams: { speed: 1.0, pitch: 0, volume: 50 }, }); const audioId = res.data?.audioId || res.data?.id; if (!audioId) throw new Error(`创建测试音频失败: ${JSON.stringify(res)}`); trackResource('audio', audioId, async () => { // 音频记录通常不直接删除 }); return { audioId }; } // ============ 视频相关 ============ /** 创建测试视频项目 */ export async function createTestVideoProject(): Promise<{ projectId: number }> { const res = await apiPost('/api/video/projects', { title: `[自动化测试] 视频项目 ${Date.now()}`, }); const projectId = res.data?.id || res.data?.project?.id; if (!projectId) throw new Error(`创建测试视频项目失败: ${JSON.stringify(res)}`); trackResource('videoProject', projectId, async () => { await apiDelete(`/api/video/projects/${projectId}`); }); return { projectId }; } // ============ 专辑相关 ============ /** 创建测试专辑 */ export async function createTestAlbum(): Promise<{ albumId: number }> { const res = await apiPost('/api/book-generator/albums', { name: `[自动化测试] 专辑 ${Date.now()}`, description: '由自动化测试创建的临时专辑', }); const albumId = res.data?.id || res.data?.album?.id; if (!albumId) throw new Error(`创建测试专辑失败: ${JSON.stringify(res)}`); trackResource('album', albumId, async () => { await apiDelete(`/api/book-generator/albums/${albumId}`); }); return { albumId }; } // ============ 播放列表相关 ============ /** 创建测试播放列表 */ export async function createTestPlaylist(): Promise<{ playlistId: number }> { const res = await apiPost('/api/playlists', { name: `[自动化测试] 播放列表 ${Date.now()}`, }); const playlistId = res.data?.id || res.data?.playlist?.id; if (!playlistId) throw new Error(`创建测试播放列表失败: ${JSON.stringify(res)}`); trackResource('playlist', playlistId, async () => { await apiDelete(`/api/playlists/${playlistId}`); }); return { playlistId }; } // ============ 收藏相关 ============ /** 收藏一个音频 */ export async function createTestFavorite(audioId: string | number): Promise { await apiPost('/api/favorites', { audioId: String(audioId) }); trackResource('favorite', audioId, async () => { await apiDelete(`/api/favorites/${audioId}`); }); } // ============ 评论相关 ============ /** 创建测试评论 */ export async function createTestComment(audioId: string | number, content?: string): Promise<{ commentId: number }> { const res = await apiPost('/api/comments', { audioId: String(audioId), content: content || '[自动化测试] 测试评论', }); const commentId = res.data?.id || res.data?.comment?.id; if (!commentId) throw new Error(`创建测试评论失败: ${JSON.stringify(res)}`); trackResource('comment', commentId, async () => { await apiDelete(`/api/comments/${commentId}`); }); return { commentId }; } // ============ 草稿相关 ============ /** 创建测试草稿 */ export async function createTestDraft(): Promise<{ draftId: number }> { const res = await apiPost('/api/drafts', { type: 'tts', data: { text: '[自动化测试] 草稿内容', voiceId: 'Cherry' }, }); const draftId = res.data?.id || res.data?.draft?.id; if (!draftId) throw new Error(`创建测试草稿失败: ${JSON.stringify(res)}`); trackResource('draft', draftId, async () => { await apiDelete(`/api/drafts/${draftId}`); }); return { draftId }; }