style(admin): unify dialog layouts and dense readonly presentation
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import ElementPlus from 'element-plus'
|
||||
import ElementPlus, { ElMessageBox } from 'element-plus'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import OceanBookingDocumentsPanel from './OceanBookingDocumentsPanel.vue'
|
||||
import { uploadOceanBookingDocument } from '../api/platformOceanBookings'
|
||||
import type { OceanBookingDocument } from '../types'
|
||||
import { invalidateOceanBookingDocument, uploadOceanBookingDocument } from '../api/platformOceanBookings'
|
||||
|
||||
vi.mock('../api/platformOceanBookings', () => ({
|
||||
downloadOceanBookingDocument: vi.fn(),
|
||||
@@ -93,3 +94,52 @@ describe('OceanBookingDocumentsPanel contract', () => {
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
function documentFixture(id: string): OceanBookingDocument {
|
||||
return { id, oceanBookingId: '123', fileId: `file-${id}`, documentType: 'BOOKING_CONFIRMATION', fileName: `${id}.pdf`, fileHash: null, sizeBytes: 128, contentType: 'application/pdf', valid: true, uploadedBy: 'internal-operator-id', uploadedByName: null, uploadedAt: '2026-10-19T10:00:00', invalidatedBy: null, invalidatedByName: null, invalidatedAt: null }
|
||||
}
|
||||
afterEach(() => { vi.restoreAllMocks(); document.body.innerHTML = '' })
|
||||
describe('OceanBookingDocumentsPanel confirmations', () => {
|
||||
beforeEach(() => { vi.clearAllMocks() })
|
||||
it('uses the booking number and preserves replacement upload/invalidation version chaining', async () => {
|
||||
const old = documentFixture('old')
|
||||
const uploaded = documentFixture('new')
|
||||
vi.mocked(uploadOceanBookingDocument).mockResolvedValue({ document: uploaded, bookingVersion: 3 })
|
||||
vi.mocked(invalidateOceanBookingDocument).mockResolvedValue({ documentId: old.id, bookingVersion: 4 })
|
||||
const confirm = vi.spyOn(ElMessageBox, 'confirm').mockResolvedValue(undefined as never)
|
||||
const wrapper = mount(OceanBookingDocumentsPanel, { props: { bookingId: '123', bookingNo: 'OB-123', bookingVersion: 2, bookingStatus: 'DRAFT', documents: [old], canManage: true }, global: { plugins: [ElementPlus] } })
|
||||
expect(wrapper.text()).not.toContain('internal-operator-id')
|
||||
const file = new File(['new'], '替换资料.pdf', { type: 'application/pdf' })
|
||||
const input = wrapper.findAll('input[type="file"]')[0]!
|
||||
Object.defineProperty(input.element, 'files', { configurable: true, value: [file] })
|
||||
await input.trigger('change')
|
||||
await flushPromises()
|
||||
expect(confirm).toHaveBeenCalledWith(expect.stringContaining('替换资料.pdf'), '替换订舱资料 · OB-123', expect.objectContaining({ customClass: 'admin-density-confirm', confirmButtonText: '确认替换' }))
|
||||
expect(uploadOceanBookingDocument).toHaveBeenCalledExactlyOnceWith('123', 2, 'BOOKING_CONFIRMATION', file)
|
||||
expect(invalidateOceanBookingDocument).toHaveBeenCalledExactlyOnceWith('123', 'old', 3)
|
||||
expect(wrapper.emitted('updated')).toEqual([
|
||||
[[old, uploaded], 3],
|
||||
[[expect.objectContaining({ id: 'old', valid: false }), uploaded], 4],
|
||||
])
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('leaves documents unchanged when invalidation is cancelled and uses the current version on confirmation', async () => {
|
||||
const old = documentFixture('old')
|
||||
const confirm = vi.spyOn(ElMessageBox, 'confirm').mockRejectedValueOnce('cancel').mockResolvedValueOnce(undefined as never)
|
||||
vi.mocked(invalidateOceanBookingDocument).mockResolvedValue({ documentId: old.id, bookingVersion: 3 })
|
||||
const wrapper = mount(OceanBookingDocumentsPanel, { props: { bookingId: '123', bookingNo: 'OB-123', bookingVersion: 2, bookingStatus: 'DRAFT', documents: [old], canManage: true }, global: { plugins: [ElementPlus] } })
|
||||
const button = wrapper.findAll('button').find(item => item.text() === '作废')!
|
||||
await button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(invalidateOceanBookingDocument).not.toHaveBeenCalled()
|
||||
expect(wrapper.emitted('updated')).toBeUndefined()
|
||||
await button.trigger('click')
|
||||
await flushPromises()
|
||||
expect(confirm).toHaveBeenLastCalledWith(expect.stringContaining('old.pdf'), '作废订舱资料 · OB-123', expect.objectContaining({ confirmButtonText: '确认作废' }))
|
||||
expect(invalidateOceanBookingDocument).toHaveBeenCalledExactlyOnceWith('123', 'old', 2)
|
||||
expect(wrapper.emitted('updated')).toEqual([[[expect.objectContaining({ id: 'old', valid: false })], 3]])
|
||||
wrapper.unmount()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user