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-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')
|
|
|
|
|
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)')
|
|
|
|
|
})
|
|
|
|
|
})
|