Files
docs/悦/货代SAAS平台后台/tests/verify-overseas-warehouse-quote.cjs
T

140 lines
5.4 KiB
JavaScript
Raw Normal View History

2026-08-21 09:20:26 +08:00
#!/usr/bin/env node
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 general = fs.readFileSync(path.join(sourceRoot, 'modules/10-general.html'), 'utf8');
const shell = fs.readFileSync(path.join(sourceRoot, 'shell.html'), 'utf8');
const app = fs.readFileSync(path.join(sourceRoot, 'app.js'), 'utf8');
const manifest = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'manifest.json'), 'utf8'));
const generalModule = manifest.modules.find(module => module.file === 'modules/10-general.html');
assert.ok(generalModule, 'manifest 中缺少通用资料模块');
const genPartnerModuleIndex = generalModule.pages.indexOf('gen-partner-warehouse');
assert.ok(genPartnerModuleIndex >= 0, '通用资料模块缺少 gen-partner-warehouse 页面');
assert.equal(
generalModule.pages[genPartnerModuleIndex + 1],
'gen-overseas-quote',
'gen-overseas-quote 应紧跟完整仓库页签组登记在通用资料模块中'
);
const genPartnerOrderIndex = manifest.pageOrder.indexOf('gen-partner-warehouse');
assert.ok(genPartnerOrderIndex >= 0, '顶层 pageOrder 缺少 gen-partner-warehouse');
assert.equal(
manifest.pageOrder[genPartnerOrderIndex + 1],
'gen-overseas-quote',
'gen-overseas-quote 应紧跟完整仓库页签组登记在顶层 pageOrder 中'
);
assert.match(
shell,
/switchPage\('gen-owned-warehouse',this\)"[^>]*>仓库管理<\/div>\s*<div class="sub-menu-item" onclick="switchPage\('gen-overseas-quote',this\)">海外仓报价<\/div>/,
'通用导航中海外仓报价入口必须紧跟仓库管理'
);
assert.equal(
(general.match(/id="page-gen-overseas-quote"/g) || []).length,
1,
'10-general.html 中 page-gen-overseas-quote 必须恰好出现一次'
);
assert.match(
general,
/#page-gen-overseas-quote \.goq-table\{min-width:1480px;table-layout:fixed;font-size:12px\}/,
'海外仓报价列表应为加宽后的操作列保留表格横向空间'
);
assert.match(
general,
/#page-gen-overseas-quote \.goq-table th:first-child,#page-gen-overseas-quote \.goq-table td:first-child\{width:250px\}/,
'海外仓报价列表操作列宽度应容纳详情、编辑、停用和删除按钮'
);
const quotePageStart = general.indexOf('<div class="page" id="page-gen-overseas-quote">');
const quotePageEnd = general.indexOf('<div class="page"', quotePageStart + 1);
const quotePage = general.slice(quotePageStart, quotePageEnd < 0 ? general.length : quotePageEnd);
for (const field of [
'报价名称',
'海外仓',
'服务商',
'币种',
'生效日期',
'失效日期',
'报价版本',
'仓储作业费用',
'中转派送价格',
'目的 FBA 仓',
'车型/提货方式',
'预估迈数',
'最低收费'
]) {
assert.ok(quotePage.includes(field), `海外仓报价页面缺少字段:${field}`);
}
assert.match(
general,
/id="modal-gen-overseas-quote-detail"/,
'10-general.html 缺少海外仓报价独立详情弹窗'
);
for (const functionName of [
'renderOverseasWarehouseQuotes',
'resetOverseasWarehouseQuoteFilters',
'openOverseasWarehouseQuoteDetail',
'renderOverseasWarehouseQuoteDetail',
'openOverseasWarehouseQuoteModal',
'addOverseasWarehouseFeeRow',
'addOverseasTransitPriceRow',
'saveOverseasWarehouseQuote',
'toggleOverseasWarehouseQuoteStatus',
'deleteOverseasWarehouseQuote'
]) {
assert.match(app, new RegExp(`function\\s+${functionName}\\s*\\(`), `app.js 缺少函数:${functionName}`);
}
function getFunctionSource(functionName) {
const start = app.search(new RegExp(`function\\s+${functionName}\\s*\\(`));
assert.ok(start >= 0, `app.js 缺少函数:${functionName}`);
const sourceFromFunction = app.slice(start);
const nextFunctionOffset = sourceFromFunction.slice(1).search(/\nfunction\s+[A-Za-z_$][\w$]*\s*\(/);
return nextFunctionOffset < 0
? sourceFromFunction
: sourceFromFunction.slice(0, nextFunctionOffset + 1);
}
const quoteListSource = getFunctionSource('renderOverseasWarehouseQuotes');
const quoteDetailButtonMatch = quoteListSource.match(
/<button\b[^>]*\bonclick="openOverseasWarehouseQuoteDetail\([^\"]*\)"[^>]*>\s*详情\s*<\/button>/
);
const quoteEditButtonMatch = quoteListSource.match(
/<button\b[^>]*\bonclick="openOverseasWarehouseQuoteModal\([^\"]*\)"[^>]*>\s*编辑\s*<\/button>/
);
assert.ok(
quoteDetailButtonMatch &&
quoteEditButtonMatch &&
quoteDetailButtonMatch.index < quoteEditButtonMatch.index,
'海外仓报价列表首位缺少“详情”入口'
);
const quoteDetailSource = [
getFunctionSource('openOverseasWarehouseQuoteDetail'),
getFunctionSource('renderOverseasWarehouseQuoteDetail')
].join('\n');
assert.match(
quoteDetailSource,
/openOverseasWarehouseQuoteModal\s*\(/,
'海外仓报价详情缺少进入现有编辑弹窗的路径'
);
const quoteDataStart = app.search(/overseasWarehouseQuoteData\s*=\s*\[/);
assert.ok(quoteDataStart >= 0, 'app.js 缺少 overseasWarehouseQuoteData 数组');
const quoteDataEnd = app.indexOf('];', quoteDataStart);
assert.ok(quoteDataEnd > quoteDataStart, 'overseasWarehouseQuoteData 数组缺少结束标记');
const quoteDataSource = app.slice(quoteDataStart, quoteDataEnd + 2);
assert.match(quoteDataSource, /warehouseFees\s*:/, '报价数据缺少 warehouseFees 字段');
assert.match(quoteDataSource, /transitPrices\s*:/, '报价数据缺少 transitPrices 字段');
console.log('海外仓报价源码契约验证通过。');