import { beforeEach, expect, it, vi } from 'vitest' import { http } from '@/shared/api/http' import { refreshReceivingCargo, getReceivingExecutionScope, saveReceivingPlan, getReceivingContext, getReceivingGroup, proposeReceivingChange, resolveReceivingChange, bookReceiving, changeReceivingGroup } from './receivingApi' vi.mock('@/shared/api/http', () => ({ http: { get: vi.fn(), post: vi.fn() }, unwrapApiResponse: (value: { data: T }) => value.data })) beforeEach(() => { vi.clearAllMocks(); vi.mocked(http.get).mockResolvedValue({ data: {} }); vi.mocked(http.post).mockResolvedValue({ data: {} }) }) it('uses the producer receiving paths and encodes opaque stable identities', async () => { await getReceivingContext('FBA_APPOINTMENT:1'); await getReceivingGroup('GROUP/1') expect(http.get).toHaveBeenNthCalledWith(1, '/platform/v1/last-leg/appointment-receiving/batches/FBA_APPOINTMENT%3A1') expect(http.get).toHaveBeenNthCalledWith(2, '/platform/v1/last-leg/appointment-receiving/agreements/GROUP%2F1') const propose = { idempotencyKey: 'unchanged-key', intent: { batchKey: 'FBA_APPOINTMENT:1', batchVersion: 3, customerId: 'customer-a', quantities: [{ sourceKey: 'ORDER:1', destinationKey: 'FBA:ONT8', retainedPackages: 0, expectedSourceVersion: 'v1', expectedVerificationVersion: 1 }], laterDate: null, ownerId: 'account-owner', nextFollowupDate: null, reason: '全部后送', transportVersion: 'scope-v1' } } await proposeReceivingChange(propose) expect(http.post).toHaveBeenLastCalledWith('/platform/v1/last-leg/appointment-receiving/changes', propose) const resolve = { idempotencyKey: 'resolve-key', version: 0, decision: 'CONFIRM' as const, warehouseEvidence: '明确回复', transportVersion: 'scope-v2' } await resolveReceivingChange('CH/1', resolve) expect(http.post).toHaveBeenLastCalledWith('/platform/v1/last-leg/appointment-receiving/changes/CH%2F1/resolve', resolve) const book = { idempotencyKey: 'book-key', bookings: [], cancelledAgreementKey: 'GROUP/1', cancelledAgreementVersion: 2, executionVersion: 'scope-v2' } await bookReceiving(book) expect(http.post).toHaveBeenLastCalledWith('/platform/v1/last-leg/appointment-receiving/bookings', book) const cancel = { idempotencyKey: 'cancel-key', version: 3, action: 'CANCEL' as const, details: null, warehouseEvidence: '取消依据', transportVersion: 'scope-v3' } await changeReceivingGroup('GROUP/1', cancel) expect(http.post).toHaveBeenLastCalledWith('/platform/v1/last-leg/appointment-receiving/agreements/GROUP%2F1/cancel', cancel) await changeReceivingGroup('GROUP/1', { ...cancel, action: 'RESCHEDULE' }) expect(http.post).toHaveBeenLastCalledWith('/platform/v1/last-leg/appointment-receiving/agreements/GROUP%2F1/reschedule', expect.objectContaining({ action: 'RESCHEDULE' })) }) it('posts a customer-scoped ordinary plan with execution version and no formal confirmation', async () => { const request = { idempotencyKey: 'plan-1', member: { batchKey: 'FBA_APPOINTMENT:1', batchVersion: 4, customerId: 'customer-b' }, executionVersion: 'exec-2', details: { plannedDate: null, plannedAt: null, plannedEndAt: null, appointmentStatus: 'FAILED' as const, appointmentRemark: '没有时段', confirmationNo: null, appointmentAt: null, appointmentEndAt: null, startOffset: null, endOffset: null } } await saveReceivingPlan(request) expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/appointment-receiving/plans', request) }) it('reads execution eligibility for the explicitly selected members without including guessed versions', async () => { const members = [{ batchKey: 'FBA_APPOINTMENT:2', customerId: 'customer-b' }] const scope = { version: 'only-B', members: [] } vi.mocked(http.post).mockResolvedValueOnce({ data: scope }) expect(await getReceivingExecutionScope(members)).toEqual(scope) expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/appointment-receiving/execution-scope', { members }) }) it('adopts latest customer cargo versions without including quantity mutations or confirmation fields', async () => { const request = { idempotencyKey: 'adopt-b', member: { batchKey: 'FBA_APPOINTMENT:1', batchVersion: 4, customerId: 'customer-b' }, executionVersion: 'exec-current', sources: [{ sourceKey: 'BOOKING:2', destinationKey: 'FBA:ONT8', expectedSourceVersion: 'latest', expectedVerificationVersion: 2 }] } await refreshReceivingCargo(request) expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/appointment-receiving/cargo-refresh', request) })