cangku/backend/test/productCodePublicApiWorkflow.test.js

145 lines
4.8 KiB
JavaScript
Raw 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.

'use strict';
const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const {
_test: {
buildProductCodeRequest,
buildProductCodeRequestHash,
normalizeProductCodeConfig,
normalizeProductCodeMeta,
validateProductCodeResponse,
},
} = require('../src/services/planningSelectionFissionService');
const remoteMeta = {
operationCenters: [{ name: '运营一部' }],
categories: [{ name: '住宅家具' }],
productTagOptionGroups: [
{ key: 'taxStatus', options: ['含税'] },
{ key: 'invoiceType', options: ['专票'] },
{ key: 'installationService', options: ['不安装'] },
{ key: 'installationMode', options: ['无需安装'] },
],
};
const configInput = {
operationCenter: '运营一部',
categoryName: '住宅家具',
taxStatus: '含税',
invoiceType: '专票',
installationService: '不安装',
installationMode: '无需安装',
};
const rows = [
{
skuCode: 'SOURCE-SKU-02',
selectedSkuName: '胡桃色 120cm 茶几',
colorName: '胡桃色',
colorSpec: '胡桃色;120cm',
lengthCm: 120,
widthCm: 60,
heightCm: 45,
weight: 20,
},
{
skuCode: 'SOURCE-SKU-01',
selectedSkuName: '原木色 90cm 茶几',
colorName: '原木色',
colorSpec: '原木色;90cm',
lengthCm: 90,
widthCm: 50,
heightCm: 42,
weight: 16,
},
];
test('product-code meta and required options are normalized from the remote contract', () => {
assert.deepEqual(normalizeProductCodeMeta(remoteMeta), {
operationCenters: ['运营一部'],
categories: ['住宅家具'],
tagOptions: {
taxStatus: ['含税'],
invoiceType: ['专票'],
installationService: ['不安装'],
installationMode: ['无需安装'],
},
});
assert.deepEqual(normalizeProductCodeConfig(configInput, remoteMeta), configInput);
});
test('product-code request preserves canonical SKU order and confirmed SKU names', () => {
const request = buildProductCodeRequest(configInput, rows, { name: '测试运营' });
assert.equal(request.skuItems.length, 2);
assert.equal(request.skuItems[0].productName, '胡桃色 120cm 茶几');
assert.equal(request.skuItems[1].productName, '原木色 90cm 茶几');
assert.deepEqual(request.skuItems[0], {
productName: '胡桃色 120cm 茶几',
colorSpec: '胡桃色;120cm',
lengthCm: 120,
widthCm: 60,
heightCm: 45,
weight: 20,
});
});
test('product-code result must match SKU count, order and exact confirmed names', () => {
const response = {
styleCode: 'STYLE-001',
items: [
{ productCode: 'SKU-001-01', productName: rows[0].selectedSkuName, colorSpec: rows[0].colorSpec },
{ productCode: 'SKU-001-02', productName: rows[1].selectedSkuName, colorSpec: rows[1].colorSpec },
],
};
assert.deepEqual(validateProductCodeResponse(response, rows).map((row) => row.productCode), [
'SKU-001-01',
'SKU-001-02',
]);
assert.throws(
() => validateProductCodeResponse({
...response,
items: [response.items[1], response.items[0]],
}, rows),
(error) => error.code === 'PRODUCT_CODE_NAME_MISMATCH' && error.indeterminate === true
);
});
test('product-code request hash changes when SKU order or final name changes', () => {
const request = buildProductCodeRequest(configInput, rows, { name: '测试运营' });
const originalHash = buildProductCodeRequestHash(request, rows);
const reversedRows = [...rows].reverse();
const reversedHash = buildProductCodeRequestHash(
buildProductCodeRequest(configInput, reversedRows, { name: '测试运营' }),
reversedRows
);
const renamedRows = rows.map((row, index) => index === 0
? { ...row, selectedSkuName: `${row.selectedSkuName} 新名称` }
: row);
const renamedHash = buildProductCodeRequestHash(
buildProductCodeRequest(configInput, renamedRows, { name: '测试运营' }),
renamedRows
);
assert.notEqual(originalHash, reversedHash);
assert.notEqual(originalHash, renamedHash);
});
test('1688 pricing confirmation reuses the global registry and never requests another code set', () => {
const serviceSource = fs.readFileSync(
path.join(__dirname, '../src/services/planningSelectionFissionService.js'),
'utf8'
);
const saveStart = serviceSource.indexOf('async function saveSelectionFissionProfitPricingTable');
const saveEnd = serviceSource.indexOf('\nasync function generateSelectionFissionSkuNames', saveStart);
assert.notEqual(saveStart, -1);
assert.notEqual(saveEnd, -1);
const saveSource = serviceSource.slice(saveStart, saveEnd);
assert.match(saveSource, /loadAlibaba1688GlobalEncoding/);
assert.match(saveSource, /product_code_status = 'completed'/);
assert.doesNotMatch(saveSource, /createProductCodes|getProductCodeMeta/);
assert.doesNotMatch(saveSource, /product_code_status = 'requesting'/);
});