优化
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import ElementPlus from 'element-plus'
|
||||
import ContainerOverviewPanel from './ContainerOverviewPanel.vue'
|
||||
import type { ContainerOverview } from '../types'
|
||||
import { downloadContainerPdaPhoto } from '../api/platformContainerLoading'
|
||||
|
||||
vi.mock('../api/platformContainerLoading', () => ({ downloadContainerPdaPhoto: vi.fn() }))
|
||||
|
||||
const overview: ContainerOverview = {
|
||||
container: { id: '7', bookingNo: 'BK-1', cabinetNo: 'CB-1', containerNo: 'MSCU-1', status: 'LOADING', warehouseId: '8', warehouseName: '义乌仓', voyageNo: 'V1', vesselName: '船一', version: 2 },
|
||||
@@ -15,8 +18,16 @@ const overview: ContainerOverview = {
|
||||
}
|
||||
|
||||
describe('ContainerOverviewPanel', () => {
|
||||
it('renders documents, PDA progress, exception history and timeline from the aggregate DTO', () => {
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.mocked(downloadContainerPdaPhoto).mockResolvedValue(new Blob(['photo']))
|
||||
Object.defineProperty(URL, 'createObjectURL', { configurable: true, value: vi.fn(() => 'blob:container-photo') })
|
||||
Object.defineProperty(URL, 'revokeObjectURL', { configurable: true, value: vi.fn() })
|
||||
})
|
||||
|
||||
it('renders documents, PDA progress, exception history and timeline from the aggregate DTO', async () => {
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('DO 资料')
|
||||
expect(wrapper.text()).toContain('do.pdf')
|
||||
expect(wrapper.text()).toContain('PDA 作业进度')
|
||||
@@ -29,25 +40,72 @@ describe('ContainerOverviewPanel', () => {
|
||||
})
|
||||
|
||||
it('emits stable document types and does not expose file ids in visible text', async () => {
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
const updateButton = wrapper.findAll('button').find((button) => button.text().includes('更新'))!
|
||||
await updateButton.trigger('click')
|
||||
expect(wrapper.emitted('uploadDocument')?.[0]).toEqual(['DELIVERY_ORDER'])
|
||||
expect(wrapper.text()).not.toContain('9007199254740999')
|
||||
})
|
||||
|
||||
it('emits the backend-provided photo object from an accessible view control', async () => {
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
await wrapper.find('button[aria-label="查看装柜照片 empty.jpg"]').trigger('click')
|
||||
expect(wrapper.emitted('previewPhoto')?.[0]?.[0]).toMatchObject({ evidenceId: '20', downloadPath: '/api/platform/v1/containers/7/pda/photos/23/download' })
|
||||
it('loads protected photos into direct thumbnails, opens them and revokes object URLs', async () => {
|
||||
const open = vi.spyOn(window, 'open').mockImplementation(() => null)
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(downloadContainerPdaPhoto).toHaveBeenCalledWith('/api/platform/v1/containers/7/pda/photos/23/download')
|
||||
expect(wrapper.find('img[src="blob:container-photo"]').exists()).toBe(true)
|
||||
await wrapper.find('button[aria-label="预览装柜照片 empty.jpg"]').trigger('click')
|
||||
expect(open).toHaveBeenCalledWith('blob:container-photo', '_blank', 'noopener,noreferrer')
|
||||
wrapper.unmount()
|
||||
expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:container-photo')
|
||||
})
|
||||
|
||||
it('renders empty and forbidden/load failure states without exposing credentials', () => {
|
||||
it('revokes old thumbnail URLs when the overview photos change', async () => {
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
const changed = { ...overview.pda!.photos[0], evidenceId: '22', fileId: '25', fileName: 'next.jpg', downloadPath: '/api/platform/v1/containers/7/pda/photos/25/download' }
|
||||
await wrapper.setProps({ overview: { ...overview, pda: { ...overview.pda!, photos: [changed] } } })
|
||||
await flushPromises()
|
||||
expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:container-photo')
|
||||
expect(downloadContainerPdaPhoto).toHaveBeenCalledWith('/api/platform/v1/containers/7/pda/photos/25/download')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('isolates one thumbnail failure without blocking other photos', async () => {
|
||||
const second = { ...overview.pda!.photos[0], evidenceId: '21', fileId: '24', fileName: 'seal.jpg', evidenceType: 'SEAL', downloadPath: '/api/platform/v1/containers/7/pda/photos/24/download' }
|
||||
vi.mocked(downloadContainerPdaPhoto).mockResolvedValueOnce(new Blob(['photo'])).mockRejectedValueOnce(new Error('photo unavailable'))
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview: { ...overview, pda: { ...overview.pda!, photos: [...overview.pda!.photos, second] } }, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.find('img[src="blob:container-photo"]').exists()).toBe(true)
|
||||
expect(wrapper.text()).toContain('照片加载失败')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('maps PDA events to Chinese and hides long technical keys from the main timeline', () => {
|
||||
const longKey = 'pda-submit-1000001-2092438843630391297-2092437496092790785--0c642e80891d76a4-m9428-76'
|
||||
const timeline = [
|
||||
{ eventType: 'PDA_CLAIM', detail: `claim-${longKey}`, operatorId: '1', operatorName: 'platform_admin', occurredAt: '2026-08-26T10:28:00' },
|
||||
{ eventType: 'PDA_BATCH', detail: longKey, operatorId: '1', operatorName: 'platform_admin', occurredAt: '2026-08-26T10:28:00' },
|
||||
{ eventType: 'PDA_COMPLETE_LOADING', detail: `complete-${longKey}`, operatorId: '1', operatorName: 'platform_admin', occurredAt: '2026-08-26T10:29:00' },
|
||||
]
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview: { ...overview, pda: null, timeline }, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
expect(wrapper.text()).toContain('领取 PDA 任务')
|
||||
expect(wrapper.text()).toContain('提交拣货结果')
|
||||
expect(wrapper.text()).toContain('完成装柜')
|
||||
expect(wrapper.text()).not.toContain(longKey)
|
||||
})
|
||||
|
||||
it('renders a compact empty photo state without exposing credentials', () => {
|
||||
const withoutPhotos = { ...overview, pda: overview.pda ? { ...overview.pda, photos: [] } : null }
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview: withoutPhotos, canManageDocuments: false, canManageException: false, photoError: { message: '当前账号无权访问该数据,请联系管理员确认权限', code: 'HTTP_403', requestId: 'req-photo' } }, global: { plugins: [ElementPlus] } })
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview: withoutPhotos, canManageDocuments: false, canManageCustoms: false, canManageException: false }, global: { plugins: [ElementPlus] } })
|
||||
expect(wrapper.text()).toContain('暂无可查看的有效照片')
|
||||
expect(wrapper.text()).toContain('当前账号无权访问该数据')
|
||||
expect(wrapper.text()).toContain('req-photo')
|
||||
expect(wrapper.text()).not.toContain('Authorization')
|
||||
})
|
||||
|
||||
it('keeps a completed customs document labelled as an attachment, not formal customs release', () => {
|
||||
const customs = { ...overview.documents[0], documentType: 'CUSTOMS_DECLARATION', completed: true, fileName: 'customs.pdf' }
|
||||
const wrapper = mount(ContainerOverviewPanel, { props: { overview: { ...overview, pda: null, documents: [customs] }, canManageDocuments: true, canManageCustoms: true, canManageException: true }, global: { plugins: [ElementPlus] } })
|
||||
expect(wrapper.text()).toContain('国内出口报关附件')
|
||||
expect(wrapper.text()).not.toContain('已完成报关')
|
||||
expect(wrapper.text()).not.toContain('已放行')
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user