import test from 'node:test' import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' const read = (path) => readFile(new URL(path, import.meta.url), 'utf8') test('domestic workbench exposes a real one-click dropship palletization entry', async () => { const [data, home, modulePage, pages] = await Promise.all([ read('../data/demo-data.js'), read('../pages/home/home.vue'), read('../pages/module/module.vue'), read('../pages.json') ]) assert.match(data, /key: 'inbound'[\s\S]*?name: '一件代发'[\s\S]*?available: true, visible: true/) assert.match(home, /'一件代发': '\/pages\/dropship-tasks\/dropship-tasks'/) assert.match(modulePage, /'一件代发': '\/pages\/dropship-tasks\/dropship-tasks'/) assert.match(pages, /pages\/dropship-tasks\/dropship-tasks/) assert.match(pages, /pages\/dropship-palletization\/dropship-palletization/) }) test('dropship palletization adapter uses only the dedicated production PDA contract', async () => { const api = await read('../api/pda-dropship.js') for (const route of [ '/tasks/pending', '/cartons/resolve', '/cartons/count', '/pallets/bind-pending', '/seal', '/unseal' ]) assert.match(api, new RegExp(route.replaceAll('/', '\\/'))) assert.doesNotMatch(api, /apiDownload|downloadAllDropshipPalletLabels|pallets\/print/) assert.match(api, /tasks\/pending\?\$\{params\.join\('&'\)\}/) assert.match(api, /warehouseId=\$\{encodeURIComponent\(warehouseId\)\}/) assert.match(api, /operationId\('count'/) assert.match(api, /operationId\('bind'/) assert.match(api, /function stableId\(value\)[\s\S]*?String\(value \?\? ''\)\.trim\(\)/) assert.match(api, /warehouseId: stableId\(warehouseId\)/) assert.match(api, /warehouseId: stableId\(payload\.warehouseId\)/) assert.doesNotMatch(api, /customerId|tenantId|inboundId/) }) test('palletization UI accepts carton and pre-generated pallet scans in either order', async () => { const [tasks, work] = await Promise.all([ read('../pages/dropship-tasks/dropship-tasks.vue'), read('../pages/dropship-palletization/dropship-palletization.vue') ]) for (const text of ['待入库任务', '入仓码', '进入作业']) assert.match(tasks, new RegExp(text)) assert.match(tasks, /\.search-card\s*\{[^}]*display:\s*flex;[^}]*box-shadow:\s*none;/) assert.match(tasks, /\.task-list\s*\{[^}]*overflow:\s*hidden;[^}]*border-radius:\s*7px;/) assert.match(tasks, /\.task-card\s*\{[^}]*margin:\s*0;[^}]*border-radius:\s*0;[^}]*box-shadow:\s*none;/) for (const text of ['一件代发入库', '领取并开始入库', '扫箱清点', '读取 SKU', '确认清点', '扫托盘', '可选', '差异说明', '托盘码', '封托']) assert.match(work, new RegExp(text)) for (const text of ['sku-label', 'sku-code', 'quantity-stepper', 'adjustQuantity']) assert.match(work, new RegExp(text)) assert.match(work, /减少 \$\{line\.skuCode\} 清点数量/) assert.match(work, /增加 \$\{line\.skuCode\} 清点数量/) for (const text of ['compact-metrics', 'compact-action']) assert.match(work, new RegExp(text)) assert.match(work, /task\.customerName/) assert.match(work, /\.task-summary-card, \.section-card \{[^}]*border:\s*0;[^}]*border-bottom:\s*6px solid[^}]*border-radius:\s*0;[^}]*box-shadow:\s*none;/) assert.match(work, /\.carton-card, \.pallet-card \{[^}]*border:\s*0;[^}]*border-top:\s*1px solid[^}]*border-radius:\s*0;[^}]*background:\s*transparent;/) for (const text of ['计划 {{ carton.expectedSkuQuantity', "carton.cargoName", "carton.countStatus === 'UNCOUNTED'"]) assert.doesNotMatch(work, new RegExp(text)) assert.match(work, /canResolveCarton\(\)[\s\S]*?boxCode[\s\S]*?!this\.loading[\s\S]*?!this\.submitting/) for (const text of ['expectedPalletCount', 'generatedPalletCount', 'palletSetupReady', 'palletSetupMessage']) assert.match(work, new RegExp(text)) assert.match(work, /