Files
admin-web/src/modules/fba-pricing/carrier-rates/pages/CarrierRatesView.test.ts
T

127 lines
6.5 KiB
TypeScript
Raw Normal View History

2026-08-04 21:01:39 +08:00
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
const source = readFileSync(join(process.cwd(), 'src/modules/fba-pricing/carrier-rates/pages/CarrierRatesView.vue'), 'utf8')
const queryToolbarSource = readFileSync(join(process.cwd(), 'src/shared/components/QueryToolbar.vue'), 'utf8')
2026-08-07 14:47:11 +08:00
describe('CarrierRatesView price-book source contract', () => {
it('keeps the operation column first and presents version-level history', () => {
expect(source.indexOf("key: 'actions'")).toBeLessThan(source.indexOf("key: 'version'"))
for (const label of ['价格表版本', '原始文件', '解析结果', '校验结果', '上传时间', '实际生效区间']) {
2026-08-04 21:01:39 +08:00
expect(source).toContain(label)
}
2026-08-07 14:47:11 +08:00
expect(source).toContain('formatEffectivePeriod')
expect(source).toContain('PENDING_CONFIRMATION')
expect(source).toContain('SUPERSEDED')
2026-08-12 10:59:49 +08:00
expect(source).not.toContain('<span>ID {{ (row as PlatformPriceBookVersion).id }}</span>')
2026-08-12 12:19:02 +08:00
expect(source).toContain("key: 'originalFileName', prop: 'originalFileName', label: '原始文件', minWidth: 250, showOverflowTooltip: true, defaultVisible: false")
2026-08-04 21:01:39 +08:00
})
2026-08-07 14:47:11 +08:00
it('uses only the parsed price-book workflow instead of legacy carrier-rate editing', () => {
for (const capability of [
'listPlatformPriceBooks',
'getPlatformPriceBook',
'uploadPlatformPriceBook',
'publishPlatformPriceBook',
'downloadPlatformPriceBookSource',
]) expect(source).toContain(capability)
for (const legacyCapability of [
'createPlatformCarrierRateVersion',
'listPlatformCarrierRates',
'retirePlatformCarrierRate',
'新增价格版本',
'编辑价格',
'有效期',
'生效日期',
]) expect(source).not.toContain(legacyCapability)
2026-08-04 21:01:39 +08:00
})
2026-08-07 14:47:11 +08:00
it('keeps uploaded prices immutable and makes confirmation the only edit action', () => {
expect(source).toContain('上传并解析')
expect(source).toContain('查看并确认')
expect(source).toContain('确认并立即生效')
expect(source).toContain('价格行不可在页面内修改')
expect(source).toContain('confirmPriceBook')
expect(source).toContain('publishPlatformPriceBook')
expect(source).not.toContain('草稿')
2026-08-04 21:01:39 +08:00
})
2026-08-07 14:47:11 +08:00
it('maps only active platform public domestic and overseas warehouses before confirmation', () => {
expect(source).toContain('listAllPlatformWarehouses()')
expect(source).toContain("warehouse.warehouseType === 'DOMESTIC'")
expect(source).toContain("warehouse.warehouseType === 'OVERSEAS'")
expect(source).toContain('起运仓映射')
expect(source).toContain('海外仓映射')
expect(source).toContain('originWarehouseCode')
expect(source).toContain('sourceDestinationName')
2026-08-07 17:36:05 +08:00
expect(source).toContain('autoSelectExactWarehouseMappings')
expect(source).toContain("'DUPLICATE_RATE'")
2026-08-07 17:46:27 +08:00
expect(source).toContain('.channel-tabs { width: 100%; min-width: 0;')
expect(source).toContain('.channel-preview :deep(.el-table) { width: 100%; max-width: 100%; min-width: 0; }')
2026-08-07 14:47:11 +08:00
expect(source).not.toContain('tenantId')
expect(source).not.toContain('客户选择')
2026-08-04 21:01:39 +08:00
})
2026-08-07 14:47:11 +08:00
it('shows parsing blockers and a channel-tabbed, read-only preview', () => {
expect(source).toContain('nonMappingBlockingIssues')
expect(source).toContain('解析与校验')
expect(source).toContain('按渠道预览')
expect(source).toContain('<el-tabs v-model="selectedChannelCode"')
expect(source).toContain('sourceLocation')
expect(source).toContain('pricingTaxModeLabel')
2026-08-04 21:01:39 +08:00
})
2026-08-07 14:47:11 +08:00
it('accepts only xlsx uploads and retains original-file download', () => {
expect(source).toContain('accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"')
expect(source).toContain("endsWith('.xlsx')")
expect(source).toContain('10 * 1024 * 1024')
expect(source).toContain('downloadSource')
expect(source).toContain('saveBlob')
2026-08-06 15:32:02 +08:00
})
2026-08-07 14:47:11 +08:00
it('uses the shared query and table primitives with mobile layout handling', () => {
expect(source).toContain("import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'")
expect(source).toContain("import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'")
2026-08-04 21:01:39 +08:00
expect(source).toContain('LoadErrorState')
2026-08-07 14:47:11 +08:00
expect(queryToolbarSource).toContain('flex-wrap: wrap')
2026-08-04 21:01:39 +08:00
expect(source).toContain('@media (max-width: 720px)')
2026-08-12 18:00:26 +08:00
expect(source).toContain('.table-actions :deep(.el-button) { min-height: 40px; }')
expect(source).toContain('@media (max-width: 420px)')
expect(source).toContain('.detail-grid { grid-template-columns: 1fr; }')
})
it('uses bordered striped tables and explicit semantic business buttons', () => {
expect(source).toContain('row-key="id"\n border\n stripe')
expect(source).toContain('<el-button size="small" plain type="primary" @click="openDetail')
expect(source).toContain('size="small"\n plain\n :loading="downloadingIds.has')
expect(source).toContain('<Eye :size="15" />{{ detailActionLabel')
expect(source).toContain('<Download :size="15" />原文件')
expect(source).toContain('<CircleCheck :size="16" />确认并立即生效')
expect(source).toContain('.price-book-footer :deep(.el-button) { min-height: 44px; }')
expect(source).not.toContain('<el-button link type="primary" @click="openDetail')
2026-08-04 21:01:39 +08:00
})
2026-08-10 16:24:54 +08:00
it('keeps upload actions in the table toolbar instead of the query toolbar', () => {
const queryToolbarEnd = source.indexOf('/>', source.indexOf('<QueryToolbar'))
const queryToolbarBlock = source.slice(source.indexOf('<QueryToolbar'), queryToolbarEnd + 2)
expect(queryToolbarBlock).not.toContain('#actions')
expect(source).toContain('<template #toolbar-actions><el-button v-if="canEdit" type="primary" @click="openUpload">')
expect(source).not.toContain('#toolbar-start')
expect(source).toContain('<template #pagination-left>共 {{ rows.length }} 个版本')
})
it('keeps list spacing and error state mutually exclusive', () => {
expect(source).toContain('<template v-if="loadError" #state>')
expect(source).toContain('<section v-if="!loadError" class="surface-panel table-panel"')
expect(source).not.toContain('<template #state>')
})
it('keeps both row actions directly visible without a premature more menu', () => {
expect(source).toContain('<Eye :size="15" />{{ detailActionLabel')
expect(source).toContain('<Download :size="15" />原文件')
expect(source).not.toContain('MoreHorizontal')
})
2026-08-04 21:01:39 +08:00
})