Files
admin-web/src/modules/ocean-bookings/pages/OceanBookingsView.test.ts
T

50 lines
4.0 KiB
TypeScript
Raw Normal View History

2026-08-08 13:32:27 +08:00
import { describe, expect, it } from 'vitest'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
2026-08-15 09:47:23 +08:00
describe('OceanBookingsView', () => { const source = readFileSync(resolve(process.cwd(), 'src/modules/ocean-bookings/pages/OceanBookingsView.vue'), 'utf8'); it('keeps the operation column first and left fixed', () => { expect(source.indexOf("key: 'actions'")).toBeLessThan(source.indexOf("prop: 'bookingNo'")); expect(source).toContain("fixed: 'left'") }); it('renders loading, empty and error through shared components', () => { expect(source).toContain('LoadErrorState'); expect(source).toContain(':loading="loading"'); expect(source).toContain(':total="total"') }); it('keeps real booking creation available without mixing draft rows into the formal list', () => { expect(source).toContain('<template #toolbar-actions>'); expect(source).toContain('新增订舱'); expect(source).toContain("router.push('/ocean-bookings/new')"); expect(source).toContain("access.can('platform:firstleg:ocean-booking:create')"); expect(source).not.toContain('PageToolbar') }); it('shows only the formal booking detail action', () => { expect(source).toContain('<Eye :size="15" />查看'); expect(source).not.toContain('<Pencil :size="15" />编辑'); expect(source).not.toContain('MoreHorizontal') }); it('limits status filters to the frozen formal booking states', () => { expect(source).toContain("['CONFIRMED', 'CHANGE_PENDING', 'RELEASED', 'CANCELLED']"); expect(source).toContain('options: formalStatusOptions'); expect(source).toContain(':status="oceanBookingStatusLabel(row.status)"'); expect(source).not.toContain(':status="row.status"') }) })
2026-08-12 16:40:09 +08:00
describe('OceanBookingsView prototype field matrix', () => {
const source = readFileSync(resolve(process.cwd(), 'src/modules/ocean-bookings/pages/OceanBookingsView.vue'), 'utf8')
it('keeps the frozen business field sequence after the first action column', () => {
2026-08-17 20:01:51 +08:00
const fields = ['bookingNo', 'customerName', 'billOfLadingNo', 'shipperName', 'consigneeName', 'containerCount', 'carrierName', 'bookingAgent', 'vesselName', 'pol', 'pod', 'etd', 'eta', 'status', 'updatedAt']
2026-08-12 16:40:09 +08:00
let previous = source.indexOf("key: 'actions'")
for (const field of fields) {
const current = source.indexOf(`prop: '${field}'`, previous + 1)
expect(current, field).toBeGreaterThan(previous)
previous = current
}
})
it('formats schedule and update timestamps without adding print actions', () => {
2026-08-17 19:52:04 +08:00
expect(source).toContain("prop: 'billOfLadingNo', label: '提单号'")
2026-08-17 20:01:51 +08:00
expect(source).toContain("prop: 'containerCount', label: '柜量'")
2026-08-12 16:40:09 +08:00
expect(source).toContain('<template #updatedAt="{ row }">{{ formatDateTime(row.updatedAt) }}</template>')
expect(source).toContain('<template #etd="{ row }">{{ formatDateTime(row.etd) }}</template>')
expect(source).not.toContain('打印')
})
})
2026-08-12 18:16:44 +08:00
describe('OceanBookingsView visual action contract', () => {
const source = readFileSync(resolve(process.cwd(), 'src/modules/ocean-bookings/pages/OceanBookingsView.vue'), 'utf8')
it('uses bordered business buttons and stacks them on narrow screens', () => {
expect(source).toContain('size="small" type="primary" plain')
expect(source).not.toContain('link type="primary" @click="open(row.id)')
expect(source).toContain('@media(max-width:420px)')
expect(source).toContain('.table-actions')
expect(source).toContain(':total="total" stripe preference-key="ocean-bookings"')
})
})
2026-08-14 12:50:50 +08:00
describe('OceanBookingsView customer filter contract', () => {
const source = readFileSync(resolve(process.cwd(), 'src/modules/ocean-bookings/pages/OceanBookingsView.vue'), 'utf8')
it('loads active customers, displays names only and submits customerId', () => {
expect(source).toContain("listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })")
expect(source).toContain("customer.status === 'ACTIVE'")
2026-08-14 14:27:03 +08:00
expect(source).toContain("label: customer.tenantName")
2026-08-14 12:50:50 +08:00
expect(source).toContain("customerId: String(query.customerId || '') || undefined")
expect(source).not.toContain('customer.tenantCode')
})
})