'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { DEFAULT_MAIN_IMAGE_PROMPT, DEFAULT_MODEL, DEFAULT_PRODUCT_TITLE_PROMPT, DEFAULT_SKU_IMAGE_PROMPT, buildSkuNameRepairInstruction, normalizeMainImagePrompt, normalizeSkuImagePrompt, normalizeProductTitleCategoryTerm, normalizeProductTitleCandidatesPayload, normalizeSkuNameCandidatesPayload, } = require('../src/services/selectionFissionAiSettings'); test('selection AI reduces taxonomy paths to a usable product title category', () => { assert.equal(normalizeProductTitleCategoryTerm('书柜 > 单个书柜'), '书柜'); assert.equal(normalizeProductTitleCategoryTerm('住宅家具 / 柜类 / 书柜'), '书柜'); assert.equal(normalizeProductTitleCategoryTerm('单个鞋柜'), '鞋柜'); assert.equal(normalizeProductTitleCategoryTerm('书柜'), '书柜'); }); test('selection AI uses the verified Qwen multimodal snapshot by default', () => { assert.equal(DEFAULT_MODEL, 'qwen3.7-max-2026-06-08'); assert.match(DEFAULT_PRODUCT_TITLE_PROMPT, /28至30个汉字/); assert.match(DEFAULT_PRODUCT_TITLE_PROMPT, /优先写满30字/); assert.match(DEFAULT_PRODUCT_TITLE_PROMPT, /第三方品牌/); assert.match(DEFAULT_PRODUCT_TITLE_PROMPT, /forbiddenBrandTerms/); }); test('main image prompt requires styled props without changing the product', () => { assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /装饰品/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /不能输出光秃秃的裸产品/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /不能.*改变|不得改变/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /不得.*赠送|不能.*赠送/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /不得出现任何字符、符号或伪文字/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /刚性整体/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /部件位置与精确数量/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /优先保持目标商品外观结构不变/); }); test('SKU image prompt treats the first image as the unique SKU identity', () => { assert.match(DEFAULT_SKU_IMAGE_PROMPT, /第一张图是当前SKU唯一商品身份图/); assert.match(DEFAULT_SKU_IMAGE_PROMPT, /只有在参考市场图生成模式下/); assert.match(DEFAULT_SKU_IMAGE_PROMPT, /其他SKU/); assert.match(DEFAULT_SKU_IMAGE_PROMPT, /刚性整体/); assert.match(DEFAULT_SKU_IMAGE_PROMPT, /部件位置与精确数量/); assert.match(DEFAULT_SKU_IMAGE_PROMPT, /优先保持SKU外观结构不变/); }); test('legacy SKU scene prompt is migrated to SKU-first reference order', () => { const legacyPrompt = [ '第一张图是已完成产品替换的市场主图场景,第二张图是公司SKU产品图。', '把第二张图的SKU商品自然放入第一张图相同的场景。', ].join('\n'); assert.equal(normalizeSkuImagePrompt(legacyPrompt), legacyPrompt); assert.equal( normalizeSkuImagePrompt('参考已替换完成的市场主图场景,旧默认'), DEFAULT_SKU_IMAGE_PROMPT ); }); test('main image prompt treats the target image as the only product identity', () => { assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /第一张图是目标商品图/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /唯一商品身份来源/); assert.match(DEFAULT_MAIN_IMAGE_PROMPT, /禁止拆分重绘或复制市场商品结构/); }); test('legacy main image prompt is migrated to the company-first reference order', () => { const legacyPrompt = [ '第一张图是市场参考图,第二张图是公司商品白底图。', '彻底移除市场参考图中的原商品、文字、图标、标签、角标、价格、水印和品牌标识,只保留干净的场景、构图、视角、光线与真实阴影。', '将第二张图中的公司商品完整替换到市场参考图原商品位置,保持商品结构、颜色和比例准确,边缘自然,不新增任何文字或图标。', '参考市场图的陈设风格,在商品上或周围布置与品类和场景协调的书籍、摆件、收纳盒、绿植等生活化装饰品,画面饱满但不过度堆砌,不能输出光秃秃的裸产品。', '所有装饰品必须采用无文字、无Logo设计,书籍封面和书脊只保留纯色或自然纹理,不得出现任何字符、符号或伪文字。', '装饰品仅作为场景陈设,不得改变、遮挡或虚构商品的层板、柜门、五金、尺寸和其他主体结构,也不得表现为随商品赠送的配件。', '输出一张可直接用于电商主图的正方形高清图片。', ].join('\n'); assert.equal(normalizeMainImagePrompt(legacyPrompt), DEFAULT_MAIN_IMAGE_PROMPT); assert.equal(normalizeMainImagePrompt('自定义主图提示词'), '自定义主图提示词'); }); test('selection AI normalizes exactly five unique names for every SKU', () => { const rows = normalizeSkuNameCandidatesPayload({ items: [{ skuCode: 'SKU-1', names: ['1. 名称甲', '名称乙', '名称丙', '名称丁', '名称戊'], }], }, [{ skuCode: 'SKU-1', originalSkuName: '1688原始SKU名' }]); assert.deepEqual(rows, [{ skuCode: 'SKU-1', originalSkuName: '1688原始SKU名', names: ['名称甲', '名称乙', '名称丙', '名称丁', '名称戊'], }]); }); test('selection AI rejects incomplete or duplicate candidate sets', () => { assert.throws( () => normalizeSkuNameCandidatesPayload({ items: [{ skuCode: 'SKU-1', names: ['名称甲', '名称甲', '名称乙', '名称丙', '名称丁'], }], }, [{ skuCode: 'SKU-1' }]), /恰好5个与原名不同的有效名称/ ); assert.throws( () => normalizeSkuNameCandidatesPayload({ items: [{ skuCode: 'SKU-1', names: ['原始名', '名称甲', '名称乙', '名称丙', '名称丁'], }], }, [{ skuCode: 'SKU-1', originalSkuName: '原始名' }]), /恰好5个与原名不同的有效名称/ ); }); test('selection AI retry instruction requires every SKU and exactly five names', () => { const instruction = buildSkuNameRepairInstruction([ { skuCode: 'SKU-1' }, { skuCode: 'SKU-2' }, ], 1); assert.match(instruction, /第2次生成/); assert.match(instruction, /SKU-1、SKU-2/); assert.match(instruction, /恰好5个名称/); assert.match(instruction, /不能遗漏任何SKU/); }); test('selection AI requires exactly five unique product title candidates', () => { const titles = [ '现代简约家用多层落地收纳书柜客厅卧室大容量置物储物柜组合', '家用客厅卧室多层落地收纳书柜简约大容量置物储物展示柜组合', '简约现代客厅卧室落地收纳书柜家用多层大容量置物储物柜组合', '客厅卧室家用多层书柜落地收纳简约现代大容量置物储物柜组合', '多层落地收纳书柜家用客厅卧室简约现代大容量置物储物柜组合', ]; assert.deepEqual( normalizeProductTitleCandidatesPayload({ titles: titles.map((title, index) => `${index + 1}. ${title}`), }), titles ); assert.throws( () => normalizeProductTitleCandidatesPayload({ titles: [titles[0], titles[0], ...titles.slice(1, 4)], }), /恰好5个有效商品标题/ ); }); test('selection AI enforces title length, category and all surging keywords', () => { const strategy = { category: '书柜', surgingKeywords: ['落地', '收纳'] }; const validTitles = [ '现代简约家用多层落地收纳书柜客厅卧室大容量置物储物柜组合', '家用客厅卧室多层落地收纳书柜简约大容量置物储物展示柜组合', '简约现代客厅卧室落地收纳书柜家用多层大容量置物储物柜组合', '客厅卧室家用多层书柜落地收纳简约现代大容量置物储物柜组合', '多层落地收纳书柜家用客厅卧室简约现代大容量置物储物柜组合', ]; assert.deepEqual(normalizeProductTitleCandidatesPayload({ titles: validTitles }, strategy), validTitles); assert.throws( () => normalizeProductTitleCandidatesPayload({ titles: [...validTitles.slice(0, 4), '家用落地收纳书柜'], }, strategy), /28至30字/ ); assert.throws( () => normalizeProductTitleCandidatesPayload({ titles: [...validTitles.slice(0, 4), '现代简约家用多层落地收纳置物架客厅卧室大容量储物展示柜组合'], }, strategy), /品类词/ ); assert.throws( () => normalizeProductTitleCandidatesPayload({ titles: [...validTitles.slice(0, 4), '现代简约家用多层落地书柜客厅卧室大容量置物储物展示柜组合款'], }, strategy), /飙升词/ ); }); test('selection AI rejects titles that copy brands or models from reference links', () => { const titles = [ '现代简约家用多层落地收纳书柜客厅卧室大容量置物储物柜组合', '家用客厅卧室多层落地收纳书柜简约大容量置物储物展示柜组合', '简约现代客厅卧室落地收纳书柜家用多层大容量置物储物柜组合', '客厅卧室家用多层书柜落地收纳简约现代大容量置物储物柜组合', '钛载S3多层落地收纳书柜家用客厅卧室大容量置物储物柜组合款', ]; assert.throws( () => normalizeProductTitleCandidatesPayload({ titles }, { category: '书柜', surgingKeywords: ['落地', '收纳'], forbiddenBrandTerms: ['钛载S3'], }), /参考商品品牌或型号“钛载S3”/ ); });