test(firstleg): seed booking file before loading release
This commit is contained in:
@@ -52,6 +52,25 @@ test('default fixture publishes a second marker-owned inbound for the same-plan
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('HTTP chain refreshes after stale inventory and keeps one stable PDA identity', () => {
|
test('HTTP chain refreshes after stale inventory and keeps one stable PDA identity', () => {
|
||||||
|
ordered(loading, [
|
||||||
|
'创建三期 DRAFT 订舱(不生成真实柜)',
|
||||||
|
'三期 DRAFT 订舱返回稳定身份和初始版本',
|
||||||
|
'三期订舱上传当前有效订舱确认文件',
|
||||||
|
'订舱文件归属当前订舱且上传递增版本',
|
||||||
|
'订舱文件同键同载荷重放',
|
||||||
|
'订舱文件精确重放不新增文件或版本',
|
||||||
|
'回查订舱文件有效归属',
|
||||||
|
'同键重放后当前订舱仅保留一条目标有效文件',
|
||||||
|
'三期订舱 RELEASED 冻结运输快照',
|
||||||
|
])
|
||||||
|
assert.match(loading, /documentType', 'BOOKING_CONFIRMATION'/)
|
||||||
|
assert.match(loading, /id\(bookingDocument\?\.document\?\.oceanBookingId\) === bookingId/)
|
||||||
|
assert.match(loading, /releaseVersion > draftVersion/)
|
||||||
|
assert.match(loading, /'Idempotency-Key': bookingDocumentKey/)
|
||||||
|
assert.equal((loading.match(/'Idempotency-Key': bookingDocumentKey/g) || []).length, 2)
|
||||||
|
assert.match(loading, /Number\(bookingDocumentReplay\?\.bookingVersion\) === releaseVersion/)
|
||||||
|
assert.match(loading, /expectedVersion: releaseVersion, reason: context\.marker/)
|
||||||
|
assert.doesNotMatch(loading, /expectedVersion: draftVersion, reason: context\.marker/)
|
||||||
ordered(loading, [
|
ordered(loading, [
|
||||||
'PDA 原子批次完成拣货并等待人工确认',
|
'PDA 原子批次完成拣货并等待人工确认',
|
||||||
'五类装柜证据完整且铅封号持久化',
|
'五类装柜证据完整且铅封号持久化',
|
||||||
|
|||||||
@@ -440,8 +440,52 @@ export async function run(context) {
|
|||||||
const bookingDraftResponse = context.apiSuccess(MODULE, '创建三期 DRAFT 订舱(不生成真实柜)', bookingCreateResponse, '', OPTIONS)
|
const bookingDraftResponse = context.apiSuccess(MODULE, '创建三期 DRAFT 订舱(不生成真实柜)', bookingCreateResponse, '', OPTIONS)
|
||||||
const bookingId = id(bookingDraftResponse?.oceanBooking?.id)
|
const bookingId = id(bookingDraftResponse?.oceanBooking?.id)
|
||||||
const draftVersion = Number(bookingDraftResponse?.oceanBooking?.version)
|
const draftVersion = Number(bookingDraftResponse?.oceanBooking?.version)
|
||||||
|
context.assert(MODULE, '三期 DRAFT 订舱返回稳定身份和初始版本', bookingCreateResponse,
|
||||||
|
Boolean(bookingId) && bookingDraftResponse?.oceanBooking?.status === 'DRAFT'
|
||||||
|
&& Number.isInteger(draftVersion) && draftVersion >= 0,
|
||||||
|
`bookingId=${bookingId || 'missing'}, status=${bookingDraftResponse?.oceanBooking?.status || 'missing'}, version=${bookingDraftResponse?.oceanBooking?.version ?? 'missing'}`, OPTIONS)
|
||||||
|
if (!bookingId || !Number.isInteger(draftVersion) || draftVersion < 0) return
|
||||||
|
const bookingDocumentKey = `${context.marker}-p3-booking-document`.slice(0, 128)
|
||||||
|
const bookingDocumentForm = () => {
|
||||||
|
const form = new FormData()
|
||||||
|
form.append('expectedVersion', String(draftVersion))
|
||||||
|
form.append('documentType', 'BOOKING_CONFIRMATION')
|
||||||
|
form.append('file', new Blob([`${context.marker}-BOOKING_CONFIRMATION`], { type: 'text/plain' }),
|
||||||
|
`booking-confirmation-${context.marker}.txt`)
|
||||||
|
return form
|
||||||
|
}
|
||||||
|
const bookingDocumentResponse = await context.requestMultipart('POST',
|
||||||
|
`/api/platform/v1/ocean-bookings/${bookingId}/documents/upload`, bookingDocumentForm(), context.token,
|
||||||
|
{ 'Idempotency-Key': bookingDocumentKey })
|
||||||
|
const bookingDocument = context.apiSuccess(MODULE, '三期订舱上传当前有效订舱确认文件', bookingDocumentResponse, '', OPTIONS)
|
||||||
|
const releaseVersion = Number(bookingDocument?.bookingVersion)
|
||||||
|
context.assert(MODULE, '订舱文件归属当前订舱且上传递增版本', bookingDocumentResponse,
|
||||||
|
Boolean(bookingDocument?.document?.id) && id(bookingDocument?.document?.oceanBookingId) === bookingId
|
||||||
|
&& bookingDocument?.document?.documentType === 'BOOKING_CONFIRMATION'
|
||||||
|
&& bookingDocument?.document?.valid === true && Number.isInteger(releaseVersion)
|
||||||
|
&& releaseVersion > draftVersion,
|
||||||
|
`documentId=${id(bookingDocument?.document?.id) || 'missing'}, oceanBookingId=${id(bookingDocument?.document?.oceanBookingId) || 'missing'}, draftVersion=${draftVersion}, bookingVersion=${bookingDocument?.bookingVersion ?? 'missing'}`, OPTIONS)
|
||||||
|
if (!bookingId || !Number.isInteger(releaseVersion) || releaseVersion <= draftVersion) return
|
||||||
|
|
||||||
|
const bookingDocumentReplayResponse = await context.requestMultipart('POST',
|
||||||
|
`/api/platform/v1/ocean-bookings/${bookingId}/documents/upload`, bookingDocumentForm(), context.token,
|
||||||
|
{ 'Idempotency-Key': bookingDocumentKey })
|
||||||
|
const bookingDocumentReplay = context.apiSuccess(MODULE, '订舱文件同键同载荷重放', bookingDocumentReplayResponse, '', OPTIONS)
|
||||||
|
context.assert(MODULE, '订舱文件精确重放不新增文件或版本', bookingDocumentReplayResponse,
|
||||||
|
id(bookingDocumentReplay?.document?.id) === id(bookingDocument?.document?.id)
|
||||||
|
&& id(bookingDocumentReplay?.document?.oceanBookingId) === bookingId
|
||||||
|
&& Number(bookingDocumentReplay?.bookingVersion) === releaseVersion,
|
||||||
|
`firstDocumentId=${id(bookingDocument?.document?.id) || 'missing'}, replayDocumentId=${id(bookingDocumentReplay?.document?.id) || 'missing'}, firstVersion=${releaseVersion}, replayVersion=${bookingDocumentReplay?.bookingVersion ?? 'missing'}`, OPTIONS)
|
||||||
|
|
||||||
|
const bookingAfterDocumentResponse = await context.request('GET', `/api/platform/v1/ocean-bookings/${bookingId}`)
|
||||||
|
const bookingAfterDocument = context.apiSuccess(MODULE, '回查订舱文件有效归属', bookingAfterDocumentResponse, '', OPTIONS)
|
||||||
|
const activeBookingDocuments = (bookingAfterDocument?.documents || []).filter((document) => document?.valid === true)
|
||||||
|
context.assert(MODULE, '同键重放后当前订舱仅保留一条目标有效文件', bookingAfterDocumentResponse,
|
||||||
|
activeBookingDocuments.filter((document) => id(document?.id) === id(bookingDocument?.document?.id)
|
||||||
|
&& id(document?.oceanBookingId) === bookingId && document?.documentType === 'BOOKING_CONFIRMATION').length === 1,
|
||||||
|
`activeDocuments=${activeBookingDocuments.length}, targetDocumentId=${id(bookingDocument?.document?.id) || 'missing'}`, OPTIONS)
|
||||||
const releaseResponse = await request(context, 'POST', `/api/platform/v1/ocean-bookings/${bookingId}/release`,
|
const releaseResponse = await request(context, 'POST', `/api/platform/v1/ocean-bookings/${bookingId}/release`,
|
||||||
{ expectedVersion: draftVersion, reason: context.marker },
|
{ expectedVersion: releaseVersion, reason: context.marker },
|
||||||
{ 'Idempotency-Key': `${context.marker}-p3-booking-release`.slice(0, 128) })
|
{ 'Idempotency-Key': `${context.marker}-p3-booking-release`.slice(0, 128) })
|
||||||
const bookingConfirmed = context.apiSuccess(MODULE, '三期订舱 RELEASED 冻结运输快照', releaseResponse, '', OPTIONS)
|
const bookingConfirmed = context.apiSuccess(MODULE, '三期订舱 RELEASED 冻结运输快照', releaseResponse, '', OPTIONS)
|
||||||
const transportFields = ['billOfLadingNo', 'vesselName', 'voyageNo', 'estimatedSailingAt', 'estimatedArrivalAt']
|
const transportFields = ['billOfLadingNo', 'vesselName', 'voyageNo', 'estimatedSailingAt', 'estimatedArrivalAt']
|
||||||
|
|||||||
Reference in New Issue
Block a user