flnxi-Wu/app/api/system/init/__tests__/system-init.test.ts
WuYongJie 63ec6b7dfb fix: 修复排行榜按钮消失、tag排序和输入框浅色模式问题
1. 排行榜悬浮窗关闭后小按钮消失问题
   - 修复面板居中模式关闭时按钮位置错误
   - 保存并恢复按钮的居中状态

2. 首页tag按钮按素材数量排序
   - 添加按素材数量降序排序逻辑

3. 上传弹窗输入框浅色模式文字不可见
   - 添加 text-slate-900 确保浅色模式下文字可见
   - 添加 placeholder 样式确保占位符正确显示
2025-12-14 21:41:29 +08:00

210 lines
7.3 KiB
TypeScript

/**
* 系统初始化 API 测试
* 测试内置模板配置和系统初始化功能
*/
// 内置模板配置(从 route.ts 复制,用于测试验证)
const BUILTIN_TEMPLATE_KEYS = [
'3dmax-material',
'psd-material',
'audio-material',
'video-material',
'model-material',
'other-material',
] as const
const BUILTIN_TEMPLATE_CONFIG: Record<string, {
name: string
description: string
materialType: string
materialKind: string
fields: string[]
}> = {
'3dmax-material': {
name: '3DMAX 素材模板',
description: '适用于 3D 模型类素材',
materialType: '3DMAX',
materialKind: 'IMAGE',
fields: ['productModel', 'categoryName', 'sceneName', 'renderer'],
},
'psd-material': {
name: 'PSD 素材模板',
description: '针对平面设计 PSD 素材',
materialType: 'PSD',
materialKind: 'IMAGE',
fields: ['productModel', 'categoryName', 'sceneName'],
},
'audio-material': {
name: '音频素材模板',
description: '适用于音频文件素材,支持 MP3、WAV、FLAC、AAC 等格式',
materialType: '音频',
materialKind: 'AUDIO',
fields: ['productModel', 'categoryName', 'sceneName'],
},
'video-material': {
name: '视频素材模板',
description: '适用于视频文件素材',
materialType: '视频',
materialKind: 'VIDEO',
fields: ['productModel', 'categoryName', 'sceneName'],
},
'model-material': {
name: '模特素材模板',
description: '用于模特/人像素材',
materialType: '模特',
materialKind: 'IMAGE',
fields: ['productModel', 'categoryName', 'sceneName'],
},
'other-material': {
name: '其他素材模板',
description: '适用于其他类型的素材',
materialType: '其他',
materialKind: 'OTHER',
fields: ['productModel', 'categoryName', 'sceneName'],
},
}
const STANDARD_FIELDS: Record<string, {
key: string
label: string
type: string
required: boolean
layoutWidth: string
visibleOnHomeFilter: boolean
isSearchable: boolean
addToCategory?: boolean
}> = {
productModel: { key: 'productModel', label: 'SPU型号', type: 'text', required: true, layoutWidth: 'full', visibleOnHomeFilter: false, isSearchable: true },
categoryName: { key: 'categoryName', label: '使用店铺', type: 'select', required: true, layoutWidth: 'full', visibleOnHomeFilter: true, isSearchable: true, addToCategory: true },
sceneName: { key: 'sceneName', label: '场景类别', type: 'select', required: true, layoutWidth: 'full', visibleOnHomeFilter: true, isSearchable: true, addToCategory: true },
renderer: { key: 'renderer', label: '渲染器', type: 'select', required: true, layoutWidth: 'full', visibleOnHomeFilter: false, isSearchable: true, addToCategory: true },
}
describe('系统初始化 - 内置模板配置', () => {
describe('BUILTIN_TEMPLATE_KEYS', () => {
it('应该包含6个内置模板', () => {
expect(BUILTIN_TEMPLATE_KEYS).toHaveLength(6)
})
it('应该包含所有预期的模板key', () => {
expect(BUILTIN_TEMPLATE_KEYS).toContain('3dmax-material')
expect(BUILTIN_TEMPLATE_KEYS).toContain('psd-material')
expect(BUILTIN_TEMPLATE_KEYS).toContain('audio-material')
expect(BUILTIN_TEMPLATE_KEYS).toContain('video-material')
expect(BUILTIN_TEMPLATE_KEYS).toContain('model-material')
expect(BUILTIN_TEMPLATE_KEYS).toContain('other-material')
})
})
describe('BUILTIN_TEMPLATE_CONFIG', () => {
it('每个模板key都应该有对应的配置', () => {
for (const key of BUILTIN_TEMPLATE_KEYS) {
expect(BUILTIN_TEMPLATE_CONFIG[key]).toBeDefined()
}
})
it('每个模板配置应该包含必要字段', () => {
for (const key of BUILTIN_TEMPLATE_KEYS) {
const config = BUILTIN_TEMPLATE_CONFIG[key]
expect(config.name).toBeTruthy()
expect(config.description).toBeTruthy()
expect(config.materialType).toBeTruthy()
expect(config.materialKind).toBeTruthy()
expect(Array.isArray(config.fields)).toBe(true)
expect(config.fields.length).toBeGreaterThan(0)
}
})
it('materialKind 应该是有效值', () => {
const validKinds = ['IMAGE', 'VIDEO', 'AUDIO', 'OTHER']
for (const key of BUILTIN_TEMPLATE_KEYS) {
const config = BUILTIN_TEMPLATE_CONFIG[key]
expect(validKinds).toContain(config.materialKind)
}
})
it('3DMAX模板应该包含renderer字段', () => {
const config = BUILTIN_TEMPLATE_CONFIG['3dmax-material']
expect(config.fields).toContain('renderer')
})
it('视频模板的materialKind应该是VIDEO', () => {
const config = BUILTIN_TEMPLATE_CONFIG['video-material']
expect(config.materialKind).toBe('VIDEO')
})
it('其他模板的materialKind应该是OTHER', () => {
const config = BUILTIN_TEMPLATE_CONFIG['other-material']
expect(config.materialKind).toBe('OTHER')
})
})
describe('STANDARD_FIELDS', () => {
it('应该包含4个标准字段', () => {
expect(Object.keys(STANDARD_FIELDS)).toHaveLength(4)
})
it('应该包含所有预期的字段', () => {
expect(STANDARD_FIELDS.productModel).toBeDefined()
expect(STANDARD_FIELDS.categoryName).toBeDefined()
expect(STANDARD_FIELDS.sceneName).toBeDefined()
expect(STANDARD_FIELDS.renderer).toBeDefined()
})
it('每个字段应该有正确的结构', () => {
for (const [key, field] of Object.entries(STANDARD_FIELDS)) {
expect(field.key).toBe(key)
expect(field.label).toBeTruthy()
expect(['text', 'select', 'number', 'textarea']).toContain(field.type)
expect(typeof field.required).toBe('boolean')
expect(field.layoutWidth).toBeTruthy()
expect(typeof field.visibleOnHomeFilter).toBe('boolean')
expect(typeof field.isSearchable).toBe('boolean')
}
})
it('productModel应该是text类型', () => {
expect(STANDARD_FIELDS.productModel.type).toBe('text')
})
it('categoryName应该是select类型且addToCategory为true', () => {
expect(STANDARD_FIELDS.categoryName.type).toBe('select')
expect(STANDARD_FIELDS.categoryName.addToCategory).toBe(true)
})
it('sceneName应该是select类型且addToCategory为true', () => {
expect(STANDARD_FIELDS.sceneName.type).toBe('select')
expect(STANDARD_FIELDS.sceneName.addToCategory).toBe(true)
})
it('renderer应该是select类型且addToCategory为true', () => {
expect(STANDARD_FIELDS.renderer.type).toBe('select')
expect(STANDARD_FIELDS.renderer.addToCategory).toBe(true)
})
it('所有模板字段都应该在STANDARD_FIELDS中定义', () => {
for (const key of BUILTIN_TEMPLATE_KEYS) {
const config = BUILTIN_TEMPLATE_CONFIG[key]
for (const fieldKey of config.fields) {
expect(STANDARD_FIELDS[fieldKey]).toBeDefined()
}
}
})
})
describe('模板ID生成', () => {
it('内置模板ID应该以builtin-开头', () => {
for (const key of BUILTIN_TEMPLATE_KEYS) {
const templateId = `builtin-${key}`
expect(templateId).toMatch(/^builtin-/)
}
})
it('生成的模板ID应该唯一', () => {
const ids = BUILTIN_TEMPLATE_KEYS.map(key => `builtin-${key}`)
const uniqueIds = new Set(ids)
expect(uniqueIds.size).toBe(ids.length)
})
})
})