Files
prompt-optimizer/packages/core/tests/unit/image/modelscope-adapter.test.ts
linshen 5e942ca945 feat: polish provider controls and themed UI
- Add provider pill selection and normalized provider display copy

- Adopt themed tooltips, confirmation dialogs, and Naive UI surface styles

- Enable Prompt Garden thumbnail previews through shared image preview components
2026-05-14 21:18:43 +08:00

200 lines
6.5 KiB
TypeScript
Raw Permalink 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.
import { describe, test, expect, vi, beforeEach } from 'vitest'
import { ModelScopeImageAdapter } from '../../../src/services/image/adapters/modelscope'
import type { ImageRequest, ImageModelConfig } from '../../../src/services/image/types'
import { IMAGE_ERROR_CODES } from '../../../src/constants/error-codes'
describe('ModelScopeImageAdapter', () => {
let adapter: ModelScopeImageAdapter
beforeEach(() => {
adapter = new ModelScopeImageAdapter()
})
describe('Provider Information', () => {
test('should return correct provider information', () => {
const provider = adapter.getProvider()
expect(provider.id).toBe('modelscope')
expect(provider.name).toBe('ModelScope')
expect(provider.requiresApiKey).toBe(true)
expect(provider.defaultBaseURL).toBe('https://api-inference.modelscope.cn/v1')
expect(provider.supportsDynamicModels).toBe(false)
expect(provider.apiKeyUrl).toBe('https://modelscope.cn/my/myaccesstoken')
expect(provider.connectionSchema?.required).toContain('apiKey')
expect(provider.connectionSchema?.optional).toEqual(expect.arrayContaining(['baseURL']))
})
})
describe('Static Models', () => {
test('should return static models list', () => {
const models = adapter.getModels()
expect(Array.isArray(models)).toBe(true)
expect(models.length).toBe(1) // Z-Image-Turbo only
const zImageModel = models.find(m => m.id === 'Tongyi-MAI/Z-Image-Turbo')
expect(zImageModel).toBeDefined()
expect(zImageModel).toMatchObject({
id: 'Tongyi-MAI/Z-Image-Turbo',
name: 'Z-Image-Turbo',
providerId: 'modelscope',
capabilities: {
text2image: true,
image2image: false,
multiImage: false
},
parameterDefinitions: expect.any(Array)
})
})
test('should include correct parameters in model definition', () => {
const models = adapter.getModels()
const zImageModel = models.find(m => m.id === 'Tongyi-MAI/Z-Image-Turbo')
expect(zImageModel?.parameterDefinitions).toBeDefined()
// 验证 size 参数
const sizeParam = zImageModel?.parameterDefinitions?.find(p => p.name === 'size')
expect(sizeParam).toBeDefined()
expect(sizeParam?.type).toBe('string')
expect(sizeParam?.defaultValue).toBe('1024x1024')
expect(sizeParam?.allowedValues).toContain('1024x1024')
// 验证 n 参数
const nParam = zImageModel?.parameterDefinitions?.find(p => p.name === 'n')
expect(nParam).toBeDefined()
expect(nParam?.type).toBe('integer')
expect(nParam?.defaultValue).toBe(1)
})
})
describe('Image Generation', () => {
test('should validate configuration before generating', async () => {
const invalidConfig: ImageModelConfig = {
id: 'test-config',
name: 'Test ModelScope Config',
providerId: 'modelscope',
modelId: 'Tongyi-MAI/Z-Image-Turbo',
enabled: true,
connectionConfig: {
// 缺少 apiKey
},
provider: adapter.getProvider(),
model: adapter.getModels()[0]
}
const request: ImageRequest = {
configId: 'test-config',
prompt: '一朵简单的红色花朵',
count: 1
}
await expect(adapter.generate(request, invalidConfig))
.rejects.toMatchObject({ code: IMAGE_ERROR_CODES.API_KEY_REQUIRED })
})
test('should validate prompt is required', async () => {
const config: ImageModelConfig = {
id: 'test-config',
name: 'Test ModelScope Config',
providerId: 'modelscope',
modelId: 'Tongyi-MAI/Z-Image-Turbo',
enabled: true,
connectionConfig: {
apiKey: 'test-api-key'
},
provider: adapter.getProvider(),
model: adapter.getModels()[0]
}
const invalidRequest: ImageRequest = {
configId: 'test-config',
prompt: '', // 空提示词
count: 1
}
await expect(adapter.generate(invalidRequest, config))
.rejects.toMatchObject({ code: IMAGE_ERROR_CODES.PROMPT_EMPTY })
})
test('should reject requests with input images', async () => {
const config: ImageModelConfig = {
id: 'test-config',
name: 'Test ModelScope Config',
providerId: 'modelscope',
modelId: 'Tongyi-MAI/Z-Image-Turbo',
enabled: true,
connectionConfig: {
apiKey: 'test-api-key'
},
provider: adapter.getProvider(),
model: adapter.getModels()[0]
}
const request: ImageRequest = {
configId: 'test-config',
prompt: 'make this colorful',
inputImage: {
b64: 'aGVsbG8=',
mimeType: 'image/png'
},
count: 1
}
await expect(adapter.generate(request, config))
.rejects.toMatchObject({ code: IMAGE_ERROR_CODES.MODEL_NOT_SUPPORT_IMAGE2IMAGE })
})
})
describe('Real API Tests', () => {
const hasApiKey = !!(
process.env.MODELSCOPE_API_KEY ||
process.env.VITE_MODELSCOPE_API_KEY
)
test.skipIf(!hasApiKey)('should successfully call ModelScope text-to-image API', async () => {
const realAdapter = new ModelScopeImageAdapter()
const apiKey = process.env.MODELSCOPE_API_KEY || process.env.VITE_MODELSCOPE_API_KEY
const config: ImageModelConfig = {
id: 'test-config',
name: 'Test ModelScope Config',
providerId: 'modelscope',
modelId: 'Tongyi-MAI/Z-Image-Turbo',
enabled: true,
connectionConfig: {
apiKey: apiKey!
},
paramOverrides: {
size: '1024x1024',
n: 1
},
provider: realAdapter.getProvider(),
model: realAdapter.getModels()[0]
}
const request: ImageRequest = {
configId: 'test-config',
prompt: '一朵简单的红色花朵',
count: 1
}
const result = await realAdapter.generate(request, config)
expect(result).toBeDefined()
expect(result.images).toBeDefined()
expect(Array.isArray(result.images)).toBe(true)
expect(result.images.length).toBeGreaterThan(0)
expect(result.images[0].url).toBeDefined()
expect(result.metadata).toBeDefined()
expect(result.metadata?.providerId).toBe('modelscope')
console.log('ModelScope Text-to-Image API Response:', {
imageCount: result.images.length,
imageUrl: result.images[0].url?.substring(0, 100),
metadata: result.metadata
})
}, 180000) // 180秒超时异步任务轮询需要更长时间
})
})