import { describe, expect, it } from 'vitest' import { readFileSync } from 'node:fs' import { resolve } from 'node:path' const source = readFileSync(resolve(process.cwd(), 'src/modules/trucking/components/TruckAppointmentForm.vue'), 'utf8') describe('TruckAppointmentForm interaction contract', () => { it('requires a released booking before a real-numbered allocated container', () => { expect(source).toContain("listOceanBookings({ page: 1, size: 200, status: 'RELEASED' })") expect(source).toContain("oceanBookingId: [{ required: true, message: '请选择已放舱订舱'") expect(source).toContain("containerBookingId: [{ required: true, message: '请选择该订舱下已录真实集装箱号的柜次'") expect(source.indexOf('label="订舱"')).toBeLessThan(source.indexOf('label="柜次(真实集装箱号)"')) expect(source).toContain(':disabled="!draft.oceanBookingId || bookingContainersLoading"') expect(source).not.toContain('关联订舱(可选)') expect(source).not.toContain('关联柜次(可选)') }) it('loads only containers allocated to the selected booking and filters missing or malformed physical numbers', () => { expect(source).toContain('getOceanBooking(bookingId)') expect(source).toContain('containers.value = booking.containers || []') expect(source).toContain('bookingDocuments.value = booking.documents || []') expect(source).toContain('isIso6346ContainerNumber(item.containerNo)') expect(source).toContain('该订舱暂无已录真实集装箱号的柜次') expect(source).not.toContain('listContainers') }) it('clears an incompatible container whenever the booking changes', () => { expect(source).toContain('draft.containerBookingId = null') expect(source).toContain('draft.loadingPlanId = null') expect(source).toContain('if (!selectableContainers.value.some((item) => item.containerBookingId === draft.containerBookingId))') }) it('freezes warehouse and bill of lading snapshots without retaining customer data', () => { expect(source).toContain('draft.warehouseId = item.warehouseId') expect(source).toContain('draft.billOfLadingNo = item.billOfLadingNo') expect(source).toContain('已从放舱订舱冻结资料带入') expect(source).toContain(':model-value="draft.billOfLadingNo || \'\'" disabled') expect(source).not.toContain('customerId') expect(source).not.toContain('customerName') expect(source).not.toContain('label="客户"') }) it('keeps server-side validation authoritative and preserves recoverable option errors', () => { expect(source).toContain('最终资格仍由服务端校验') expect(source).toContain('所选订舱缺少有效的订舱确认文件或提单文件') expect(source).toContain('所选订舱缺少有效提单号') expect(source).toContain("booking.status !== 'RELEASED'") expect(source).toContain('bookingContainersError') expect(source).toContain("getApiErrorDetails(cause, '该订舱柜次加载失败,请重试')") expect(source).toContain('') expect(source).toContain('重新加载选项') expect(source).toContain('重新加载') expect(source).toContain('请选择有效的合作中拖车供应商') }) it('labels the generated cabinet reference and physical container number separately', () => { expect(source).toContain('柜次号:${item.cabinetNo') expect(source).toContain('集装箱号:${item.containerNo}') }) it('keeps the form usable at 390px', () => { expect(source).toContain('@media (max-width: 480px)') expect(source).toContain('min-height: 40px') }) it('suppresses duplicate submits and truncates long booking or container labels', () => { expect(source).toContain('if (props.submitting) return') expect(source).toContain(':deep(.el-select__selected-item)') expect(source).toContain('text-overflow:ellipsis') }) })