包含: - furniture-3d-system:Next.js 16 全栈应用(资产中心、产品管理、3D装配动画) - autocad-plugin:AutoCAD 家具导出插件源码 - 资产中心改造:编辑弹窗化、删除功能、Toast反馈、自定义Select组件 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
144 lines
4.6 KiB
TypeScript
144 lines
4.6 KiB
TypeScript
import { describe, it, expect } from '@jest/globals'
|
|
import { SKUUploadService } from '@/server/services/sku-upload.service'
|
|
|
|
function buildBaseFormData(): FormData {
|
|
const formData = new FormData()
|
|
formData.append('productId', 'product-1')
|
|
formData.append('skuCode', 'SKU-001')
|
|
formData.append('attributes', JSON.stringify({ 颜色: '白色' }))
|
|
return formData
|
|
}
|
|
|
|
describe('SKUUploadService', () => {
|
|
it('应该在缺少 panels 时根据 holes 自动补齐板件', async () => {
|
|
const service = new SKUUploadService()
|
|
const formData = buildBaseFormData()
|
|
formData.append('holesData', JSON.stringify({
|
|
pluginVersion: '2.2.14',
|
|
holes: [
|
|
{
|
|
panelId: 'panel_A',
|
|
position: [100, 200, 0],
|
|
normal: [0, 0, 1],
|
|
diameter: 5,
|
|
depth: 10,
|
|
},
|
|
{
|
|
panelId: 'panel_A',
|
|
position: [320, 260, 0],
|
|
normal: [0, 0, 1],
|
|
diameter: 5,
|
|
depth: 10,
|
|
},
|
|
],
|
|
panels: [],
|
|
}))
|
|
|
|
const result = await service.prepareCreatePayload(formData)
|
|
|
|
expect(result.cadHoles).toHaveLength(2)
|
|
expect(result.cadPanels).toHaveLength(1)
|
|
expect(result.cadPanels[0].id).toBe('panel_A')
|
|
expect(result.cadPanels[0].panelType).toBe('panel')
|
|
expect(result.cadPanels[0].size[0]).toBeGreaterThan(0)
|
|
expect(result.cadPanels[0].size[1]).toBeGreaterThan(0)
|
|
expect(result.cadPanels[0].size[2]).toBeGreaterThan(0)
|
|
})
|
|
|
|
it('应该对 panelId 去空白并避免重复补板', async () => {
|
|
const service = new SKUUploadService()
|
|
const formData = buildBaseFormData()
|
|
formData.append('holesData', JSON.stringify({
|
|
pluginVersion: '2.2.14',
|
|
holes: [
|
|
{
|
|
panelId: ' Cabinet/Panel_01 ',
|
|
position: [10, 20, 0],
|
|
normal: [0, 0, 1],
|
|
diameter: 5,
|
|
depth: 10,
|
|
},
|
|
],
|
|
panels: [
|
|
{
|
|
id: 'cabinet/panel_01',
|
|
panelType: 'side_panel',
|
|
size: [1000, 500, 18],
|
|
},
|
|
],
|
|
}))
|
|
|
|
const result = await service.prepareCreatePayload(formData)
|
|
|
|
expect(result.cadPanels).toHaveLength(1)
|
|
expect(result.cadPanels[0].id).toBe('cabinet/panel_01')
|
|
expect(result.cadHoles[0].panelId).toBe('Cabinet/Panel_01')
|
|
})
|
|
|
|
it('应该允许 holes 为空但仍保存板件数据(有些板件本身无孔位)', async () => {
|
|
const service = new SKUUploadService()
|
|
const formData = buildBaseFormData()
|
|
formData.append('holesData', JSON.stringify({
|
|
pluginVersion: '2.2.14',
|
|
holes: [],
|
|
panels: [
|
|
{
|
|
id: 'panel_no_holes',
|
|
panelType: 'panel',
|
|
size: [600, 400, 18],
|
|
},
|
|
],
|
|
}))
|
|
|
|
const result = await service.prepareCreatePayload(formData)
|
|
|
|
expect(result.cadHoles).toHaveLength(0)
|
|
expect(result.cadPanels).toHaveLength(1)
|
|
expect(result.cadPanels[0].id).toBe('panel_no_holes')
|
|
})
|
|
|
|
it('应该在 holes/panels/hardwareSummary 都为空时给出明确错误', async () => {
|
|
const service = new SKUUploadService()
|
|
const formData = buildBaseFormData()
|
|
formData.append('holesData', JSON.stringify({
|
|
pluginVersion: '2.2.14',
|
|
holes: [],
|
|
panels: [],
|
|
}))
|
|
|
|
await expect(service.prepareCreatePayload(formData)).rejects.toThrow(
|
|
'hardware.json 未包含可导入的孔位/板件/五金统计数据'
|
|
)
|
|
})
|
|
|
|
it('应该在数值字段非法时抛出可读错误', async () => {
|
|
const service = new SKUUploadService()
|
|
const formData = buildBaseFormData()
|
|
formData.append('price', 'abc')
|
|
|
|
await expect(service.prepareCreatePayload(formData)).rejects.toThrow('销售价格必须是非负数字')
|
|
})
|
|
|
|
it('应该允许可转换模型源文件超过 50MB 但不超过 200MB', () => {
|
|
const service = new SKUUploadService() as unknown as {
|
|
ensureSourceModelFileSize: (file: File, ext: string) => void
|
|
}
|
|
const oversizedObj = new File([new Uint8Array(1)], 'demo.obj')
|
|
Object.defineProperty(oversizedObj, 'size', { value: 55 * 1024 * 1024 })
|
|
|
|
expect(() => service.ensureSourceModelFileSize(oversizedObj, '.obj')).not.toThrow()
|
|
})
|
|
|
|
it('应该在转换后模型仍超过 50MB 时抛出更准确的错误', () => {
|
|
const service = new SKUUploadService() as unknown as {
|
|
ensureProcessedModelFileSize: (file: File, ext: string) => void
|
|
}
|
|
const convertedFile = new File([new Uint8Array(1)], 'demo.glb')
|
|
Object.defineProperty(convertedFile, 'size', { value: 55 * 1024 * 1024 })
|
|
|
|
expect(() => service.ensureProcessedModelFileSize(convertedFile, '.obj')).toThrow(
|
|
'转换后的模型文件大小超过限制'
|
|
)
|
|
})
|
|
})
|