Files
docs/悦/货代SAAS平台后台/tests/verify-customer-service-exception-orders.cjs
T
2026-08-22 09:50:50 +08:00

138 lines
5.2 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const root = path.resolve(__dirname, '..');
const sourceRoot = path.join(root, 'prototype-src');
const shell = fs.readFileSync(path.join(sourceRoot, 'shell.html'), 'utf8');
const manifest = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'manifest.json'), 'utf8'));
const overseasDelivery = fs.readFileSync(
path.join(sourceRoot, 'modules/04-overseas-delivery.html'),
'utf8',
);
const customerServicePath = path.join(sourceRoot, 'modules/04a-customer-service.html');
const customerService = fs.existsSync(customerServicePath)
? fs.readFileSync(customerServicePath, 'utf8')
: '';
const app = fs.readFileSync(path.join(sourceRoot, 'app.js'), 'utf8');
function sidebarItemStart(source, marker) {
const markerIndex = source.indexOf(marker);
return markerIndex < 0 ? -1 : source.lastIndexOf('<div class="sidebar-item"', markerIndex);
}
function sidebarItemAt(source, start) {
if (start < 0) return '';
const nextStart = source.indexOf('<div class="sidebar-item"', start + 1);
return source.slice(start, nextStart < 0 ? source.length : nextStart);
}
function sidebarItemStartByLabel(source, label) {
const starts = [...source.matchAll(/<div class="sidebar-item"(?:\s[^>]*)?>/g)].map(
match => match.index,
);
return starts.find((start, index) => {
const item = source.slice(start, starts[index + 1] ?? source.length);
const labelEnd = item.indexOf('</div>');
return labelEnd >= 0 && item.slice(0, labelEnd).includes(label);
}) ?? -1;
}
function countMatches(source, pattern) {
return [...source.matchAll(pattern)].length;
}
function pageSource(source, pageId) {
const pagePattern = new RegExp(`<div\\b[^>]*\\bid=(["'])page-${pageId}\\1[^>]*>`);
const match = pagePattern.exec(source);
if (!match) return '';
const nextPagePattern = /<div\b[^>]*\bid=["']page-/g;
nextPagePattern.lastIndex = match.index + match[0].length;
const nextPage = nextPagePattern.exec(source);
return source.slice(match.index, nextPage ? nextPage.index : source.length);
}
const outboundNavStart = sidebarItemStart(shell, 'data-menu="outbound"');
const supplierNavStart = sidebarItemStart(shell, 'data-menu="supplier"');
const customerServiceNavStart = sidebarItemStartByLabel(shell, '客户服务');
assert.ok(customerServiceNavStart >= 0, '侧栏缺少客户服务导航');
assert.ok(outboundNavStart >= 0, '侧栏缺少海外派送导航');
assert.ok(supplierNavStart >= 0, '侧栏缺少供应商中心导航');
assert.ok(
outboundNavStart < customerServiceNavStart && customerServiceNavStart < supplierNavStart,
'客户服务导航必须位于海外派送之后、供应商中心之前',
);
const outboundNav = sidebarItemAt(shell, outboundNavStart);
const customerServiceNav = sidebarItemAt(shell, customerServiceNavStart);
assert.doesNotMatch(
outboundNav,
/outbound-exception|异常订单/,
'海外派送导航不应再包含异常订单',
);
assert.match(
customerServiceNav,
/switchPage\(\s*['"]outbound-exception['"]\s*,\s*this\s*\)/,
'客户服务导航缺少 outbound-exception 入口',
);
assert.match(customerServiceNav, />\s*异常订单\s*</, '客户服务导航缺少异常订单文案');
const overseasDeliveryIndex = manifest.modules.findIndex(
item => item.file === 'modules/04-overseas-delivery.html',
);
const customerServiceIndex = manifest.modules.findIndex(
item => item.file === 'modules/04a-customer-service.html',
);
const customerServiceModule = manifest.modules[customerServiceIndex];
assert.ok(overseasDeliveryIndex >= 0, 'manifest 缺少海外派送模块');
assert.ok(customerServiceIndex >= 0, 'manifest 缺少客户服务模块');
assert.equal(customerServiceModule.title, '客户服务', '客户服务模块标题不正确');
assert.equal(
customerServiceIndex,
overseasDeliveryIndex + 1,
'客户服务模块必须紧邻海外派送之后',
);
assert.ok(
customerServiceModule.pages.includes('outbound-exception'),
'客户服务模块必须归属 outbound-exception 页面',
);
assert.ok(
!manifest.modules[overseasDeliveryIndex].pages.includes('outbound-exception'),
'海外派送模块不应再归属 outbound-exception 页面',
);
assert.equal(
countMatches(overseasDelivery, /id=["']page-outbound-exception["']/g),
0,
'海外派送模块仍包含 page-outbound-exception',
);
assert.equal(
countMatches(customerService, /id=["']page-outbound-exception["']/g),
1,
'客户服务模块必须且只能包含一个 page-outbound-exception',
);
const exceptionPage = pageSource(customerService, 'outbound-exception');
assert.match(
exceptionPage,
/class=["']breadcrumb["'][^>]*>[\s\S]*?客户服务[\s\S]*?<strong>\s*异常订单\s*<\/strong>/,
'异常订单页面面包屑必须归属客户服务',
);
assert.match(
exceptionPage,
/onclick=["']switchPage\(\s*['"]outbound-dispatch['"]\s*,\s*this\s*\)["'][^>]*>\s*返回派送单\s*<\/button>/,
'异常订单页面必须保留原有返回派送单链接',
);
assert.match(
app,
/if\s*\(\s*page\s*===\s*['"]outbound-exception['"]\s*\)\s*renderDispatchExceptions\s*\(\s*\)\s*;/,
'app.js 必须继续通过 renderDispatchExceptions() 渲染 outbound-exception',
);
console.log('CUSTOMER_SERVICE_EXCEPTION_ORDERS_CHECK_PASS');