This commit is contained in:
2026-08-17 13:24:48 +08:00
parent ac6cf9c904
commit 6739c83467
43 changed files with 1049 additions and 315 deletions
@@ -31,28 +31,42 @@ test('simulation creation uses server-owned identity and formal master data', ()
assert.match(firstlegOpenApi, /服务端生成稳定 containerBookingId\/cabinetNo,不要求真实柜号或订舱/)
})
test('first link and unlink gates are intentionally asymmetric', () => {
test('link consumes one active real booking container through the frozen request', () => {
assert.match(controller, /@PostMapping\("\/\{id\}\/ocean-booking-link"\)/)
assert.match(controller, /@DeleteMapping\("\/\{id\}\/ocean-booking-link"\)/)
assert.match(containerDtos, /OceanBookingLinkRequest\(@NotNull @Positive Long realContainerBookingId,[\s\S]*expectedVersion/)
assert.match(containerService, /requireFirstLinkMutable\(container\)/)
assert.match(containerService, /WAIT_LOADING && value != SmartLoadingStatus\.EDITING/)
assert.match(containerService, /repository\.findForUpdate\(request\.realContainerBookingId\(\)\)/)
assert.match(containerService, /"OCEAN_BOOKING"\.equals\(source\.getSourceType\(\)\)/)
assert.match(containerService, /"ACTIVE"\.equals\(source\.getRecordStatus\(\)\)/)
assert.match(containerService, /"CONFIRMED"\.equals\(booking\.getStatus\(\)\)[\s\S]*"RELEASED"\.equals\(booking\.getStatus\(\)\)/)
assert.match(containerService, /hasPickTask[\s\S]*hasEvidence[\s\S]*hasDocuments/)
assert.match(containerService, /requireUnlinkMutable\(container\)/)
assert.match(containerService, /status\(container\) != SmartLoadingStatus\.WAIT_LOADING \|\| repository\.hasActiveLoadingItems/)
assert.match(firstlegOpenApi, /首次关联允许 WAIT_LOADING 或已有预排货的 EDITING 柜/)
assert.match(firstlegOpenApi, /解绑或换绑仅允许完全空的 WAIT_LOADING 模拟柜/)
assert.match(firstlegOpenApi, /realContainerBookingId/)
assert.match(firstlegOpenApi, /原真实柜置 MERGED 且不再出现在正常货柜列表/)
})
test('real booking association locks scope capacity and stable internal identity', () => {
test('real booking merge locks scope and changes all identities atomically', () => {
for (const field of ['warehouseId', 'channelCode', 'containerType', 'capacityCbm', 'maxWeightKg']) {
assert.match(containerService, new RegExp(`container\\.get${field[0].toUpperCase()}${field.slice(1)}\\(\\)`), field)
}
assert.match(containerService, /hasMismatchedCustomerItems/)
assert.match(containerService, /真实订舱柜箱型分配已关联/)
assert.match(containerService, /setOceanBookingId[\s\S]*setOceanBookingRequirementId/)
assert.match(containerService, /consumeRealSource\(source\.getId\(\), id/)
assert.match(containerService, /mergeRealSource\(id, source\.getId\(\), source\.getContainerNo\(\)/)
assert.match(containerService, /reassignAllocation\(source\.getId\(\), id\)/)
assert.doesNotMatch(containerService.match(/linkOceanBooking[\s\S]*?return required\(id\);/)?.[0] || '', /container\.setId\(|container\.setCabinetNo\(/)
})
test('booking creation atomically registers one real operational container per input row', () => {
assert.match(oceanOpenApi, /containers: \{type: array, minItems: 1, maxItems: 20/)
assert.match(oceanOpenApi, /required: \[containerNo, containerType, containerKind, capacityCbm, maxWeightKg\]/)
assert.match(oceanService, /request\.data\(\)\.containers\(\)\.forEach/)
assert.match(oceanService, /同一订舱内集装箱号不能重复/)
assert.match(oceanService, /createRealContainers\(value, requirements, request\.data\(\)\.containers\(\)/)
assert.match(oceanService, /setSourceType\("OCEAN_BOOKING"\)/)
assert.match(oceanService, /setRecordStatus\("ACTIVE"\)/)
assert.match(oceanService, /setQuantity\(1\)/)
})
test('HTTP fixture follows simulation arrange link PDA sequence without auto-container fallback', () => {
const ordered = [
'新增内部模拟柜',
@@ -64,9 +78,10 @@ test('HTTP fixture follows simulation arrange link PDA sequence without auto-con
assert.ok(ordered.every((value, index) => index === 0 || value > ordered[index - 1]), `invalid sequence: ${ordered.join(',')}`)
assert.match(loadingFixture, /ocean-booking-link/)
assert.match(loadingFixture, /关联前后内部柜次、计划和排货明细身份稳定/)
assert.match(loadingFixture, /同一真实订舱箱型容量拒绝重复关联/)
assert.match(loadingFixture, /已消费 MERGED 真实柜拒绝再次关联/)
assert.match(loadingFixture, /已有排货后拒绝解绑或换绑/)
assert.match(loadingFixture, /空模拟柜解绑后允许重新关联/)
assert.match(loadingFixture, /合并后列表仅保留模拟柜原地转成的一条 ACTIVE 操作身份/)
assert.match(loadingFixture, /订舱真实柜 allocation 已原子改指稳定模拟柜身份/)
assert.doesNotMatch(loadingFixture, /确认订舱并自动生成|确认响应包含自动生成/)
})