2026-08-17 17:49:10 +08:00
|
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
|
import { resolve } from 'node:path'
|
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
|
|
|
|
|
|
const source = readFileSync(resolve(process.cwd(), 'src/modules/inbounds/measurement/InboundMeasurementDialog.vue'), 'utf8')
|
|
|
|
|
const panelSource = readFileSync(resolve(process.cwd(), 'src/modules/inbounds/measurement/InboundMeasurementPanel.vue'), 'utf8')
|
|
|
|
|
const taskListSource = readFileSync(resolve(process.cwd(), 'src/modules/inbounds/components/InboundTaskList.vue'), 'utf8')
|
|
|
|
|
const orderListSource = readFileSync(resolve(process.cwd(), 'src/modules/unified-orders/pages/UnifiedOrdersView.vue'), 'utf8')
|
|
|
|
|
|
2026-09-14 17:54:21 +08:00
|
|
|
const densitySource = readFileSync(resolve(process.cwd(), 'src/styles/adminDensity.css'), 'utf8')
|
|
|
|
|
|
2026-08-17 17:49:10 +08:00
|
|
|
describe('InboundMeasurementDialog', () => {
|
|
|
|
|
it('owns the complete measurement workspace behind one centered dialog', () => {
|
2026-09-04 11:35:24 +08:00
|
|
|
expect(source).toContain("import AppDialog from '@/shared/components/AppDialog.vue'")
|
|
|
|
|
expect(source).toContain('<AppDialog')
|
2026-09-14 15:33:35 +08:00
|
|
|
expect(source).toContain('class="inbound-measurement-workspace-dialog admin-density-dialog admin-density-workspace inbound-density"')
|
|
|
|
|
expect(source).toContain('width="min(1560px, calc(100vw - 48px))"')
|
2026-08-17 17:49:10 +08:00
|
|
|
expect(source).toContain('height: 92vh')
|
2026-09-14 17:54:21 +08:00
|
|
|
expect(densitySource).toContain('.admin-density-dialog.el-dialog .el-dialog__header')
|
|
|
|
|
expect(densitySource).toContain('padding: var(--admin-space-4, 10px) 48px var(--admin-space-4, 10px) var(--admin-space-6, 16px)')
|
2026-08-17 17:49:10 +08:00
|
|
|
expect(source).toContain('<WeightOcrPanel')
|
|
|
|
|
expect(source).toContain('<InboundMeasurementPanel')
|
2026-09-18 11:41:27 +08:00
|
|
|
expect(source).toContain('customerName?: string | null')
|
|
|
|
|
expect(source).toContain(':customer-name="customerName"')
|
2026-08-17 18:32:41 +08:00
|
|
|
expect(source).toContain('class="measurement-dialog-weight"')
|
|
|
|
|
expect(source).not.toContain('class="surface-panel measurement-dialog-weight"')
|
|
|
|
|
expect(source).toContain('border-bottom: 1px solid var(--cc-border)')
|
2026-08-17 17:49:10 +08:00
|
|
|
expect(source).toContain('@summary-changed="handleWeightSummaryChanged"')
|
2026-09-11 16:17:21 +08:00
|
|
|
expect(source).toContain('measurementPanelRef.value?.updateWeightEvidence(actualGrossWeightKg, actualNetWeightKg, hasConfirmedWeight)')
|
|
|
|
|
expect(source).toContain('measurementPanelRef?.submissionBlockReason')
|
2026-08-18 11:33:01 +08:00
|
|
|
})
|
|
|
|
|
|
2026-09-04 11:35:24 +08:00
|
|
|
it('offers the shared fullscreen control without forcing fullscreen on open', () => {
|
|
|
|
|
expect(source).toContain('fullscreenable')
|
|
|
|
|
expect(source).not.toContain('default-fullscreen')
|
|
|
|
|
expect(source).not.toContain('<el-dialog')
|
|
|
|
|
})
|
|
|
|
|
|
2026-08-18 11:33:01 +08:00
|
|
|
it('shows the inbound code once in the dialog title and not as a second body heading', () => {
|
2026-08-30 17:43:03 +08:00
|
|
|
expect(source).toContain("`测量 · ${props.inboundCode?.trim() || '入仓码待补充'}`")
|
|
|
|
|
expect(source).not.toContain('props.inboundCode?.trim() || props.inboundId')
|
2026-08-18 11:33:01 +08:00
|
|
|
expect(source).toContain(':title="title"')
|
|
|
|
|
expect(panelSource).not.toContain('<span>入仓码</span>')
|
|
|
|
|
expect(panelSource).not.toContain('<strong>{{ detail.inboundCode')
|
|
|
|
|
expect(panelSource).toContain('class="measurement-summary-context"')
|
2026-08-17 17:49:10 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('is the only measurement dialog opened by both formal list entries', () => {
|
|
|
|
|
for (const entrySource of [taskListSource, orderListSource]) {
|
|
|
|
|
expect(entrySource).toContain('<InboundMeasurementDialog')
|
|
|
|
|
expect(entrySource).not.toContain('<InboundMeasurementPanel')
|
|
|
|
|
expect(entrySource).not.toContain('<WeightOcrPanel')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('keeps draft saves open, closes only after submit, and refreshes parent entries consistently', () => {
|
|
|
|
|
expect(source).toContain('@saved="handleUpdated"')
|
|
|
|
|
expect(source).toContain('@updated="handleUpdated"')
|
|
|
|
|
expect(source).toContain('@submitted="handleSubmitted"')
|
|
|
|
|
expect(source).toContain("emit('updated')")
|
|
|
|
|
expect(source).toContain("emit('update:modelValue', false)")
|
|
|
|
|
expect(source).toContain("emit('submitted')")
|
|
|
|
|
expect(panelSource).toContain("emit('saved')")
|
|
|
|
|
expect(panelSource).toContain("emit('submitted')")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('uses the existing permission-aware panels and protects unsaved work on close', () => {
|
|
|
|
|
expect(source).toContain('measurementPanelRef.value?.isDirty')
|
|
|
|
|
expect(source).toContain('当前测量数据尚未保存')
|
|
|
|
|
expect(source).toContain(':close-on-click-modal="false"')
|
|
|
|
|
expect(source).toContain(':before-close="beforeClose"')
|
|
|
|
|
expect(source).toContain('measurementPanelRef?.canEdit')
|
|
|
|
|
expect(source).toContain('measurementPanelRef?.canSubmit')
|
|
|
|
|
})
|
|
|
|
|
})
|