feat:Strengthen the testing framework
This commit is contained in:
121
tests/system/generate-video.system.test.ts
Normal file
121
tests/system/generate-video.system.test.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { callRoute } from '../integration/api/helpers/call-route'
|
||||
import { installAuthMocks, mockAuthenticated, resetAuthMockState } from '../helpers/auth'
|
||||
import { resetSystemState } from '../helpers/db-reset'
|
||||
import { prisma } from '../helpers/prisma'
|
||||
import { seedMinimalDomainState } from './helpers/seed'
|
||||
import { expectLifecycleEvents, listTaskEventTypes, waitForTaskTerminalState } from './helpers/tasks'
|
||||
import { startSystemWorkers, stopSystemWorkers, type SystemWorkers } from './helpers/workers'
|
||||
|
||||
type PollState = {
|
||||
status: 'processing' | 'completed'
|
||||
resultUrl?: string
|
||||
}
|
||||
|
||||
const videoState = vi.hoisted(() => ({
|
||||
pollResponses: new Map<string, PollState[]>(),
|
||||
uploadedCosKey: 'video/system-video.mp4',
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/generator-api', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/lib/generator-api')>('@/lib/generator-api')
|
||||
return {
|
||||
...actual,
|
||||
generateVideo: vi.fn(async () => ({
|
||||
success: true,
|
||||
async: true,
|
||||
externalId: 'video-ext-1',
|
||||
})),
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/lib/async-poll', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/lib/async-poll')>('@/lib/async-poll')
|
||||
return {
|
||||
...actual,
|
||||
pollAsyncTask: vi.fn(async (externalId: string) => {
|
||||
const queue = videoState.pollResponses.get(externalId) || []
|
||||
const next = queue.shift()
|
||||
if (!next) {
|
||||
return { status: 'completed', resultUrl: 'https://provider.example/video-final.mp4' }
|
||||
}
|
||||
videoState.pollResponses.set(externalId, queue)
|
||||
return next
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/lib/media/outbound-image', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/lib/media/outbound-image')>('@/lib/media/outbound-image')
|
||||
return {
|
||||
...actual,
|
||||
normalizeToBase64ForGeneration: vi.fn(async (input: string) => input),
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/lib/workers/utils', async () => {
|
||||
const actual = await vi.importActual<typeof import('@/lib/workers/utils')>('@/lib/workers/utils')
|
||||
return {
|
||||
...actual,
|
||||
uploadVideoSourceToCos: vi.fn(async () => videoState.uploadedCosKey),
|
||||
}
|
||||
})
|
||||
|
||||
describe('system - generate video', () => {
|
||||
let workers: SystemWorkers = {}
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.resetModules()
|
||||
vi.clearAllMocks()
|
||||
videoState.uploadedCosKey = 'video/system-video.mp4'
|
||||
videoState.pollResponses.clear()
|
||||
videoState.pollResponses.set('video-ext-1', [
|
||||
{ status: 'processing' },
|
||||
{ status: 'completed', resultUrl: 'https://provider.example/video-final.mp4' },
|
||||
])
|
||||
await resetSystemState()
|
||||
installAuthMocks()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await stopSystemWorkers(workers)
|
||||
workers = {}
|
||||
resetAuthMockState()
|
||||
})
|
||||
|
||||
it('queued external generation -> polling -> videoUrl persisted', async () => {
|
||||
const seeded = await seedMinimalDomainState()
|
||||
mockAuthenticated(seeded.user.id)
|
||||
workers = await startSystemWorkers(['video'])
|
||||
|
||||
const mod = await import('@/app/api/novel-promotion/[projectId]/generate-video/route')
|
||||
const response = await callRoute(
|
||||
mod.POST,
|
||||
'POST',
|
||||
{
|
||||
locale: 'zh',
|
||||
storyboardId: seeded.storyboard.id,
|
||||
panelIndex: 0,
|
||||
videoModel: 'fal::seedance/video',
|
||||
},
|
||||
{ params: { projectId: seeded.project.id } },
|
||||
)
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
const json = await response.json() as { async: boolean; taskId: string }
|
||||
const task = await waitForTaskTerminalState(json.taskId)
|
||||
|
||||
expect(task.status).toBe('completed')
|
||||
expect(task.type).toBe('video_panel')
|
||||
expect(task.externalId).toBe('video-ext-1')
|
||||
|
||||
const panel = await prisma.novelPromotionPanel.findUnique({
|
||||
where: { id: seeded.panel.id },
|
||||
select: { videoUrl: true },
|
||||
})
|
||||
expect(panel?.videoUrl).toBe(videoState.uploadedCosKey)
|
||||
|
||||
const eventTypes = await listTaskEventTypes(json.taskId)
|
||||
expectLifecycleEvents(eventTypes, 'completed')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user