import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { overseasWarehouseLabel } from './inboundPlanDisplay.ts' const api = readFileSync(new URL('./api/inboundPlans.ts', import.meta.url), 'utf8') const routes = readFileSync(new URL('./routes.ts', import.meta.url), 'utf8') const view = readFileSync(new URL('./views/InboundOrdersView.vue', import.meta.url), 'utf8') const overseasHttp = readFileSync(new URL('../../api/overseasHttp.ts', import.meta.url), 'utf8') test('activates the customer-scoped overseas inbound list and detail', () => { assert.match(routes, /path: 'orders\/inbound'[\s\S]*?release: 'active'[\s\S]*?permission: 'merchant:warehouse:inbound:list'/) assert.match(routes, /path: 'orders\/inbound\/:planNo\/detail'[\s\S]*?name: 'orders-inbound-detail'/) assert.match(api, /\/merchant\/v1\/last-leg\/inbound-plans/) assert.match(api, /encodeURIComponent\(planNo\)/) assert.doesNotMatch(api, /\/platform\/|\/internal\/|customerId|tenantId/) assert.doesNotMatch(view, /customerId|tenantId/) }) test('keeps actions first and exposes filters loading errors empty state pagination and business identifiers', () => { assert.match(view, /label: '操作', slotName: 'actions'[^\n]*fixed: 'left'/) for (const token of ['planNo', 'inboundCode', 'destinationWarehouseCode', 'appointmentStatus', 'dispatchStatus', 'createdDates']) assert.match(view, new RegExp(token)) assert.match(view, /v-loading="loading"/) assert.match(view, /type="error"/) assert.match(view, /empty-text="暂无入库订单"/) assert.match(view, /]*v-model:page="query\.page"/) assert.match(view, /detail\.planNo/) assert.doesNotMatch(view, /planId|orderId|warehouseId|customerId/) }) test('shows only the server-provided overseas receiving warehouse code and name', () => { assert.equal((api.match(/overseasWarehouseCode\?: string \| null/g) || []).length, 2) assert.equal((api.match(/overseasWarehouseName\?: string \| null/g) || []).length, 2) assert.doesNotMatch(api, /overseasWarehouseId/) assert.match(view, /label: '海外接柜仓'/) assert.match(view, /overseasWarehouseLabel\(row\.overseasWarehouseCode, row\.overseasWarehouseName\)/) assert.match(view, /overseasWarehouseLabel\(detail\.overseasWarehouseCode, detail\.overseasWarehouseName\)/) assert.doesNotMatch(view, /warehouseName \|\| warehouseCode|destinationWarehouse(?:Id|Code|Name).*overseasWarehouse/i) }) test('renders a dash when either formal receiving warehouse field is absent', () => { assert.equal(overseasWarehouseLabel('US-LAX-01', '洛杉矶仓'), 'US-LAX-01 · 洛杉矶仓') assert.equal(overseasWarehouseLabel(' US-LAX-01 ', ' 洛杉矶仓 '), 'US-LAX-01 · 洛杉矶仓') for (const pair of [ [undefined, undefined], [null, null], ['', '洛杉矶仓'], ['US-LAX-01', ''], [undefined, '洛杉矶仓'], ['US-LAX-01', undefined], [' ', '洛杉矶仓'], ['US-LAX-01', ' '], ]) assert.equal(overseasWarehouseLabel(pair[0], pair[1]), '—') }) test('preserves overseas API diagnostic metadata without rendering it as a business identifier', () => { assert.match(overseasHttp, /response\.data\.traceId/) assert.match(overseasHttp, /response\.data\.requestId/) assert.match(overseasHttp, /body\.traceId, body\.requestId/) assert.doesNotMatch(view, /requestId|traceId/) }) test('renders inbound workflow statuses in Chinese and keeps desktop values on one line', () => { for (const [status, label] of [ ['PENDING_ASSIGNMENT', '待分配'], ['PDA_PENDING', '待入库'], ['ASSIGNED', '已分配'], ['SIGNED', '已签收'], ['PICKING', '拣货中'], ['PARTIAL_INBOUND', '部分入库'], ]) assert.match(view, new RegExp(`${status}: '${label}'`)) assert.match(view, /COMPLETED: '全部入库'/) assert.match(view, /label: '状态', slotName: 'status', width: 120/) assert.match(view, /\.detail-grid div \{ display: grid; min-width: 0; min-height: 42px;/) assert.match(view, /\.detail-grid dd \{[^}]*overflow: hidden;[^}]*text-overflow: ellipsis;[^}]*white-space: nowrap;/) }) test('uses the shared compact detail surface instead of stacked cards', () => { assert.match(view, /
/) assert.match(view, /name: 'orders-inbound-detail', params: \{ planNo: row\.planNo \}/) assert.match(view, /]*\/>返回列表<\/el-button>/) assert.match(view, /class="client-status" :data-tone="statusTone\(detail\.status\)"/) assert.match(view, / { assert.match(view, /const inboundStatusOptions = \[/) assert.match(view, /key: 'status', label: '作业状态', type: 'select', options: inboundStatusOptions/) assert.match(view, /destinationWarehouseLabel\(row\.fbaWarehouseCode, row\.destinationWarehouseCode, row\.destinationWarehouseName\)/) assert.match(view, /destinationWarehouseLabel\(row\.destinationWarehouseCode, row\.destinationWarehouseName\)/) assert.doesNotMatch(view, /label="目的仓代码"|label="目的仓名称"/) assert.doesNotMatch(view, /destinationWarehouseLabel\([^)]*overseasWarehouse/) })