import { describe, expect, it } from 'vitest' import { readFileSync } from 'node:fs' import { resolve } from 'node:path' const source = readFileSync(resolve(process.cwd(), 'src/modules/loading-lists/pages/PreloadPlanDetailView.vue'), 'utf8') const detailSource = readFileSync(resolve(process.cwd(), 'src/modules/loading-lists/components/LoadingListDetailDrawer.vue'), 'utf8') describe('PreloadPlanDetailView prototype contract', () => { it('is a formal desktop detail page wired to the shared header return action', () => { expect(source).toContain('') expect(source).toContain('@back="goBack"') expect(source).toContain("router.push({ name: 'loading-plans' })") expect(source).toContain('@media (min-width: 1920px) { .preload-detail-page { width: 100%; max-width: none; gap: var(--admin-space-5, 12px); } }') expect(source).not.toContain('AppDrawer') }) it('requires the real warehouse context and preserves status boundaries', () => { expect(source).toContain('MISSING_WAREHOUSE_CONTEXT') expect(source).toContain("['EDITING', 'LOADING'].includes(result.summary.status)") expect(source).toContain('MODE_STATUS_MISMATCH') }) it('switches a completed preload lifecycle to the confirmed detail without swallowing unrelated errors', () => { expect(source).toContain('/loading-plans/${encodeURIComponent(planId.value)}/lifecycle') expect(source).toContain("lifecycle.detailResource === 'LOADING_LIST'") expect(source).toContain("lifecycle.planStatus !== 'COMPLETED'") expect(source).toContain("router.replace({ name: 'domestic-container-detail'") expect(source).toContain("workspace.removeByIds(['preload-plan-detail'])") expect(source).toContain('装柜已完成,已切换至装柜清单详情') expect(source).not.toContain("preloadError.code !== 'A0404'") expect(source).toContain('getConfirmedLoadingList') expect(source).not.toContain("router.push({ name: 'loading-list-detail'") }) it('uses the real optimistic-lock transport endpoint without inventing note writes', () => { expect(source).toContain('updatePreloadTransport') expect(source).toContain('expectedVersion: detail.value.summary.version') expect(source).toContain('width="min(620px, calc(100vw - 28px))"') expect(source).not.toContain('saveMfNote') }) it('edits the selected item internal, warehouse and customer-service remarks with optimistic locking', () => { expect(source).toContain('@edit-remarks="openRemarks"') expect(source).toContain('updateLoadingItemRemarks(current.summary.planId, target.itemId') expect(source).toContain('expectedPlanVersion: current.summary.version') expect(source).toContain('expectedItemVersion: target.itemVersion') expect(source).toContain('operationId: remarkOperationId.value') expect(source).toContain('maxlength="1000"') expect(source).toContain("remarkForm.internalRemark.trim() || null") expect(source).toContain("remarkForm.warehouseRemark.trim() || null") expect(source).toContain("remarkForm.customerServiceRemark.trim() || null") expect(source).toContain('summary: { ...current.summary, version: result.version }') expect(source).toContain('updatedItem?.version') expect(source).not.toContain('plan.remark') }) it('preserves remark input and refreshes current data on conflicts', () => { expect(source).toContain("details.code === 'A0409'") expect(source).toContain('await loadDetail()') expect(source).toContain("detail.value?.items.find((item) => item.itemId === target.itemId) || target") expect(source).toContain('当前输入已保留') expect(source).toContain('计划状态或明细版本已变化') expect(source).toContain(':confirm-loading="remarkSaving"') }) it('supports first entry and reasoned correction before PDA claim without blocking earlier flow', () => { expect(source).toContain("{ required: true, message: '请输入集装箱号'") expect(source).toContain("summary?.status === 'EDITING'") expect(source).toContain("(!pdaStatus || pdaStatus === 'PENDING')") expect(source).not.toContain('summary?.containerNo && summary.status') expect(source).toContain('PDA 已领取或作业已开始,真实集装箱号只读。') expect(source).toContain("isContainerCorrection.value ? '纠正集装箱号 / 航次' : '补录集装箱号 / 航次'") expect(source).toContain("isContainerCorrection.value && !String(value || '').trim() ? new Error('纠错时请输入操作原因')") expect(source).toContain("String(value || '').trim().toUpperCase()") expect(source).toContain('operationReason: editForm.operationReason.trim() || null') expect(detailSource).toContain('v-if="canEditTransport"') expect(detailSource).toContain("summary.containerNo || '待补录'") expect(source).toContain('由服务端按真实条件创建唯一 PDA 任务') expect(source).toContain('缺号不阻断此前流程') expect(source).toContain('PDA 确认装柜完成前由服务端执行最终门禁') expect(source).not.toContain('真实集装箱号未录入时不能确认') }) it('uses a flat blocking note instead of repeated colored page alerts', () => { expect(source).not.toContain(' { expect(source).toContain('confirmPreloadPlan(summary.planId, summary.version, confirmOperationId.value)') expect(source).toContain('summary?.readiness.canConfirm') expect(source).toContain('confirmSaving.value') expect(source).toContain('await loadDetail()') expect(source).toContain('本操作将确认整份预装计划') expect(source).toContain('全部入库预装票据') expect(source).toContain('当前页面不会伪造 PDA 成功') expect(source).not.toContain('/inbounds/') }) it('keeps backend confirmation errors visible and supports narrow dialogs', () => { expect(source).toContain("confirmError.value = getApiErrorDetails(cause, '确认预装失败,请稍后重试')") expect(source).toContain('') expect(source).not.toContain(':message="confirmError.message"') expect(source).toContain('width="min(520px, calc(100vw - 28px))"') expect(source).toContain("label=\"柜次号\"") expect(source).toContain("label=\"集装箱号\"") }) })