235 lines
12 KiB
JavaScript
235 lines
12 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import test from 'node:test'
|
|
|
|
const view = readFileSync(new URL('./WarehouseServiceView.vue', import.meta.url), 'utf8')
|
|
const api = readFileSync(new URL('../api/warehouseServices.ts', import.meta.url), 'utf8')
|
|
const warehouseApi = readFileSync(new URL('../../first-leg/api/firstLeg.ts', import.meta.url), 'utf8')
|
|
|
|
test('总文件可以独立清除并重选同名文件,提交时禁止清除', () => {
|
|
assert.match(view, /@click="clearCreateTotalFile\('CARTON_TOTAL'\)"/)
|
|
assert.match(view, /@click="clearCreateTotalFile\('SKU_TOTAL'\)"/)
|
|
const clear = view.slice(view.indexOf('function clearCreateTotalFile'), view.indexOf('function chooseCreateTotalFile'))
|
|
assert.match(clear, /if \(saving.value\) return/)
|
|
assert.match(clear, /file.value = null/)
|
|
assert.match(clear, /input.value.value = ''/)
|
|
assert.match(view, /aria-label="清除箱唛总文件" :disabled="saving"/)
|
|
assert.match(view, /aria-label="清除 SKU 总文件" :disabled="saving"/)
|
|
})
|
|
|
|
test('贴标文件按总文件和关联模板分组展示', () => {
|
|
assert.match(view, /warehouse-file-groups/)
|
|
assert.match(view, /<span>1<\/span>贴标总文件/)
|
|
assert.match(view, /必传 · 二选一/)
|
|
assert.match(view, /必传 · 两份文件/)
|
|
assert.match(view, /<span>2<\/span>明细关联模板/)
|
|
assert.match(view, /SKU 关联/)
|
|
assert.match(view, /箱号关联/)
|
|
assert.match(view, /SKU 混箱/)
|
|
assert.match(view, /warehouse-file-groups--single/)
|
|
})
|
|
|
|
test('贴标申请移除操作项下方的解释文字,保留必要状态', () => {
|
|
assert.doesNotMatch(view, /选择后仅查询当前客户在该中转仓的可用库存/)
|
|
assert.doesNotMatch(view, /托盘仅作为库内承载位置/)
|
|
assert.doesNotMatch(view, /整张贴标申请只能选择一个目的仓/)
|
|
assert.doesNotMatch(view, /SKU 与箱号关联通过仓库唛头合并/)
|
|
assert.match(view, /必传 · 二选一/)
|
|
assert.match(view, /必传 · 两份文件/)
|
|
})
|
|
|
|
test('贴标申请可从当前客户仍有库存的入仓单或退货单选择来源', () => {
|
|
assert.match(view, /海外操作仓(中转仓)/)
|
|
assert.match(view, /选择入仓单或退货单/)
|
|
assert.match(view, /quantityUnit: candidate\.returnCartonId \? '件' : '箱'/)
|
|
assert.match(view, /暂无匹配的可选库存/)
|
|
assert.match(view, /relabelInboundOptions/)
|
|
assert.match(view, /listRelabelInventoryCandidates\(form\.warehouse\)/)
|
|
assert.match(api, /relabel-applications\/inventory-candidates/)
|
|
assert.match(api, /params: \{ operationWarehouseId/)
|
|
})
|
|
|
|
test('客户贴标表单不展示客户单号、托盘和内部库存来源列', () => {
|
|
assert.doesNotMatch(view, /<i>\*<\/i>客户单号/)
|
|
assert.doesNotMatch(view, /<th>原入仓单<\/th>/)
|
|
assert.doesNotMatch(view, /<th>托盘<\/th>/)
|
|
assert.doesNotMatch(view, /<th>中转仓<\/th>/)
|
|
assert.doesNotMatch(view, /已选托盘组成/)
|
|
})
|
|
|
|
test('贴标申请使用统一明细模板下载和上传入口', () => {
|
|
assert.match(view, /downloadRelabelTemplate/)
|
|
assert.match(view, /<strong>统一贴标明细<\/strong>/)
|
|
assert.match(view, />下载模板<\/el-button>/)
|
|
assert.match(view, />上传文件<\/el-button>/)
|
|
assert.match(view, /unifiedTemplateInput\?\.click\(\)/)
|
|
assert.match(view, /importRelabelTemplate/)
|
|
assert.match(view, /明细行标识/)
|
|
assert.match(view, /'明细行标识', '贴标类型'/)
|
|
assert.doesNotMatch(view.slice(view.indexOf('function downloadRelabelTemplate'), view.indexOf('function parseCsvLine')), /FBA目的仓/)
|
|
assert.doesNotMatch(view, /const includeDestination = props\.service !== 'transfer'/)
|
|
assert.match(view, /<strong>绑定明细<\/strong>/)
|
|
assert.match(view, /<th>仓库唛头 \*<\/th>/)
|
|
assert.doesNotMatch(view, /库存位置ID/)
|
|
})
|
|
|
|
test('贴标货物明细支持手动添加和编辑', () => {
|
|
assert.match(view, /手动添加行/)
|
|
assert.match(view, /addRelabelCargoRow/)
|
|
assert.match(view, /所选入仓单没有更多可添加的库存箱/)
|
|
assert.match(view, /<el-input v-model="row\.sku" :readonly="props\.service === 'disposal'"/)
|
|
})
|
|
|
|
test('上传关系支持部分或全量选择后导入本次换标明细', () => {
|
|
assert.match(view, /interface ImportedRelabelBinding/)
|
|
assert.match(view, /待导入绑定关系/)
|
|
assert.match(view, /全选/)
|
|
assert.match(view, /导入到明细/)
|
|
assert.match(view, /importSelectedBindingsToDetails/)
|
|
assert.match(view, /item\.selected/)
|
|
assert.match(view, /cartonDetailRows/)
|
|
assert.match(view, /included: false/)
|
|
assert.match(view, /cargoRows\.value\[0\]\.included = true/)
|
|
})
|
|
|
|
test('箱唛换标一行固定代表一箱', () => {
|
|
const cartonTable = view.match(/<div v-if="labelingMode === 'carton'" class="warehouse-table-scroll">.+?(?=<div v-else class="warehouse-table-scroll">)/s)?.[0]
|
|
assert.ok(cartonTable)
|
|
assert.match(cartonTable, /<th>箱数<\/th>/)
|
|
assert.match(cartonTable, /<td><strong>1 箱<\/strong><\/td>/)
|
|
assert.doesNotMatch(cartonTable, /v-model="row\.quantity"/)
|
|
assert.doesNotMatch(view, /'本次箱数'/)
|
|
assert.match(view, /totalPackageCount: 1, notifiedPackageCount: 1/)
|
|
})
|
|
|
|
test('贴标货物明细通过单一换标类型选择三种模式', () => {
|
|
assert.match(view, /<el-radio-group v-model="labelingMode" aria-label="换标类型">/)
|
|
assert.match(view, /<el-radio-button value="carton">只换箱唛<\/el-radio-button>/)
|
|
assert.match(view, /<el-radio-button value="sku">只换 SKU 标签<\/el-radio-button>/)
|
|
assert.match(view, /<el-radio-button value="carton_and_sku">SKU 和箱唛都换<\/el-radio-button>/)
|
|
assert.doesNotMatch(view, /el-tab-pane label="(?:箱唛换标|SKU 换标)"/)
|
|
assert.match(view, /interface SkuRelabelRow/)
|
|
assert.match(view, /旧 SKU \*/)
|
|
assert.match(view, /仓库唛头 \*/)
|
|
assert.match(view, /换标数量(件)\*/)
|
|
assert.match(view, /旧SKU标签/)
|
|
assert.match(view, /新SKU标签/)
|
|
assert.match(view, /已读取 \$\{rows\.length\} 条绑定关系/)
|
|
assert.match(view, /applyExistingSkuBinding/)
|
|
assert.match(view, /applyExistingCartonBinding/)
|
|
assert.match(view, /buildSkuRelabelItems/)
|
|
assert.match(view, /CARTON_AND_SKU/)
|
|
assert.match(view, /changeCarton/)
|
|
assert.doesNotMatch(view, /SKU 换标提交待接口接入/)
|
|
})
|
|
|
|
test('箱唛相关换标必须选择四选一派送方式', () => {
|
|
assert.match(view, /label="卡车派送" value="TRUCK"/)
|
|
assert.match(view, /label="快递派送" value="EXPRESS"/)
|
|
assert.match(view, /label="亚马逊自提" value="AMAZON_PICKUP"/)
|
|
assert.match(view, /label="客户自提" value="CUSTOMER_PICKUP"/)
|
|
assert.match(api, /RelabelDeliveryMethod = 'TRUCK' \| 'EXPRESS' \| 'AMAZON_PICKUP' \| 'CUSTOMER_PICKUP'/)
|
|
assert.match(view, /labelingMode\.value !== 'sku' && !form\.deliveryMethod/)
|
|
})
|
|
|
|
test('一次申请单选库存来源且退货库存按退货单汇总', () => {
|
|
assert.doesNotMatch(view, /multiple filterable collapse-tags/)
|
|
assert.match(view, /returnSourceNos\(item\)\.includes\(selectedReturnOrderNo\.value\)/)
|
|
assert.match(view, /current\.availablePackages \+= inventoryQuantity\(candidate\.availablePackages\)/)
|
|
assert.match(view, /availablePackages: inventoryQuantity\(candidate\.availablePackages\)/)
|
|
assert.match(view, /const quantity = Number\(value\)/)
|
|
assert.match(view, /可用包裹<\/h3>/)
|
|
assert.match(view, /仓库箱识别码/)
|
|
assert.match(view, /箱内 SKU/)
|
|
assert.match(view, /returnLooseCandidates/)
|
|
assert.match(view, /returnBoxCandidates/)
|
|
assert.doesNotMatch(view, /submitReturnRelabel/)
|
|
assert.doesNotMatch(view, /candidate\.sourceType === 'RETURN_CARTON'\) rows\.push\(\.\.\.Array\.from/)
|
|
assert.match(view, /sourceInventoryBalanceId: String\(candidate\.inventoryBalanceId\)/)
|
|
assert.match(view, /sourceInventoryPositionId: String\(position\.positionId\)/)
|
|
assert.match(view, /sourceInboundOrderId: String\(candidate\.inboundOrderId\)/)
|
|
assert.match(api, /sourceInventoryBalanceId\?: string; sourceInventoryPositionId\?: string; sourceInboundOrderId\?: string; returnCartonId\?: string/)
|
|
})
|
|
|
|
test('退货贴标复用普通申请,混贴要求两份总文件', () => {
|
|
assert.match(view, /cartonTotalFile\.value && !requiresBothTotalFiles\.value\) clearCreateTotalFile\('SKU_TOTAL'\)/)
|
|
assert.match(view, /skuTotalFile\.value && !requiresBothTotalFiles\.value\) clearCreateTotalFile\('CARTON_TOTAL'\)/)
|
|
assert.match(view, /const created = await createRelabel/)
|
|
assert.doesNotMatch(view, /&& !isReturnRelabelSource.value && labelingMode.value === 'carton_and_sku'/)
|
|
})
|
|
|
|
test('SKU 和箱唛都换时两份总文件必须同时上传', () => {
|
|
assert.match(view, /labelingMode\.value === 'carton_and_sku'/)
|
|
assert.match(view, /requiresBothTotalFiles\.value && \(!cartonTotalFile\.value \|\| !skuTotalFile\.value\)/)
|
|
assert.match(view, /必须同时上传箱唛总文件和 SKU 总文件/)
|
|
assert.match(view, /requiresBothTotalFiles \? '和' : '或'/)
|
|
assert.match(view, /必传 · 两份文件/)
|
|
})
|
|
|
|
test('海外操作仓和FBA目的仓使用独立字段', () => {
|
|
assert.match(api, /operationWarehouseId: string/)
|
|
assert.match(api, /destinationFbaWarehouseCode\?: string/)
|
|
assert.match(view, /operationWarehouseId: form\.warehouse/)
|
|
assert.match(view, /destinationFbaWarehouseCode: form\.destination/)
|
|
assert.match(view, /FBA 目的仓<\/span><el-select v-model="form\.destination"/)
|
|
assert.doesNotMatch(view, /v-model="row\.destinationWarehouseId"[^\n]+请选择 FBA 目的仓/)
|
|
})
|
|
|
|
test('操作仓和FBA仓均从商户仓库目录按类型加载', () => {
|
|
assert.match(view, /loadAllWarehouseRecords\('FBA', getMerchantWarehouses\)/)
|
|
assert.match(view, /\['OVERSEAS', 'OVERSEAS_PARTNER'\]/)
|
|
assert.match(view, /v-for="warehouse in operationWarehouses"/)
|
|
assert.match(view, /v-for="warehouse in fbaWarehouses"/)
|
|
assert.doesNotMatch(view, /美西海外仓-ONT8/)
|
|
})
|
|
|
|
test('选择海外操作仓后自动带出仓库签收联系方式', () => {
|
|
assert.match(warehouseApi, /contactName: string \| null/)
|
|
assert.match(warehouseApi, /contactPhone: string \| null/)
|
|
assert.match(view, /form\.contact = warehouse\?\.contactName \|\| ''/)
|
|
assert.match(view, /form\.phone = warehouse\?\.contactPhone \|\| ''/)
|
|
assert.match(view, /海外仓签收联系人/)
|
|
assert.match(view, /海外仓联系电话/)
|
|
assert.doesNotMatch(view, /ElMessage\.warning\('该海外仓主数据未完整维护/)
|
|
assert.match(view, /form\.warehouse && !form\.contact[^\n]+warehouse-unmaintained[^\n]+未维护/)
|
|
assert.match(view, /form\.warehouse && !form\.phone[^\n]+warehouse-unmaintained[^\n]+未维护/)
|
|
})
|
|
|
|
test('贴标详情展示箱唛、SKU 子明细和独立FBA目的仓', () => {
|
|
assert.match(api, /export interface RelabelDetail/)
|
|
assert.match(view, /item\.cartonMark \|\| '—'/)
|
|
assert.match(view, /item\.fbaCartonMark \|\| '—'/)
|
|
assert.match(view, /item\.destinationFbaWarehouseCode/)
|
|
assert.match(view, /item\.operationType === 'CARTON_AND_SKU'/)
|
|
assert.match(view, /item\.skuItems\?\.length/)
|
|
})
|
|
|
|
test('客户可在换标列表或详情确认完工且照片使用二进制下载', () => {
|
|
assert.match(view, /item\.__status === 'CUSTOMER_CONFIRM_PENDING'/)
|
|
assert.match(view, /confirmRelabelFromList\(item\['0'\]\)/)
|
|
assert.match(view, /selectedRelabelDetail\?\.application\.status === 'CUSTOMER_CONFIRM_PENDING'/)
|
|
assert.match(view, /@click="confirmSelectedRelabel">确认换标完成/)
|
|
assert.match(api, /apiBlobRequest/)
|
|
})
|
|
|
|
test('客户详情进入页面后直接回显完工照片并支持大图预览', () => {
|
|
assert.match(view, /void loadCompletionPhotos\(\)/)
|
|
assert.match(view, /class="warehouse-photo-grid"/)
|
|
assert.match(view, /<el-image v-if="completionPhotoUrls\[fileId\]"/)
|
|
assert.match(view, /:preview-src-list="completionPhotoPreviewUrls"/)
|
|
assert.doesNotMatch(view, />照片 \{\{ index \+ 1 \}\}<\/el-button>/)
|
|
})
|
|
|
|
test('进入复核后客户订单回显换标完成状态', () => {
|
|
assert.match(view, /CUSTOMER_CONFIRM_PENDING: '待客户确认'/)
|
|
assert.match(view, /READY_FOR_OUTBOUND: '换标完成'/)
|
|
})
|
|
|
|
test('审核驳回后展示原因并允许替换资料后重新提交', () => {
|
|
assert.match(api, /export function resubmitRelabel\(/)
|
|
assert.match(view, /<ReviewRejectionNotice/)
|
|
assert.match(view, /application\.reviewRemark/)
|
|
assert.match(view, /修改后重新提交/)
|
|
assert.match(view, /await resubmitRelabel\(/)
|
|
})
|