import { test } from 'node:test' import assert from 'node:assert/strict' import { http } from '../src/shared/api/http.ts' import { getImageVideoSecretStatus, saveImageVideoSecrets, runImageVideoDouyinCopy, runImageVideoWorkflow, getImageVideoWorkflowResult, getImageVideoAsyncTask, uploadImageVideoMedia, listImageVideoVoices, deleteImageVideoVoice, cloneImageVideoVoice, synthesizeImageVideoVoice, } from '../src/shared/api/types/modules/image-video.ts' import { expandBrandFolderRecursive, getBrandTasks, createBrandTask, getBrandTaskEventsUrl, } from '../src/shared/api/types/modules/brand.ts' import { getCurrentUserAppColumnKeys, type PermissionMenuItem, } from '../src/shared/api/types/modules/permission.ts' import { getDigitalHumanVersions, releaseDigitalHumanVersion, getDigitalHumanVersionDownloadUrl, } from '../src/shared/api/types/modules/digital-human.ts' function setupWindow() { const store = new Map([['uid', '42']]) ;(globalThis as Record).window = { localStorage: { getItem: (key: string) => store.get(key) ?? null, setItem: (key: string, value: string) => void store.set(key, value), }, location: { origin: 'http://localhost' }, } } function mockRequest( t: Parameters[1] extends (t: infer T) => unknown ? T : never, impl: (config: { url?: string; method?: string; params?: Record; data?: unknown; timeout?: number }) => Promise, ) { t.mock.method(http, 'request', impl as never) } const okResponse = (data: unknown) => Promise.resolve({ data: { success: true, message: 'ok', data } }) test('test_image_video_secrets', async (t) => { setupWindow() const calls: { url?: string; method?: string; params?: Record; data?: unknown }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ userId: 42, configured: true }) }) await getImageVideoSecretStatus() await saveImageVideoSecrets({ expireDays: 30 }) assert.equal(calls[0].url, '/newApi/api/image-video/secrets') assert.deepEqual(calls[0].params, { user_id: 42 }) assert.equal(calls[1].url, '/newApi/api/image-video/secrets') assert.equal(calls[1].method, 'PUT') assert.deepEqual(calls[1].data, { expireDays: 30, userId: 42 }) }) test('test_image_video_workflow', async (t) => { setupWindow() const calls: { url?: string; method?: string; data?: unknown }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ taskId: 1, taskType: 'workflow', status: 'RUNNING' }) }) const params = { api_key_info: { t8star_key: 'a', t8_video_key: 'b', ai_conductor_key: 'c' } } await runImageVideoWorkflow(params as never) await getImageVideoWorkflowResult('exec-1') assert.equal(calls[0].url, '/newApi/api/image-video/workflow/run') assert.equal(calls[0].method, 'POST') assert.deepEqual(calls[0].data, { userId: 42, parameters: params }) assert.equal(calls[1].url, '/newApi/api/image-video/workflow/result') assert.deepEqual(calls[1].data, { userId: 42, executeId: 'exec-1' }) }) test('test_image_video_douyin_async', async (t) => { setupWindow() const calls: { url?: string; method?: string; data?: unknown; params?: Record }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ taskId: 2, taskType: 'copy', status: 'PENDING' }) }) await runImageVideoDouyinCopy({ url: 'https://x.com/v' }) await getImageVideoAsyncTask(7) assert.equal(calls[0].url, '/newApi/api/image-video/douyin-copy') assert.equal(calls[0].method, 'POST') assert.deepEqual(calls[0].data, { userId: 42, url: 'https://x.com/v' }) assert.equal(calls[1].url, '/newApi/api/image-video/tasks/7') assert.deepEqual(calls[1].params, { user_id: 42 }) }) test('test_image_video_voice', async (t) => { setupWindow() const calls: { url?: string; method?: string; data?: unknown }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ taskId: 3, taskType: 'voice', status: 'SUCCESS' }) }) await listImageVideoVoices('v1') await deleteImageVideoVoice('vid-1') await cloneImageVideoVoice({ name: 'clone' }) await synthesizeImageVideoVoice({ text: '你好', voiceId: 'vid-1' }) assert.equal(calls[0].url, '/newApi/api/image-video/voice/list') assert.deepEqual(calls[0].data, { userId: 42, name: 'v1' }) assert.equal(calls[1].url, '/newApi/api/image-video/voice/delete') assert.deepEqual(calls[1].data, { userId: 42, voiceId: 'vid-1' }) assert.equal(calls[2].url, '/newApi/api/image-video/voice/clone') assert.deepEqual(calls[2].data, { userId: 42, name: 'clone' }) assert.equal(calls[3].url, '/newApi/api/image-video/voice/synthesis') assert.deepEqual(calls[3].data, { userId: 42, text: '你好', voiceId: 'vid-1' }) }) test('test_image_video_upload_media', async (t) => { setupWindow() const calls: { url?: string; method?: string; data?: unknown }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ url: 'https://oss/x', objectKey: 'k1', originalFilename: 'a.png', mediaType: 'image' }) }) const file = new File(['x'], 'a.png', { type: 'image/png' }) const result = await uploadImageVideoMedia(file) assert.equal(calls[0].url, '/newApi/api/files/upload') assert.equal(calls[0].method, 'POST') assert.ok(calls[0].data instanceof FormData) assert.deepEqual(result, { url: 'https://oss/x', objectKey: 'k1', originalFilename: 'a.png', mediaType: 'image' }) }) test('test_brand_tasks', async (t) => { setupWindow() const calls: { url?: string; method?: string; data?: unknown }[] = [] mockRequest(t, (config) => { calls.push(config) return Promise.resolve({ data: { success: true, items: [{ id: 1 }] } }) }) await getBrandTasks() await createBrandTask(['/tmp/a'], 'STRATEGY_A') await expandBrandFolderRecursive('/tmp/a') assert.equal(calls[0].url, '/api/brand/tasks?userId=42') assert.equal(calls[0].method, 'GET') assert.equal(calls[1].url, '/api/brand/tasks?userId=42') assert.equal(calls[1].method, 'POST') assert.deepEqual(calls[1].data, { files: ['/tmp/a'], strategy: 'STRATEGY_A', taskType: 2 }) assert.equal(calls[2].url, '/api/brand/expand-folder-recursive') assert.equal(calls[2].method, 'POST') assert.deepEqual(calls[2].data, { folder: '/tmp/a' }) assert.equal( getBrandTaskEventsUrl(7), '/api/brand/tasks/7/events?user_id=42', ) }) test('test_permission_column_keys', async (t) => { setupWindow() mockRequest(t, () => Promise.resolve({ data: { success: true, data: [{ column_key: 'collect-data' }, { columnKey: 'Shop-Match' }] }, }), ) const keys = await getCurrentUserAppColumnKeys() assert.deepEqual(keys, ['collect-data', 'shop-match']) }) test('test_digital_human_versions', async (t) => { setupWindow() const calls: { url?: string; method?: string; params?: Record }[] = [] mockRequest(t, (config) => { calls.push(config) return okResponse({ records: [{ id: 1, version: '1.0.0' }], total: 1 }) }) await getDigitalHumanVersions({ page: 1, pageSize: 10 }) await releaseDigitalHumanVersion('1.0.0') await getDigitalHumanVersionDownloadUrl('1.0.0') assert.equal(calls[0].url, '/newApi/api/digital-human/versions') assert.deepEqual(calls[0].params, { page: 1, pageSize: 10 }) assert.equal(calls[1].url, '/newApi/api/digital-human/versions/1.0.0/release') assert.equal(calls[1].method, 'POST') assert.equal(calls[2].url, '/newApi/api/digital-human/versions/1.0.0/download-url') }) test('test_image_video_export_compat', async (t) => { setupWindow() const fromJavaModules = await import('../src/shared/api/java-modules.ts') const fromImageVideo = await import('../src/shared/api/types/modules/image-video.ts') const imageVideoNames = [ 'getImageVideoSecretStatus', 'saveImageVideoSecrets', 'runImageVideoDouyinCopy', 'runImageVideoWorkflow', 'getImageVideoWorkflowResult', 'getImageVideoAsyncTask', 'uploadImageVideoMedia', 'listImageVideoVoices', 'deleteImageVideoVoice', 'cloneImageVideoVoice', 'synthesizeImageVideoVoice', ] for (const name of imageVideoNames) { assert.equal(fromJavaModules[name], fromImageVideo[name], `${name} 应为同一引用`) } const fromBrand = await import('../src/shared/api/types/modules/brand.ts') assert.equal(typeof fromBrand.expandBrandFolderRecursive, 'function') const item: PermissionMenuItem = { id: 1, column_key: 'x' } assert.equal(item.column_key, 'x') }) test('test_image_video_unwrap_and_error', async (t) => { setupWindow() mockRequest(t, () => okResponse({ taskId: 1, taskType: 't', status: 'RUNNING' })) const result = await getImageVideoAsyncTask(1) assert.equal(result.taskId, 1) mockRequest(t, () => Promise.resolve({ data: { success: false, message: '密钥未配置' } })) await assert.rejects(getImageVideoSecretStatus(), /密钥未配置/) })