88 lines
4.5 KiB
TypeScript
88 lines
4.5 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const source = readFileSync(resolve(process.cwd(), 'src/modules/port-schedules/components/CarrierScheduleQueryPanel.vue'), 'utf8')
|
|
const apiSource = readFileSync(resolve(process.cwd(), 'src/modules/port-schedules/api/platformCarrierScheduleQueries.ts'), 'utf8')
|
|
|
|
describe('CarrierScheduleQueryPanel', () => {
|
|
it('uses the existing relation filters and never creates or executes polling tasks', () => {
|
|
expect(source).toContain('listCarrierScheduleQueries({ page: 1, size: 200')
|
|
expect(source).toContain('oceanBookingId: props.oceanBookingId')
|
|
expect(source).toContain('containerBookingId: props.containerBookingId')
|
|
expect(source).not.toContain('createCarrierSchedule')
|
|
expect(source).not.toContain(['attempt', 'CarrierSchedule'].join(''))
|
|
})
|
|
|
|
it('shows source, observation/update times, history, failures and expiry truthfully', () => {
|
|
expect(source).toContain('最新来源')
|
|
expect(source).toContain('观测时间')
|
|
expect(source).toContain('来源参考')
|
|
expect(source).toContain('providerCode')
|
|
expect(source).toContain('sourceReference')
|
|
expect(source).toContain('实际发生时间')
|
|
expect(source).toContain('变更历史')
|
|
expect(source).toContain('query?.lastErrorMessage')
|
|
expect(source).toContain('query.lastErrorCode')
|
|
expect(source).toContain("queryView?.expired ? '结果已过期' : '结果有效'")
|
|
})
|
|
|
|
it('keeps query-history and linked-schedule partial failures independently visible', () => {
|
|
expect(source).toContain('queryDetailError')
|
|
expect(source).toContain('scheduleError')
|
|
expect(source).toContain('标准节点与变更历史暂不可用')
|
|
expect(source).toContain('关联船期结果暂不可用')
|
|
})
|
|
|
|
it('shows all ten canonical nodes and stops only on actual empty return', () => {
|
|
for (const node of ['DEPARTED_WAREHOUSE', 'AT_ORIGIN_PORT', 'LOADED_ON_VESSEL', 'DEPARTED_ORIGIN_PORT', 'IN_TRANSIT', 'ARRIVED_DESTINATION_PORT', 'DISCHARGED_FROM_VESSEL', 'PICKUP_READY', 'PICKED_UP', 'EMPTY_RETURNED']) expect(source).toContain(node)
|
|
expect(source).not.toMatch(new RegExp(`\\b${['ARR', 'IVED'].join('')}:`))
|
|
expect(source).toContain("latestActualNode === 'EMPTY_RETURNED'")
|
|
expect(source).toContain("'已停止 · 已还柜'")
|
|
expect(source).toContain('确认离仓后自动开始船节点跟踪')
|
|
expect(source).not.toContain('/' + 'scheduler')
|
|
expect(source).not.toContain('/' + 'attempts')
|
|
})
|
|
|
|
it('uses a compact no-task state without the large empty illustration', () => {
|
|
expect(source).toContain('class="tracking-prompt"')
|
|
expect(source).not.toContain('<el-empty v-else-if="!query"')
|
|
expect(source).toContain('确认离仓后自动开始船节点跟踪')
|
|
})
|
|
|
|
it('keeps estimated facts labelled and separate from actual progress', () => {
|
|
expect(source).toContain("actual ? `实际")
|
|
expect(source).toContain("item.estimatedAt ? `预计")
|
|
expect(source).toContain('latestActualNode')
|
|
expect(source).toContain('item.actualAt')
|
|
})
|
|
|
|
it('blocks repeated actual progress and folds older immutable facts out of the primary trajectory', () => {
|
|
expect(source).toContain('isManualActualNodeAllowed')
|
|
expect(source).toContain(':disabled="Boolean(manualForm.actualAt) && !isManualActualNodeAllowed(node)"')
|
|
expect(source).toContain('primaryNodeFacts')
|
|
expect(source).toContain('supersededActualNodes')
|
|
expect(source).toContain('历史重复实际节点')
|
|
})
|
|
|
|
it('uses the frozen manual-node permission and keeps exceptions separate', () => {
|
|
expect(source).toContain("access.can('platform:firstleg:port-schedule-query:manual')")
|
|
expect(source).toContain('appendCarrierScheduleManualNode')
|
|
expect(source).toContain('manualIdempotencyKey')
|
|
expect(source).toContain("type: '异常'")
|
|
expect(source).toContain('船运跟踪')
|
|
expect(source).toContain('item.providerStatus')
|
|
expect(source).not.toContain('/' + 'manual-results')
|
|
})
|
|
|
|
it('keeps retired progress fields and forbidden write endpoints out of the panel and adapter', () => {
|
|
const productionSource = `${source}\n${apiSource}`
|
|
expect(productionSource).not.toContain(['latest', 'StandardNode'].join(''))
|
|
expect(productionSource).not.toContain(['latest', 'NodeObservedAt'].join(''))
|
|
expect(productionSource).not.toContain('/' + 'attempts')
|
|
expect(productionSource).not.toContain('/' + 'manual-results')
|
|
expect(productionSource).not.toContain('/' + 'scheduler')
|
|
expect(apiSource).toContain('/manual-nodes')
|
|
})
|
|
})
|