Files
waooplus/tests/unit/generator-api-openai-template-required.test.ts
2026-03-08 17:10:06 +08:00

106 lines
3.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const resolveModelSelectionMock = vi.hoisted(() =>
vi.fn(async () => ({
provider: 'openai-compatible:oa-1',
modelId: 'gpt-image-1',
modelKey: 'openai-compatible:oa-1::gpt-image-1',
mediaType: 'image',
compatMediaTemplate: undefined,
})),
)
const getProviderConfigMock = vi.hoisted(() =>
vi.fn(async () => ({
id: 'openai-compatible:oa-1',
name: 'OpenAI Compat',
apiKey: 'oa-key',
gatewayRoute: 'openai-compat' as const,
})),
)
const resolveModelGatewayRouteMock = vi.hoisted(() => vi.fn(() => 'openai-compat'))
const generateImageViaOpenAICompatMock = vi.hoisted(() => vi.fn(async () => ({ success: true, imageUrl: 'image' })))
const generateVideoViaOpenAICompatMock = vi.hoisted(() => vi.fn(async () => ({ success: true, videoUrl: 'video' })))
const generateImageViaOpenAICompatTemplateMock = vi.hoisted(() => vi.fn(async () => ({ success: true, imageUrl: 'image' })))
const generateVideoViaOpenAICompatTemplateMock = vi.hoisted(() => vi.fn(async () => ({ success: true, videoUrl: 'video' })))
vi.mock('@/lib/api-config', () => ({
resolveModelSelection: resolveModelSelectionMock,
getProviderConfig: getProviderConfigMock,
getProviderKey: (providerId: string) => providerId.split(':')[0] || providerId,
}))
vi.mock('@/lib/model-gateway', () => ({
resolveModelGatewayRoute: resolveModelGatewayRouteMock,
generateImageViaOpenAICompat: generateImageViaOpenAICompatMock,
generateVideoViaOpenAICompat: generateVideoViaOpenAICompatMock,
generateImageViaOpenAICompatTemplate: generateImageViaOpenAICompatTemplateMock,
generateVideoViaOpenAICompatTemplate: generateVideoViaOpenAICompatTemplateMock,
}))
vi.mock('@/lib/generators/factory', () => ({
createImageGenerator: vi.fn(() => ({ generate: vi.fn() })),
createVideoGenerator: vi.fn(() => ({ generate: vi.fn() })),
createAudioGenerator: vi.fn(() => ({ generate: vi.fn() })),
}))
vi.mock('@/lib/providers/bailian', () => ({
generateBailianImage: vi.fn(),
generateBailianVideo: vi.fn(),
generateBailianAudio: vi.fn(),
}))
vi.mock('@/lib/providers/siliconflow', () => ({
generateSiliconFlowImage: vi.fn(),
generateSiliconFlowVideo: vi.fn(),
generateSiliconFlowAudio: vi.fn(),
}))
import { generateImage, generateVideo } from '@/lib/generator-api'
describe('generator-api requires compat media template for openai-compatible media', () => {
beforeEach(() => {
vi.clearAllMocks()
resolveModelGatewayRouteMock.mockReturnValue('openai-compat')
getProviderConfigMock.mockResolvedValue({
id: 'openai-compatible:oa-1',
name: 'OpenAI Compat',
apiKey: 'oa-key',
gatewayRoute: 'openai-compat',
})
})
it('throws for image model without compatMediaTemplate', async () => {
resolveModelSelectionMock.mockResolvedValueOnce({
provider: 'openai-compatible:oa-1',
modelId: 'gpt-image-1',
modelKey: 'openai-compatible:oa-1::gpt-image-1',
mediaType: 'image',
compatMediaTemplate: undefined,
})
await expect(
generateImage('user-1', 'openai-compatible:oa-1::gpt-image-1', 'draw cat'),
).rejects.toThrow('MODEL_COMPAT_MEDIA_TEMPLATE_REQUIRED')
expect(generateImageViaOpenAICompatMock).not.toHaveBeenCalled()
expect(generateImageViaOpenAICompatTemplateMock).not.toHaveBeenCalled()
})
it('throws for video model without compatMediaTemplate', async () => {
resolveModelSelectionMock.mockResolvedValueOnce({
provider: 'openai-compatible:oa-1',
modelId: 'veo3.1',
modelKey: 'openai-compatible:oa-1::veo3.1',
mediaType: 'video',
compatMediaTemplate: undefined,
})
await expect(
generateVideo('user-1', 'openai-compatible:oa-1::veo3.1', 'https://example.com/a.png', { prompt: 'animate' }),
).rejects.toThrow('MODEL_COMPAT_MEDIA_TEMPLATE_REQUIRED')
expect(generateVideoViaOpenAICompatMock).not.toHaveBeenCalled()
expect(generateVideoViaOpenAICompatTemplateMock).not.toHaveBeenCalled()
})
})