153 lines
5.4 KiB
JavaScript
153 lines
5.4 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
|
|
const html = fs.readFileSync('workbench.html', 'utf8');
|
|
|
|
function extractFunction(name) {
|
|
const start = html.indexOf(`function ${name}(`);
|
|
assert.notEqual(start, -1, `${name} should exist`);
|
|
const bodyStart = html.indexOf('{', start);
|
|
let depth = 0;
|
|
for (let index = bodyStart; index < html.length; index += 1) {
|
|
if (html[index] === '{') depth += 1;
|
|
if (html[index] === '}') depth -= 1;
|
|
if (depth === 0) return html.slice(start, index + 1);
|
|
}
|
|
throw new Error(`Unable to extract ${name}`);
|
|
}
|
|
|
|
const getLabelingRelationTemplateRows = vm.runInNewContext(
|
|
`(${extractFunction('getLabelingRelationTemplateRows')})`
|
|
);
|
|
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(getLabelingRelationTemplateRows())),
|
|
[['箱唛', '需贴箱唛', '需贴SKU标', '备注']],
|
|
'the downloaded relation template should expose the required columns in order'
|
|
);
|
|
|
|
const createPage = html.match(/<div class="page-content" id="page-labeling">([\s\S]*?)<!-- ========== MODAL: 编辑贴标申请/)?.[1] || '';
|
|
assert.match(
|
|
createPage,
|
|
/onclick="downloadLabelingRelationTemplate\(\)"[\s\S]*?onclick="addLabelingRow\(\)"/,
|
|
'the relation template download should appear before Add row'
|
|
);
|
|
|
|
let writtenWorkbook = null;
|
|
let writtenFileName = '';
|
|
const downloadLabelingRelationTemplate = vm.runInNewContext(
|
|
`(${extractFunction('downloadLabelingRelationTemplate')})`,
|
|
{
|
|
getLabelingRelationTemplateRows,
|
|
showToast: () => {},
|
|
XLSX: {
|
|
utils: {
|
|
aoa_to_sheet: rows => ({ rows }),
|
|
book_new: () => ({ sheets: [] }),
|
|
book_append_sheet: (workbook, worksheet, name) => workbook.sheets.push({ worksheet, name })
|
|
},
|
|
writeFile: (workbook, fileName) => {
|
|
writtenWorkbook = workbook;
|
|
writtenFileName = fileName;
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
downloadLabelingRelationTemplate();
|
|
assert.equal(writtenFileName, '贴标关联模板.xlsx');
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(writtenWorkbook.sheets)),
|
|
[{ worksheet: { rows: [['箱唛', '需贴箱唛', '需贴SKU标', '备注']], '!cols': [{ wch: 24 }, { wch: 14 }, { wch: 14 }, { wch: 32 }] }, name: '关联明细' }]
|
|
);
|
|
|
|
const generatedRow = {
|
|
innerHTML: '',
|
|
querySelector: selector => selector === '.labeling-requirement' ? { value: '' } : null
|
|
};
|
|
const createLabelingRow = vm.runInNewContext(
|
|
`(${extractFunction('createLabelingRow')})`,
|
|
{
|
|
document: { createElement: () => generatedRow },
|
|
escapeLabelingHtml: value => String(value == null ? '' : value)
|
|
}
|
|
);
|
|
createLabelingRow({ relationFileName: '关联表.xlsx', itemRemark: '优先处理 A 箱' });
|
|
assert.match(generatedRow.innerHTML, /class="[^"]*labeling-relation-file[^"]*"[\s\S]*?关联表\.xlsx/);
|
|
assert.match(generatedRow.innerHTML, /class="form-input labeling-item-remark"[\s\S]*?value="优先处理 A 箱"/);
|
|
|
|
const fileControl = (selectedName, existingName) => ({
|
|
files: selectedName ? [{ name: selectedName }] : [],
|
|
dataset: { existingFile: existingName || '' }
|
|
});
|
|
const controls = {
|
|
'.labeling-sku': { value: ' SKU-100 ' },
|
|
'.labeling-name': { value: ' 商品一 ' },
|
|
'.labeling-boxes': { value: '3' },
|
|
'.labeling-transfer-boxes': { value: '2' },
|
|
'.labeling-shipment-no': { value: ' FBA-1 ' },
|
|
'.labeling-tracking-no': { value: ' TRACK-1 ' },
|
|
'.labeling-new-sku': { value: ' NEW-100 ' },
|
|
'.labeling-requirement': { value: '换SKU标' },
|
|
'.labeling-label-file input[type="file"]': fileControl('', '贴标文件.pdf'),
|
|
'.labeling-relation-file input[type="file"]': fileControl('新关联表.xlsx', '旧关联表.xlsx'),
|
|
'.labeling-item-remark': { value: ' 易碎品 ' }
|
|
};
|
|
const collectLabelingRows = vm.runInNewContext(`(${extractFunction('collectLabelingRows')})`);
|
|
const collectedRows = collectLabelingRows({
|
|
querySelectorAll: () => [{ querySelector: selector => controls[selector] || null }]
|
|
});
|
|
assert.deepEqual(JSON.parse(JSON.stringify(collectedRows)), [{
|
|
sku: 'SKU-100',
|
|
name: '商品一',
|
|
boxes: 3,
|
|
transferBoxes: 2,
|
|
shipmentNo: 'FBA-1',
|
|
trackingNo: 'TRACK-1',
|
|
newSku: 'NEW-100',
|
|
requirement: '换SKU标',
|
|
fileName: '贴标文件.pdf',
|
|
relationFileName: '新关联表.xlsx',
|
|
itemRemark: '易碎品'
|
|
}]);
|
|
|
|
let savedOrders = null;
|
|
const dataRow = { querySelector: selector => controls[selector] || null };
|
|
const labelingTbody = {
|
|
querySelector: () => null,
|
|
querySelectorAll: () => [dataRow]
|
|
};
|
|
const labelingForm = {
|
|
checkValidity: () => true,
|
|
elements: {
|
|
inboundNo: { value: 'RK001' },
|
|
deadline: { value: '2026-09-10T10:00' },
|
|
contact: { value: '联系人' },
|
|
phone: { value: '13800000000' },
|
|
remark: { value: '订单备注' }
|
|
}
|
|
};
|
|
const submitLabeling = vm.runInNewContext(
|
|
`(${extractFunction('submitLabeling')})`,
|
|
{
|
|
document: { getElementById: id => id === 'labeling-form' ? labelingForm : labelingTbody },
|
|
getLabelingInboundByNo: () => ({ warehouse: '美西洛杉矶仓' }),
|
|
loadLabelingOrders: () => [],
|
|
collectLabelingRows,
|
|
saveLabelingOrders: orders => { savedOrders = orders; return true; },
|
|
renderLabelingList: () => {},
|
|
openLabelingList: () => {},
|
|
showToast: () => {},
|
|
labelingFilteredOrders: null
|
|
}
|
|
);
|
|
submitLabeling({ preventDefault: () => {} });
|
|
assert.deepEqual(
|
|
JSON.parse(JSON.stringify(savedOrders[0].items)),
|
|
JSON.parse(JSON.stringify(collectedRows)),
|
|
'creating an order should persist all per-row labeling data'
|
|
);
|
|
|
|
console.log('labeling relation fields: ok');
|