gongxiangp2/lib/__tests__/standard-model-white-background.test.ts
chenpei 4712175cb0 feat(素材链路): 发布白底图双轨与AI生图回传能力
- 完成白底图 WebP 双轨接口、上传链路与预览缓存改造
- 新增 AI 生图平台成品回传接口、任务状态与表单规则
- 补齐 AI 生成标签、任务详情补全、相关测试与对接文档
2026-03-25 10:28:02 +08:00

257 lines
9.6 KiB
TypeScript

import {
buildWhiteBackgroundFixedFileName,
countWhiteBackgroundAssets,
countWhiteBackgroundFixedViews,
countWhiteBackgroundOtherImages,
getWhiteBackgroundAssetWhereForSku,
getMissingWhiteBackgroundViewsFromAssetGroup,
getWhiteBackgroundOtherAssetType,
getWhiteBackgroundOtherPreviewRelativeFilePath,
getNextWhiteBackgroundOtherIndex,
getWhiteBackgroundPreviewRelativeDirectory,
getWhiteBackgroundPreviewRelativeFilePath,
getWhiteBackgroundPreviewRelativePathFromAssetPath,
getWhiteBackgroundRelativeDirectory,
getWhiteBackgroundRelativeFilePath,
getWhiteBackgroundViewAssetType,
getWhiteBackgroundZipFileName,
groupWhiteBackgroundAssetsBySku,
hasAnyWhiteBackgroundAssetGroup,
hasCompleteWhiteBackgroundAssetGroup,
parseStandardModelWhiteBgAssetType,
STANDARD_MODEL_WHITE_BG_ASSET_TYPE_PREFIX,
STANDARD_MODEL_WHITE_BG_OTHER_ASSET_TYPE_PREFIX,
STANDARD_MODEL_WHITE_BG_VIEWS,
STANDARD_MODEL_WHITE_BG_OTHER_FIELD_NAME,
STANDARD_MODEL_WHITE_BG_VIEW_ASSET_TYPE_PREFIX,
getAllWhiteBackgroundAssetTypesForSku,
getCurrentWhiteBackgroundAssetType,
getMissingWhiteBackgroundViews,
hasCompleteWhiteBackgroundSet,
getWhiteBackgroundFieldName,
normalizeWhiteBackgroundSkuName,
replaceWhiteBackgroundFileExtension,
} from '@/lib/standard-model-white-background'
describe('standard-model-white-background helpers', () => {
const createMockFile = (name: string): File => ({ name } as unknown as File)
test('returns missing views when not all eight images are provided', () => {
const files = {
leftFront45: createMockFile('left-front-45.jpg'),
rightFront45: createMockFile('right-front-45.jpg'),
leftBack45: createMockFile('left-back-45.jpg'),
rightBack45: null,
front: createMockFile('front.jpg'),
back: null,
left: createMockFile('left.jpg'),
right: null,
}
const missing = getMissingWhiteBackgroundViews(files)
expect(missing).toEqual(['rightBack45', 'back', 'right'])
})
test('recognizes complete white background image set', () => {
const files = {
leftFront45: createMockFile('left-front-45.jpg'),
rightFront45: createMockFile('right-front-45.jpg'),
leftBack45: createMockFile('left-back-45.jpg'),
rightBack45: createMockFile('right-back-45.jpg'),
front: createMockFile('front.jpg'),
back: createMockFile('back.jpg'),
left: createMockFile('left.jpg'),
right: createMockFile('right.jpg'),
}
expect(hasCompleteWhiteBackgroundSet(files)).toBe(true)
expect(getMissingWhiteBackgroundViews(files)).toEqual([])
})
test('exports eight canonical white background views', () => {
expect(STANDARD_MODEL_WHITE_BG_VIEWS.map((item) => item.key)).toEqual([
'leftFront45',
'rightFront45',
'leftBack45',
'rightBack45',
'front',
'back',
'left',
'right',
])
})
test('builds backend field names from view key', () => {
expect(getWhiteBackgroundFieldName('leftFront45')).toBe('whiteBgLeftFront45')
expect(getWhiteBackgroundFieldName('front')).toBe('whiteBgFront')
})
test('exports other images field name', () => {
expect(STANDARD_MODEL_WHITE_BG_OTHER_FIELD_NAME).toBe('whiteBgOtherImages')
})
test('exports current white background asset type helpers', () => {
expect(STANDARD_MODEL_WHITE_BG_ASSET_TYPE_PREFIX).toBe('standard-model-white-bg-zip-v2:')
expect(getCurrentWhiteBackgroundAssetType('sku-1')).toBe('standard-model-white-bg-zip-v2:sku-1')
expect(getAllWhiteBackgroundAssetTypesForSku('sku-1')).toContain('standard-model-white-bg-zip-v2:sku-1')
expect(getAllWhiteBackgroundAssetTypesForSku('sku-1')).toContain('standard-model-white-bg-zip')
expect(getAllWhiteBackgroundAssetTypesForSku('sku-1')).toContain('standard-model-white-bg-zip:sku-1')
})
test('exports per-image asset type helpers', () => {
expect(STANDARD_MODEL_WHITE_BG_VIEW_ASSET_TYPE_PREFIX).toBe('standard-model-white-bg-view:')
expect(STANDARD_MODEL_WHITE_BG_OTHER_ASSET_TYPE_PREFIX).toBe('standard-model-white-bg-other:')
expect(getWhiteBackgroundViewAssetType('sku-1', 'front')).toBe('standard-model-white-bg-view:sku-1:front')
expect(getWhiteBackgroundOtherAssetType('sku-1', 2)).toBe('standard-model-white-bg-other:sku-1:2')
})
test('parses per-image asset types', () => {
expect(parseStandardModelWhiteBgAssetType('standard-model-white-bg-view:sku-1:front')).toEqual({
kind: 'view',
skuId: 'sku-1',
viewKey: 'front',
})
expect(parseStandardModelWhiteBgAssetType('standard-model-white-bg-other:sku-1:3')).toEqual({
kind: 'other',
skuId: 'sku-1',
index: 3,
})
})
test('builds white background storage paths', () => {
expect(getWhiteBackgroundRelativeDirectory('material-1', 'sku-1')).toBe(
'uploads/skus/material-1/white-background/sku-1',
)
expect(getWhiteBackgroundRelativeFilePath('material-1', 'sku-1', 'front.jpg')).toBe(
'uploads/skus/material-1/white-background/sku-1/front.jpg',
)
expect(getWhiteBackgroundZipFileName('SKU001')).toBe('SKU001_白底图.zip')
})
test('builds white background preview storage paths', () => {
expect(replaceWhiteBackgroundFileExtension('front.png')).toBe('front.webp')
expect(replaceWhiteBackgroundFileExtension('other/front.JPG')).toBe('other/front.webp')
expect(getWhiteBackgroundPreviewRelativeDirectory('material-1', 'sku-1')).toBe(
'uploads/skus/material-1/white-background/sku-1/preview',
)
expect(getWhiteBackgroundPreviewRelativeFilePath('material-1', 'sku-1', 'front.png')).toBe(
'uploads/skus/material-1/white-background/sku-1/preview/front.webp',
)
expect(getWhiteBackgroundOtherPreviewRelativeFilePath('material-1', 'sku-1', '01-other.png')).toBe(
'uploads/skus/material-1/white-background/sku-1/preview/other/01-other.webp',
)
})
test('derives preview relative path from white background asset path', () => {
expect(
getWhiteBackgroundPreviewRelativePathFromAssetPath(
'uploads/skus/material-1/white-background/sku-1/front.png',
),
).toBe('uploads/skus/material-1/white-background/sku-1/preview/front.webp')
expect(
getWhiteBackgroundPreviewRelativePathFromAssetPath(
'/uploads/skus/material-1/white-background/sku-1/other/01-other.png',
),
).toBe('uploads/skus/material-1/white-background/sku-1/preview/other/01-other.webp')
expect(
getWhiteBackgroundPreviewRelativePathFromAssetPath(
'https://s3.example/white-background/front.png',
),
).toBeNull()
})
test('builds fixed white background file name with sku and category', () => {
expect(normalizeWhiteBackgroundSkuName('sku_01-a')).toBe('SKU_01-A')
expect(buildWhiteBackgroundFixedFileName('sku_01-a', '休闲椅', '左前45°', '.PNG')).toBe(
'SKU_01-A-休闲椅-左前45°.png',
)
expect(buildWhiteBackgroundFixedFileName('sku001', '', '正视图', 'jpg')).toBe(
'SKU001-正视图.jpg',
)
})
test('builds prisma where clause for a sku white background', () => {
expect(getWhiteBackgroundAssetWhereForSku('sku-1')).toEqual({
OR: [
{ assetType: 'standard-model-white-bg-zip-v2:sku-1' },
{ assetType: 'standard-model-white-bg-zip' },
{ assetType: 'standard-model-white-bg-zip:sku-1' },
{ assetType: { startsWith: 'standard-model-white-bg-view:sku-1:' } },
{ assetType: { startsWith: 'standard-model-white-bg-other:sku-1:' } },
],
})
})
test('groups white background assets by sku and recognizes completeness', () => {
const grouped = groupWhiteBackgroundAssetsBySku([
{
assetType: 'standard-model-white-bg-view:sku-1:leftFront45',
fileUrl: 'uploads/a.jpg',
fileName: '左前45°.jpg',
sortOrder: 0,
},
{
assetType: 'standard-model-white-bg-view:sku-1:rightFront45',
fileUrl: 'uploads/b.jpg',
fileName: '右前45°.jpg',
sortOrder: 1,
},
{
assetType: 'standard-model-white-bg-view:sku-1:leftBack45',
fileUrl: 'uploads/c.jpg',
fileName: '左后45°.jpg',
sortOrder: 2,
},
{
assetType: 'standard-model-white-bg-view:sku-1:rightBack45',
fileUrl: 'uploads/d.jpg',
fileName: '右后45°.jpg',
sortOrder: 3,
},
{
assetType: 'standard-model-white-bg-view:sku-1:front',
fileUrl: 'uploads/e.jpg',
fileName: '正视图.jpg',
sortOrder: 4,
},
{
assetType: 'standard-model-white-bg-view:sku-1:back',
fileUrl: 'uploads/f.jpg',
fileName: '后视图.jpg',
sortOrder: 5,
},
{
assetType: 'standard-model-white-bg-view:sku-1:left',
fileUrl: 'uploads/g.jpg',
fileName: '左视图.jpg',
sortOrder: 6,
},
{
assetType: 'standard-model-white-bg-view:sku-1:right',
fileUrl: 'uploads/h.jpg',
fileName: '右视图.jpg',
sortOrder: 7,
},
{
assetType: 'standard-model-white-bg-other:sku-1:1',
fileUrl: 'uploads/other-1.jpg',
fileName: '01-other.jpg',
sortOrder: 1000,
},
])
const group = grouped.get('sku-1')
expect(group).toBeDefined()
expect(group?.other).toHaveLength(1)
expect(hasAnyWhiteBackgroundAssetGroup(group)).toBe(true)
expect(hasCompleteWhiteBackgroundAssetGroup(group)).toBe(true)
expect(countWhiteBackgroundFixedViews(group)).toBe(8)
expect(countWhiteBackgroundOtherImages(group)).toBe(1)
expect(countWhiteBackgroundAssets(group)).toBe(9)
expect(getNextWhiteBackgroundOtherIndex(group)).toBe(2)
expect(getMissingWhiteBackgroundViewsFromAssetGroup(group)).toEqual([])
})
})