import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { containerWorkbenchGaps } from './phase3-container-loading.mjs' const read = (name) => readFileSync(new URL(name, import.meta.url), 'utf8') test('workbench DTO rejects the old flat entity and incomplete action/state projections', () => { const container = { id: '71', cabinetNo: 'CB-20260909-01', version: 0 } const row = { container, workbenchStage: 'WAIT_LOADING', statusSummary: {}, allowedActions: [] } assert.deepEqual(containerWorkbenchGaps(row), []) assert.ok(containerWorkbenchGaps(container).includes('container.id')) for (const field of ['container', 'workbenchStage', 'statusSummary', 'allowedActions']) { const invalid = { ...row } delete invalid[field] assert.ok(containerWorkbenchGaps(invalid).length > 0, `missing ${field} must fail`) } assert.ok(containerWorkbenchGaps({ ...row, container: { ...container, version: null } }).includes('container.version')) }) test('Admin read routes match controller workbench endpoints and default HTTP regression exercises the page DTO', () => { const controller = read('../../firstleg/src/main/java/com/baiyue/firstleg/controller/PlatformContainerController.java') const admin = read('../../../apps/admin-web/src/modules/container-loading/api/platformContainerLoading.ts') assert.match(controller, /@GetMapping\("\/domestic"\)/) assert.match(controller, /@GetMapping\("\/domestic\/\{id\}"\)/) assert.match(controller, /ApiResponse>/) assert.match(admin, /listContainers\([^\n]*workbench: ContainerWorkbenchKind = 'DOMESTIC'/) assert.ok(admin.includes('`${containerPath}/${workbench.toLowerCase()}`')) assert.ok(admin.includes('`${containerPath}/${workbench.toLowerCase()}/${encodeURIComponent(containerId)}`')) const loading = read('./phase3-container-loading.mjs') assert.ok(loading.includes('size=20&scope=ACTIVE&status=')) assert.ok(loading.includes('containerWorkbenchGaps(containerDetailResponse.body?.data)')) assert.ok(loading.includes('records(page).every((item) => containerWorkbenchGaps(item).length === 0)')) assert.ok(!loading.includes('value?.container || value')) }) test('manual and coload consumers read domestic WorkbenchItem rather than the removed flat routes', () => { for (const name of ['manual-loading-complete-fixture', 'manual-order-splitting-verify', 'manual-pda-ready-fixture', 'manual-pda-ready-verify', 'manual-preload-push-fixture', 'manual-preload-push-verify', 'coload-groups']) { const source = read(`./${name}.mjs`) assert.ok(source.includes("context.request('GET', `${CONTAINERS}/domestic/${"), name) assert.ok(!source.includes("context.request('GET', `${CONTAINERS}/${"), name) assert.match(source, /OPTIONS\)\?\.container/, name) } const states = read('./manual-state-loading-pda.mjs') assert.ok(states.includes('`${CONTAINERS}/domestic?scope=ACTIVE&status=')) assert.ok(states.includes('item.container?.planStatus === status')) }) test('domestic container fixtures use the current workbench detail route', () => { const containerLoading = read('./phase3-container-loading.mjs') assert.ok(containerLoading.includes("context.request('GET', `${DOMESTIC_CONTAINERS}/${containerId}`)")) assert.ok(!containerLoading.includes("context.request('GET', `${CONTAINERS}/${containerId}`)")) assert.ok(containerLoading.includes("const containerDetail = containerRecord(context.apiSuccess(MODULE, '回查货柜详情'")) assert.ok(containerLoading.includes("const simulationBeforeLink = containerRecord(context.apiSuccess(MODULE, '预装确认前读取模拟柜最新版本'")) assert.ok(containerLoading.includes('`${DOMESTIC_CONTAINERS}?page=1&size=50&scope=ACTIVE&keyword=')) assert.ok(containerLoading.includes('records(activeContainers).map(containerRecord)')) const loading = read('./phase3-loading.mjs') assert.ok(loading.includes("context.request('GET', `/api/platform/v1/containers/domestic/${containerBookingId}`)")) assert.ok(!loading.includes("context.request('GET', `/api/platform/v1/containers/${containerBookingId}`)")) assert.ok(loading.includes("const latestContainer = containerRecord(context.apiSuccess(MODULE, '合并前读取模拟柜最新版本'")) const crossRegion = read('./phase4-cross-region-events.mjs') const fixtureId = 'encodeURIComponent(id(phase3.containerBookingId))' assert.ok(crossRegion.includes(`/api/platform/v1/containers/domestic/\${${fixtureId}}`)) assert.ok(!crossRegion.includes(`/api/platform/v1/containers/\${${fixtureId}}`)) assert.ok(crossRegion.includes('/api/platform/v1/containers/domestic?scope=HISTORY&containerNo=')) assert.ok(crossRegion.includes('.map((item) => item?.container).filter(')) }) test('service center truck fixture uses the released booking warehouse', () => { const source = read('./service-center-flow.mjs') assert.ok(source.includes('warehouseId: id(booking?.warehouseId)')) assert.ok(!source.includes('context.createdResources?.warehouse?.id')) })