45 lines
4.4 KiB
TypeScript
45 lines
4.4 KiB
TypeScript
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: <T>(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)
|
|
})
|