import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import { describe, expect, it } from 'vitest' import { unifiedOrderStatusOptions } from '../api/unifiedOrders' const source = readFileSync(resolve(process.cwd(), 'src/modules/unified-orders/pages/UnifiedOrdersView.vue'), 'utf8') const routeSource = readFileSync(resolve(process.cwd(), 'src/modules/unified-orders/routes.ts'), 'utf8') describe('UnifiedOrdersView contract', () => { it('only exposes the seven product main statuses', () => { expect(unifiedOrderStatusOptions.map((item) => item.label)).toEqual([ '待审核', '待测量数据', '已入库', '待分柜', '装柜中', '装柜完成', '派送完成', ]) for (const legacyLabel of ['待客户确认', '差异处理中', '派送中', '进入分柜']) { expect(source).not.toContain(legacyLabel) } }) it('renders accessible current-status tabs with keyboard navigation', () => { expect(source).toContain('role="tablist"') expect(source).toContain('role="tab"') expect(source).toContain(':aria-selected="filters.mainStatus === tab.value"') expect(source).toContain("event.key === 'ArrowRight'") expect(source).toContain("event.key === 'ArrowLeft'") expect(source).toContain("event.key === 'Home'") expect(source).toContain("event.key === 'End'") }) it('provides labeled prototype-aligned advanced filters backed by real query fields', () => { for (const key of [ 'receivingWarehouseId', 'destinationWarehouseId', 'inboundCode', 'internalOrderStatus', 'expectedArrivalDate', 'feeReviewStatus', 'containerNo', 'cabinetNo', 'channelName', 'sailingDate', 'loaded', 'fullContainer', 'measurementReviewStatus', 'fbaCode', 'createdRange', ]) expect(source).toContain(`key: '${key}'`) for (const label of ['定位仓库', '交货仓', '费用审核状态', '是否已配载', '是否整柜', '测量数据审核状态', '商品 FBA 编码']) { expect(source).toContain(`label: '${label}'`) } expect(source).toContain('listAllPlatformWarehouses') expect(source).toContain("{ status: 'ACTIVE' }") expect(source).toContain("warehouse.warehouseType === 'DOMESTIC'") expect(source).toContain("loaded: optionalBoolean(filters.value.loaded)") expect(source).toContain("fullContainer: optionalBoolean(filters.value.fullContainer)") expect(source).toContain("{ value: 'UNRECORDED', label: '未录入' }") expect(source).not.toContain("{ value: 'DRAFT', label: '草稿' }") expect(source).not.toContain("{ value: 'CANCELLED', label: '已取消' }") expect(source).not.toContain("key: 'orderNo'") expect(source.match(/key: 'inboundCode', type: 'input'/g)).toHaveLength(1) expect(source).not.toContain("key: 'keyword'") const prototypeFieldOrder = [ 'receivingWarehouseId', 'destinationWarehouseId', 'inboundCode', 'internalOrderStatus', 'expectedArrivalDate', 'feeReviewStatus', 'tenantId', 'containerNo', 'cabinetNo', 'channelName', 'sailingDate', 'loaded', 'fullContainer', 'measurementReviewStatus', 'fbaCode', 'createdRange', ] const fieldPositions = prototypeFieldOrder.map((key) => source.indexOf(`key: '${key}'`)) expect(fieldPositions).toEqual([...fieldPositions].sort((left, right) => left - right)) expect(source).toContain('preference-key="unified-orders-query-v2"') }) it('covers real list states and keeps operation column first and left-fixed', () => { expect(source).toContain("{ key: 'actions', label: '操作', width: 180, fixed: 'left'") expect(source).toContain("{ key: 'selection', type: 'selection', width: 52, fixed: 'left'") expect(source).toContain('批量审核接口待接入') expect(source).toContain('@selection-change="handleSelectionChange"') expect(source).toContain('title="订单列表暂时无法加载"') expect(source).toContain('empty-text="暂无符合条件的订单"') expect(source).toContain(':loading="loading"') expect(source).toContain('v-model:page="page"') expect(source).toContain('v-model:page-size="pageSize"') expect(source).toContain('slotName: \'orderStatus\'') expect(source).toContain('slotName: \'measurementReviewStatus\'') expect(source).toContain("NOT_SUBMITTED: '未提交'") expect(source).toContain("{ key: 'customerRemark', prop: 'customerRemark', label: '备注'") expect(source).toContain("{ key: 'latestInternalNote', prop: 'latestInternalNote', label: '客服内部备注'") expect(source.match(/ { expect(source).toContain('nextActionBoundary') expect(source).toContain("can('platform:firstleg:inbound:view')") expect(source).toContain('openMeasurement') expect(source).not.toContain('待接入:智能分柜') expect(source).not.toContain('updateMainStatus') expect(source).not.toContain('人工进入分柜') expect(source).not.toContain('performPlatformUnifiedOrderAction') expect(source).not.toContain('/actions/') }) it('approves pending review orders without exposing an order carrier assignment', () => { expect(source).toContain("row.nextAction === 'APPROVE_ORDER'") expect(source).toContain("can('platform:order:approve')") expect(source).toContain('await approvePlatformUnifiedOrder(tenantId, orderId)') expect(source).toContain('title="审核订单"') expect(source).toContain('confirm-text="审核通过"') expect(source).not.toContain('assignPlatformUnifiedOrderCarrier') expect(source).not.toContain('listPlatformPartners') expect(source).not.toContain('指派承运商') expect(source).not.toContain('待平台指派') }) it('provides unified detail, history and internal note states', () => { expect(source).toContain('getPlatformUnifiedOrder') expect(source).toContain('aria-label="状态历史"') expect(source).toContain('aria-label="内部备注"') expect(source).toContain('订单详情暂时无法加载') expect(source).toContain('一、客户下单数据') expect(source).toContain('二、外箱规数据') expect(source).toContain('三、实际测量数据') expect(source).toContain('measurementCollapsed = reactive({ customer: false, outer: false, actual: false })') expect(source).toContain('function toggleMeasurementSection(section: keyof typeof measurementCollapsed)') expect(source).toContain(':aria-expanded="!measurementCollapsed.customer"') expect(source).toContain(':aria-expanded="!measurementCollapsed.outer"') expect(source).toContain(':aria-expanded="!measurementCollapsed.actual"') expect(source).toContain('class="measurement-section-summary"') expect(source).toContain('') expect(source).toContain("{ key: 'girthCm', label: '箱规周长(cm)' }") expect(source).toContain('runMoreAction($event, row as UnifiedOrderResource)') expect(source).toContain('aria-label="更多订单操作"') expect(source).toContain("can('platform:order:note')") expect(source).toContain('await loadOrders()') }) it('renders order detail as a routed full page instead of a drawer', () => { expect(source).toContain('