114 lines
6.7 KiB
JavaScript
114 lines
6.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|||
|
|
import { existsSync, readFileSync } from 'node:fs';
|
||
|
|
import { fileURLToPath } from 'node:url';
|
||
|
|
import path from 'node:path';
|
||
|
|
import { test } from 'node:test';
|
||
|
|
|
||
|
|
const prototypePath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '官网头程下单', 'workbench.html');
|
||
|
|
const html = existsSync(prototypePath) ? readFileSync(prototypePath, 'utf8') : '';
|
||
|
|
|
||
|
|
function fn(name) {
|
||
|
|
const start = html.indexOf(`function ${name}(`);
|
||
|
|
assert.ok(start >= 0, `${name} should exist`);
|
||
|
|
const next = html.indexOf('\n function ', start + 1);
|
||
|
|
return html.slice(start, next >= 0 ? next : html.length);
|
||
|
|
}
|
||
|
|
|
||
|
|
test('sea order navigation exposes only three business entry points', () => {
|
||
|
|
const group = html.match(/<!-- 出海下单 -->([\s\S]*?)<!-- 海外仓 -->/);
|
||
|
|
assert.ok(group, 'sea order menu should exist');
|
||
|
|
assert.equal((group[1].match(/data-sea-action=/g) || []).length, 0);
|
||
|
|
const entries = [...group[1].matchAll(/data-business="(Procurement|Truck|Pallet)"[^>]*onclick="([^"]+)"/g)];
|
||
|
|
assert.equal(entries.length, 3);
|
||
|
|
for (const [type, label] of [['Procurement', '海外采购'], ['Truck', '美国本土卡'], ['Pallet', '美本土散板']]) {
|
||
|
|
const entry = entries.find(([, , onclick]) => onclick.includes(`openSeaBusiness('${type}','list'`));
|
||
|
|
assert.ok(entry, `${label} navigation entry should open its list page`);
|
||
|
|
assert.match(entry[0], new RegExp(`data-business="${type}"`));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
test('three sea business list pages include add, query, and order lists', () => {
|
||
|
|
const cases = [
|
||
|
|
['sea-procurement-page', 'Procurement', '海外采购', ['订单号', '采购品类', '商品规格', '采购数量', '预算单价', '状态', '操作']],
|
||
|
|
['sea-truck-page', 'Truck', '美国本土卡', ['操作', '订单编号', '运输类型', '起运地', '目的地', '柜型', '总重量(kg)', '预算总价', '要求时间', '状态']],
|
||
|
|
['sea-pallet-page', 'Pallet', '美本土散板', ['操作', '订单编号', '运输方式', '是否打盘', '运输类型', '起运地', '目的地', '总重量(kg)', '预算总价', '要求时间', '状态']],
|
||
|
|
];
|
||
|
|
for (const [id, type, label, headers] of cases) {
|
||
|
|
const start = html.indexOf(`id="${id}"`);
|
||
|
|
assert.ok(start >= 0, `${id} should exist`);
|
||
|
|
const page = html.slice(start, html.indexOf('</section>', start) + 10);
|
||
|
|
assert.match(page, new RegExp(label));
|
||
|
|
assert.match(page, new RegExp(`openSeaBusiness\\('${type}','new'`));
|
||
|
|
assert.match(page, new RegExp(`querySeaOrders\\('${type}'\\)`));
|
||
|
|
assert.match(page, new RegExp(`resetSeaOrders\\('${type}'\\)`));
|
||
|
|
for (const header of headers) assert.match(page, new RegExp(`<th>${header.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}</th>`));
|
||
|
|
}
|
||
|
|
const truckStart = html.indexOf('id="sea-truck-page"');
|
||
|
|
const truckPage = html.slice(truckStart, html.indexOf('</section>', truckStart) + 10);
|
||
|
|
assert.doesNotMatch(truckPage, /<th>联系人<\/th>|<th>联系方式<\/th>/);
|
||
|
|
assert.match(html.slice(html.indexOf('data-order-form="Truck"'), html.indexOf('</form>', html.indexOf('data-order-form="Truck"'))), /name="预算总价"/);
|
||
|
|
const palletStart = html.indexOf('id="sea-pallet-page"');
|
||
|
|
const palletPage = html.slice(palletStart, html.indexOf('</section>', palletStart) + 10);
|
||
|
|
assert.doesNotMatch(palletPage, /<th>联系人<\/th>|<th>联系方式<\/th>/);
|
||
|
|
assert.match(html.slice(html.indexOf('data-order-form="Pallet"'), html.indexOf('</form>', html.indexOf('data-order-form="Pallet"'))), /name="预算总价"/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('all sea business orders support edit and detail actions', () => {
|
||
|
|
for (const name of ['openSeaOrderEditor', 'closeSeaOrderEditor', 'saveSeaOrderEdit', 'showSeaOrderDetail']) fn(name);
|
||
|
|
assert.match(fn('renderSeaOrders'), /openSeaOrderEditor/);
|
||
|
|
assert.match(fn('renderSeaOrders'), /showSeaOrderDetail/);
|
||
|
|
assert.match(html, /id="sea-order-edit-modal"/);
|
||
|
|
assert.match(html, /id="sea-order-edit-form"/);
|
||
|
|
assert.match(fn('openSeaOrderEditor'), /data-order-form/);
|
||
|
|
assert.match(fn('saveSeaOrderEdit'), /seaOrders\[type\]/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('sea business details expose business, carrier, and progress information', () => {
|
||
|
|
const details = [
|
||
|
|
['sea-procurement-detail', ['商品信息', '订单信息', '快递信息']],
|
||
|
|
['sea-truck-detail', ['运输信息', '货物信息', '承运商信息', '运输进度']],
|
||
|
|
['sea-pallet-detail', ['运输信息', '货物信息', '承运商信息', '运输进度']],
|
||
|
|
];
|
||
|
|
for (const [id, sections] of details) {
|
||
|
|
const start = html.indexOf(`id="${id}"`);
|
||
|
|
assert.ok(start >= 0, `${id} should exist`);
|
||
|
|
const detail = html.slice(start, html.indexOf('</section>', start) + 10);
|
||
|
|
for (const section of sections) assert.match(detail, new RegExp(section));
|
||
|
|
assert.match(detail, /data-detail-content/);
|
||
|
|
}
|
||
|
|
const procurementDetail = html.slice(html.indexOf('id="sea-procurement-detail"'), html.indexOf('</section>', html.indexOf('id="sea-procurement-detail"')) + 10);
|
||
|
|
assert.doesNotMatch(procurementDetail, /采购进度/);
|
||
|
|
assert.doesNotMatch(procurementDetail, /承运商信息/);
|
||
|
|
assert.match(procurementDetail, /data-detail-content="预算总价"/);
|
||
|
|
for (const field of ['订单号', '采购数量', '预算单价', '订单状态', '联系人', '联系电话', '收货地址', '订单备注']) {
|
||
|
|
assert.match(procurementDetail, new RegExp(field));
|
||
|
|
}
|
||
|
|
for (const field of ['国内快递公司', '国内运单号', '海外快递公司', '海外运单号']) {
|
||
|
|
assert.match(procurementDetail, new RegExp(`data-detail-content="${field}"`));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
test('sea business routing reuses existing forms and isolates order state', () => {
|
||
|
|
for (const name of ['showSeaBusinessPage', 'showSeaBusinessOrderForm', 'openSeaBusiness', 'renderSeaOrders', 'querySeaOrders', 'resetSeaOrders']) fn(name);
|
||
|
|
assert.match(html, /const\s+seaOrders\s*=\s*\{\s*Procurement:\s*\[/);
|
||
|
|
assert.match(html, /data-order-form="Procurement"/);
|
||
|
|
assert.match(html, /data-order-form="Truck"/);
|
||
|
|
assert.match(html, /data-order-form="Pallet"/);
|
||
|
|
assert.doesNotMatch(fn('openSeaBusiness'), /data-sea-action/);
|
||
|
|
assert.match(fn('openSeaBusiness'), /dash-nav-link\[data-business=/);
|
||
|
|
assert.match(fn('openOrder'), /openSeaBusiness\(type,'new'/);
|
||
|
|
assert.match(fn('querySeaOrders'), /seaOrders\[type\]/);
|
||
|
|
assert.match(html, /function\s+collectSeaOrderFields\s*\(/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('sea business controls match overseas warehouse colors', () => {
|
||
|
|
const styleStart = html.indexOf('.sea-business-page');
|
||
|
|
const styleEnd = html.indexOf('</style>', styleStart);
|
||
|
|
const styles = html.slice(styleStart, styleEnd);
|
||
|
|
assert.match(styles, /\.sea-business-page[^{}]*\.btn-primary|\.sea-business-form-panel[^{}]*\.btn-primary/);
|
||
|
|
assert.match(styles, /#667eea/);
|
||
|
|
assert.match(styles, /#764ba2/);
|
||
|
|
assert.match(styles, /\.sea-business-page \.sea-order-table th/);
|
||
|
|
assert.match(styles, /color:\s*#667eea/);
|
||
|
|
});
|