diff --git a/src/shared/components/InboundCodeRelationshipDrawer.test.ts b/src/shared/components/InboundCodeRelationshipDrawer.test.ts index 949a3117..9926df7b 100644 --- a/src/shared/components/InboundCodeRelationshipDrawer.test.ts +++ b/src/shared/components/InboundCodeRelationshipDrawer.test.ts @@ -1,10 +1,114 @@ import { readFileSync } from 'node:fs' import { resolve } from 'node:path' -import { describe, expect, it } from 'vitest' +import { defineComponent } from 'vue' +import { flushPromises, mount } from '@vue/test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { + getLoadingAssociationSummary, + getOverseasInboundCodeRelationship, + getPlatformInboundCodeAssociation, +} from '@/shared/api/inboundCodeRelations' +import InboundCodeRelationshipDrawer from './InboundCodeRelationshipDrawer.vue' + +vi.mock('@/shared/api/inboundCodeRelations', () => ({ + getLoadingAssociationSummary: vi.fn(), + getOverseasInboundCodeRelationship: vi.fn(), + getPlatformInboundCodeAssociation: vi.fn(), +})) const source = readFileSync(resolve(process.cwd(), 'src/shared/components/InboundCodeRelationshipDrawer.vue'), 'utf8') +const AppDrawerStub = defineComponent({ + props: { modelValue: Boolean, title: String, loading: Boolean }, + emits: ['update:modelValue'], + template: '', +}) + +function mountDrawer() { + return mount(InboundCodeRelationshipDrawer, { + props: { + modelValue: true, + inboundCode: 'NYEXX2608300027', + canReadBase: true, + canReadLoading: true, + canReadOverseas: true, + }, + global: { + stubs: { + AppDrawer: AppDrawerStub, + ApiErrorMeta: true, + LoadErrorState: true, + StatusBadge: true, + 'el-alert': true, + 'el-empty': { props: ['description'], template: '

{{ description }}

' }, + 'el-table': { props: ['data'], template: '
{{ data[0]?.skuCode }}
' }, + 'el-table-column': true, + }, + }, + }) +} describe('InboundCodeRelationshipDrawer contract', () => { + beforeEach(() => { + vi.clearAllMocks() + vi.mocked(getPlatformInboundCodeAssociation).mockResolvedValue({ + inboundCode: 'NYEXX2608300027', orderNo: 'FL2093975748931063810', orderStatus: 'APPROVED', + orderId: '90071992547409931', customerId: '90071992547409932', customerName: '纽约客户', + destinationType: 'FBA', destinationWarehouseId: '90071992547409933', destinationWarehouseCode: 'ABE3', destinationWarehouseName: '亚马逊 ABE3 仓', + }) + vi.mocked(getLoadingAssociationSummary).mockResolvedValue({ + inboundId: '90071992547409934', inboundCode: 'NYEXX2608300027', orderNo: 'FL2093975748931063810', + loadingPlanId: '90071992547409935', loadingPlanNo: 'LP-260830-0016', containerBookingId: '90071992547409936', + cabinetNo: 'CAB-260830-0016', containerNo: null, loadingStatus: 'LOADING', taskId: '90071992547409937', + pdaTaskStatus: 'IN_PROGRESS', coLoadGroupId: null, coLoadGroupNo: null, items: [{ itemId: '90071992547409938' }], + }) + vi.mocked(getOverseasInboundCodeRelationship).mockResolvedValue({ + inboundCode: 'NYEXX2608300027', found: true, + customer: { customerId: '90071992547409932', customerName: '纽约客户' }, + overseasWarehouse: { warehouseId: '90071992547409939', warehouseCode: 'LAX', warehouseName: '洛杉矶海外仓' }, + overseasReceivingStatus: 'RECEIVING', taillegOrders: [{ orderNo: 'LL-260830-0001', orderStatus: 'PENDING' }], + inboundPlans: [{ planNo: 'IP-260830-0001', planStatus: 'READY', receivingStatus: 'WAITING' }], + palletCodes: ['PLT-LAX-001'], inventory: [{ skuCode: 'SKU-001', productNameZh: '测试商品', packageCount: 12 }], + }) + }) + + it('loads all three sections on an initially open mount and reloads after closing and reopening', async () => { + const wrapper = mountDrawer() + await flushPromises() + + expect(getPlatformInboundCodeAssociation).toHaveBeenCalledWith('NYEXX2608300027') + expect(getLoadingAssociationSummary).toHaveBeenCalledWith('NYEXX2608300027') + expect(getOverseasInboundCodeRelationship).toHaveBeenCalledWith('NYEXX2608300027') + expect(wrapper.text()).toContain('FL2093975748931063810') + expect(wrapper.text()).toContain('LP-260830-0016') + expect(wrapper.text()).toContain('CAB-260830-0016') + expect(wrapper.text()).toContain('纽约客户') + expect(wrapper.text()).toContain('洛杉矶海外仓') + expect(wrapper.text()).toContain('LL-260830-0001') + expect(wrapper.text()).toContain('IP-260830-0001') + expect(wrapper.text()).toContain('PLT-LAX-001') + expect(wrapper.text()).toContain('SKU-001') + expect(wrapper.text()).not.toMatch(/9007199254740993[1-9]/) + + await wrapper.setProps({ modelValue: false }) + await wrapper.setProps({ modelValue: true }) + await flushPromises() + expect(getPlatformInboundCodeAssociation).toHaveBeenCalledTimes(2) + expect(getLoadingAssociationSummary).toHaveBeenCalledTimes(2) + expect(getOverseasInboundCodeRelationship).toHaveBeenCalledTimes(2) + }) + + it('keeps a server-declared overseas miss as a local empty state', async () => { + vi.mocked(getOverseasInboundCodeRelationship).mockResolvedValueOnce({ + inboundCode: 'NYEXX2608300027', found: false, customer: null, overseasWarehouse: null, + overseasReceivingStatus: null, taillegOrders: [], inboundPlans: [], palletCodes: [], inventory: [], + }) + const wrapper = mountDrawer() + await flushPromises() + expect(wrapper.text()).toContain('服务端未找到该入仓码的海外关联数据') + expect(wrapper.text()).toContain('FL2093975748931063810') + expect(wrapper.text()).toContain('LP-260830-0016') + }) + it('loads only permission-authorized server read models and keeps failures isolated', () => { expect(source).toContain('props.canReadBase') expect(source).toContain('props.canReadLoading') @@ -13,6 +117,7 @@ describe('InboundCodeRelationshipDrawer contract', () => { expect(source).toContain('getLoadingAssociationSummary(code)') expect(source).toContain('getOverseasInboundCodeRelationship(code)') expect(source).toContain('await Promise.all(tasks)') + expect(source).toContain('{ immediate: true }') expect(source).toContain(' [props.modelValue, props.inboundCode, props.canReadBase, props.canReadLoading, props.canReadOverseas] as const, ([open]) => { if (open) void load() else serial += 1 -}) +}, { immediate: true })