test(firstleg): cover simulated container booking links
This commit is contained in:
@@ -25,6 +25,7 @@ async function createConfirmedUnassignedBooking(context, suffix, master) {
|
||||
const createdResponse = await request(context, 'POST', BASE, { expectedVersion: 0, data: draft }, { 'Idempotency-Key': key })
|
||||
const created = data(createdResponse)
|
||||
const bookingId = id(created?.oceanBooking?.id)
|
||||
const createdBookingNo = id(created?.oceanBooking?.bookingNo)
|
||||
context.apiSuccess(MODULE, '创建未指定客户订舱', createdResponse,
|
||||
`marker=${context.marker}, customerFields=${'customerId' in draft || 'customerName' in draft ? 'present' : 'omitted'}`, OPTIONS)
|
||||
context.assert(MODULE, '未指定客户订舱不伪造客户快照', createdResponse,
|
||||
@@ -32,6 +33,12 @@ async function createConfirmedUnassignedBooking(context, suffix, master) {
|
||||
`bookingId=${bookingId || 'missing'}, customerId=${id(created?.oceanBooking?.customerId) || 'null'}, customerName=${created?.oceanBooking?.customerName || 'null'}`, OPTIONS)
|
||||
if (!bookingId) return null
|
||||
|
||||
const hiddenResponse = await request(context, 'GET', `${BASE}?page=1&size=20&keyword=${encodeURIComponent(createdBookingNo)}`)
|
||||
const hiddenPage = context.apiSuccess(MODULE, '未确认订舱不进入正式订舱列表', hiddenResponse, '', OPTIONS)
|
||||
context.assert(MODULE, 'DRAFT 未指定客户订舱仅可按详情维护', hiddenResponse,
|
||||
!hiddenPage?.records?.some?.((item) => id(item.id) === bookingId),
|
||||
`bookingId=${bookingId}, records=${hiddenPage?.records?.length ?? 'n/a'}`, OPTIONS)
|
||||
|
||||
const path = `${BASE}/${bookingId}`
|
||||
const submitResponse = await request(context, 'POST', `${path}/submit`, {
|
||||
expectedVersion: Number(created.oceanBooking.version), reason: context.marker,
|
||||
@@ -40,16 +47,15 @@ async function createConfirmedUnassignedBooking(context, suffix, master) {
|
||||
const confirmResponse = await request(context, 'POST', `${path}/confirm`, {
|
||||
expectedVersion: Number(submitted?.oceanBooking?.version), reason: context.marker,
|
||||
}, { 'Idempotency-Key': `${context.marker}-ocean-unassigned-confirm`.slice(0, 128) })
|
||||
context.apiSuccess(MODULE, '确认未指定客户订舱并生成柜次', confirmResponse, '', OPTIONS)
|
||||
context.apiSuccess(MODULE, '确认未指定客户真实订舱', confirmResponse, '', OPTIONS)
|
||||
|
||||
const detailResponse = await request(context, 'GET', path)
|
||||
const detail = context.apiSuccess(MODULE, '回查未指定客户订舱持久化结果', detailResponse, '', OPTIONS)
|
||||
const containerBookingId = id(detail?.containerAllocations?.[0]?.containerBookingId)
|
||||
const bookingNo = id(detail?.oceanBooking?.bookingNo || created?.oceanBooking?.bookingNo)
|
||||
context.assert(MODULE, '未指定客户订舱保持空客户并在 CONFIRMED 生成稳定柜次', detailResponse,
|
||||
context.assert(MODULE, '未指定客户订舱保持空客户且 CONFIRMED 不自动生成内部柜', detailResponse,
|
||||
detail?.oceanBooking?.status === 'CONFIRMED' && detail?.oceanBooking?.customerId == null
|
||||
&& detail?.oceanBooking?.customerName == null && Boolean(containerBookingId) && Boolean(bookingNo),
|
||||
`status=${detail?.oceanBooking?.status || 'missing'}, customerId=${id(detail?.oceanBooking?.customerId) || 'null'}, bookingNo=${bookingNo || 'missing'}, containerBookingId=${containerBookingId || 'missing'}`, OPTIONS)
|
||||
&& detail?.oceanBooking?.customerName == null && detail?.containerAllocations?.length === 0 && Boolean(bookingNo),
|
||||
`status=${detail?.oceanBooking?.status || 'missing'}, customerId=${id(detail?.oceanBooking?.customerId) || 'null'}, bookingNo=${bookingNo || 'missing'}, allocations=${detail?.containerAllocations?.length ?? 'n/a'}`, OPTIONS)
|
||||
|
||||
const listResponse = await request(context, 'GET', `${BASE}?page=1&size=20&keyword=${encodeURIComponent(bookingNo)}`)
|
||||
const page = context.apiSuccess(MODULE, '按真实订舱号查询未指定客户订舱', listResponse, `bookingNo=${bookingNo}`, OPTIONS)
|
||||
@@ -57,7 +63,7 @@ async function createConfirmedUnassignedBooking(context, suffix, master) {
|
||||
page?.records?.some?.((item) => id(item.id) === bookingId && item.customerId == null && item.customerName == null),
|
||||
`bookingId=${bookingId}, bookingNo=${bookingNo}, records=${page?.records?.length ?? 'n/a'}`, OPTIONS)
|
||||
const resource = { id: bookingId, marker: context.marker, customerId: null, customerName: null,
|
||||
bookingNo, channelCode: draft.channelCode, warehouseId: draft.warehouseId, containerBookingId,
|
||||
bookingNo, channelCode: draft.channelCode, warehouseId: draft.warehouseId, containerBookingId: null,
|
||||
finalStatus: detail?.oceanBooking?.status || null }
|
||||
context.createdResources.oceanBookingUnassignedCustomer = resource
|
||||
return resource
|
||||
@@ -119,8 +125,9 @@ export async function run(context) {
|
||||
}
|
||||
const page = context.apiSuccess(MODULE, '订舱列表分页查询', list, '', OPTIONS)
|
||||
context.assert(MODULE, '订舱列表分页结构正确', list, Array.isArray(page?.records) && Number.isFinite(Number(page?.total)), `records=${page?.records?.length ?? 'n/a'}`, OPTIONS)
|
||||
const statuses = ['DRAFT', 'SUBMITTED', 'CONFIRMED', 'RELEASED', 'FAILED', 'CANCELLED']
|
||||
const statuses = ['CONFIRMED', 'CHANGE_PENDING', 'RELEASED', 'CANCELLED']
|
||||
for (const status of statuses) { const r = await request(context, 'GET', `${BASE}?page=1&size=5&status=${status}`); const d = data(r); step(context, `订舱 ${status} 状态筛选`, r, r.http === 200 && codeOf(r) === '200' && Array.isArray(d?.records) && d.records.every((x) => x.status === status), `HTTP=${r.http}, code=${codeOf(r)}, records=${d?.records?.length ?? 'n/a'}`) }
|
||||
for (const status of ['DRAFT', 'SUBMITTED']) { const r = await request(context, 'GET', `${BASE}?page=1&size=5&status=${status}`); step(context, `正式订舱列表拒绝 ${status} 状态`, r, failure(r), `HTTP=${r.http}, code=${codeOf(r)}`) }
|
||||
|
||||
await createConfirmedUnassignedBooking(context, suffix, master)
|
||||
|
||||
@@ -154,7 +161,7 @@ export async function run(context) {
|
||||
const changed = await request(context, 'POST', `${path}/change-request`, { expectedVersion: version, vesselName: `改船-${suffix}`, voyageNo: `CV${suffix}`, reason: context.marker }, { 'Idempotency-Key': `${context.marker}-change` })
|
||||
context.apiSuccess(MODULE, '申请改船', changed, '', OPTIONS); version = Number(data(changed)?.oceanBooking?.version)
|
||||
const changeConfirmed = await action('确认改船', 'change-confirm', version, 'confirm change')
|
||||
let allocatedContainerBookingId = id(changeConfirmed?.containerAllocations?.[0]?.containerBookingId)
|
||||
const allocatedContainerBookingId = ''
|
||||
if (containerFlow?.finalStatus === 'COMPLETED' || containerFlow?.finalStatus === 'LOADED') {
|
||||
context.assert(MODULE, '订舱与本轮柜次客户归属一致', changed,
|
||||
id(containerFlow?.tenantId) === id(changeConfirmed?.oceanBooking?.customerId),
|
||||
@@ -163,9 +170,9 @@ export async function run(context) {
|
||||
context.assert(MODULE, '订舱存在匹配本轮柜型的箱型需求', changed,
|
||||
Boolean(requirement?.id), `requirementId=${id(requirement?.id) || 'missing'}`, OPTIONS)
|
||||
if (!requirement?.id || id(containerFlow?.tenantId) !== id(changeConfirmed?.oceanBooking?.customerId)) return
|
||||
context.assert(MODULE, '确认订舱自动生成并关联柜次', changed,
|
||||
Boolean(allocatedContainerBookingId) && Number.isInteger(version),
|
||||
`containerBookingId=${allocatedContainerBookingId || 'missing'}, version=${version}`, OPTIONS)
|
||||
context.assert(MODULE, '独立订舱生命周期不占用本轮已装货柜次', changed,
|
||||
changeConfirmed?.containerAllocations?.length === 0 && Number.isInteger(version),
|
||||
`allocations=${changeConfirmed?.containerAllocations?.length ?? 'n/a'}, version=${version}`, OPTIONS)
|
||||
}
|
||||
const released = await request(context, 'POST', `${path}/release`, {
|
||||
expectedVersion: version, billOfLadingNo: `BL-${suffix}`, vesselName: `放舱船-${suffix}`,
|
||||
@@ -177,9 +184,9 @@ export async function run(context) {
|
||||
version = Number(releasedDetail?.oceanBooking?.version)
|
||||
const final = await request(context, 'GET', path); const fd = data(final)
|
||||
context.apiSuccess(MODULE, '回查 RELEASED 订舱详情', final, '', OPTIONS)
|
||||
context.assert(MODULE, '订舱状态历史、审计操作者、柜次关联和终态完整', final,
|
||||
context.assert(MODULE, '独立订舱状态历史、审计操作者和终态完整', final,
|
||||
fd?.oceanBooking?.status === 'RELEASED' && fd.histories?.length >= 5 && fd.histories.every((h) => h.operatorName)
|
||||
&& fd?.containerAllocations?.some?.((item) => id(item?.containerBookingId) === allocatedContainerBookingId),
|
||||
&& fd?.containerAllocations?.length === 0,
|
||||
`status=${fd?.oceanBooking?.status || 'missing'}, histories=${fd?.histories?.length ?? 'n/a'}, allocations=${fd?.containerAllocations?.length ?? 'n/a'}`, OPTIONS)
|
||||
let downstreamBooking = {
|
||||
id: bookingId, customerId: id(fd?.oceanBooking?.customerId), marker: context.marker,
|
||||
|
||||
Reference in New Issue
Block a user