优化
This commit is contained in:
@@ -54,6 +54,8 @@ function deferred<T>() {
|
||||
}
|
||||
type ClearanceVm = { clearanceOpen: boolean; clearanceFile: File | null; clearanceError: { code?: string; requestId?: string } | null; documentRefreshWarning: unknown; selectClearanceFile: (file: { raw: File }) => void; uploadClearance: () => Promise<void>; completeClearance: () => Promise<void> }
|
||||
function clearanceVm(wrapper: VueWrapper) { return wrapper.vm as unknown as ClearanceVm }
|
||||
type DocumentVm = { documentOpen: boolean; documentFile: File | null; documentError: { code?: string; requestId?: string } | null; documentUploadKey: number; documentRefreshWarning: { code?: string } | null; selectDocumentFile: (file: { raw: File }) => void; saveDocument: () => Promise<void> }
|
||||
function documentVm(wrapper: VueWrapper) { return wrapper.vm as unknown as DocumentVm }
|
||||
|
||||
describe('ContainerDetailView', () => {
|
||||
beforeEach(() => {
|
||||
@@ -193,6 +195,63 @@ describe('ContainerDetailView', () => {
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it.each([
|
||||
['DELIVERY_ORDER', 'DO 资料'],
|
||||
['PICKUP_ORDER', 'PU 资料'],
|
||||
] as const)('optimistically replaces %s, closes before overview refresh and preserves the returned file over a stale overview', async (documentType, label) => {
|
||||
const existing = { id: `old-${documentType}`, documentType, fileId: `old-file-${documentType}`, fileName: `old-${documentType}.pdf`, fileHash: null, uploadedBy: '1', uploadedByName: '旧操作员', uploadedAt: '2026-08-26T10:00:00', version: 1, completed: false }
|
||||
const initial = { ...overview, documents: [...overview.documents, existing] }
|
||||
const uploaded = { id: `new-${documentType}`, documentType, fileId: `new-file-${documentType}`, fileName: `new-${documentType}.pdf`, fileHash: 'hash', uploadedBy: '2', uploadedByName: '新操作员', uploadedAt: '2026-08-27T13:00:00', completedBy: null, completedByName: null, completedAt: null, version: 2 }
|
||||
const refresh = deferred<typeof initial>()
|
||||
vi.mocked(getContainerOverview).mockResolvedValueOnce(initial as never).mockReturnValueOnce(refresh.promise as never)
|
||||
vi.mocked(uploadContainerDocument).mockResolvedValueOnce(uploaded as never)
|
||||
const wrapper = mountView(); await flushPromises()
|
||||
await documentButton(wrapper, label, '更新附件').trigger('click'); await flushPromises()
|
||||
const file = new File([documentType], `new-${documentType}.pdf`, { type: 'application/pdf' })
|
||||
documentVm(wrapper).selectDocumentFile({ raw: file })
|
||||
const request = documentVm(wrapper).saveDocument(); await flushPromises()
|
||||
expect(uploadContainerDocument).toHaveBeenCalledWith('2092438843630391297', documentType, file, 1, `上传${label}`)
|
||||
expect(documentVm(wrapper).documentOpen).toBe(false)
|
||||
expect(documentVm(wrapper).documentFile).toBeNull()
|
||||
expect(documentArticle(wrapper, label).text()).toContain(`new-${documentType}.pdf`)
|
||||
expect(documentArticle(wrapper, label).text()).toContain('新操作员')
|
||||
refresh.resolve(initial); await request; await flushPromises()
|
||||
expect(documentArticle(wrapper, label).text()).toContain(`new-${documentType}.pdf`)
|
||||
expect(documentVm(wrapper).documentRefreshWarning).toMatchObject({ code: 'DOCUMENT_OVERVIEW_STALE' })
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('rebuilds the upload picker on reopen and keeps DO failures open with the selected file and API evidence', async () => {
|
||||
const existing = { id: 'do-old', documentType: 'DELIVERY_ORDER', fileId: 'do-file-old', fileName: 'old-do.pdf', fileHash: null, uploadedBy: '1', uploadedByName: '旧操作员', uploadedAt: '2026-08-26T10:00:00', version: 1, completed: false }
|
||||
vi.mocked(getContainerOverview).mockResolvedValue({ ...overview, documents: [...overview.documents, existing] } as never)
|
||||
vi.mocked(uploadContainerDocument)
|
||||
.mockRejectedValueOnce(new ApiResponseError('版本冲突', 'A0409', undefined, undefined, 'request-do-409', 'trace-do-409'))
|
||||
.mockResolvedValueOnce(null)
|
||||
const wrapper = mountView(); await flushPromises()
|
||||
await documentButton(wrapper, 'DO 资料', '更新附件').trigger('click'); await flushPromises()
|
||||
const firstKey = documentVm(wrapper).documentUploadKey
|
||||
const file = new File(['do'], 'next-do.pdf', { type: 'application/pdf' })
|
||||
documentVm(wrapper).selectDocumentFile({ raw: file })
|
||||
await documentVm(wrapper).saveDocument(); await flushPromises()
|
||||
expect(documentVm(wrapper).documentOpen).toBe(true)
|
||||
expect(documentVm(wrapper).documentFile).toBe(file)
|
||||
expect(documentVm(wrapper).documentError).toMatchObject({ code: 'A0409', requestId: 'request-do-409' })
|
||||
expect(wrapper.text()).toContain('trace-do-409')
|
||||
documentVm(wrapper).documentOpen = false; await flushPromises()
|
||||
await documentButton(wrapper, 'PU 资料', '上传附件').trigger('click'); await flushPromises()
|
||||
expect(documentVm(wrapper).documentUploadKey).toBeGreaterThan(firstKey)
|
||||
expect(documentVm(wrapper).documentFile).toBeNull()
|
||||
expect(documentVm(wrapper).documentError).toBeNull()
|
||||
expect(wrapper.text()).not.toContain('request-do-409')
|
||||
const puFile = new File(['pu'], 'next-pu.pdf', { type: 'application/pdf' })
|
||||
documentVm(wrapper).selectDocumentFile({ raw: puFile })
|
||||
await documentVm(wrapper).saveDocument(); await flushPromises()
|
||||
expect(documentVm(wrapper).documentOpen).toBe(true)
|
||||
expect(documentVm(wrapper).documentFile).toBe(puFile)
|
||||
expect(uploadContainerDocument).toHaveBeenCalledTimes(2)
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('downloads destination clearance through its dedicated endpoint and keeps completed rows download-only', async () => {
|
||||
const completed = { id: '351', documentType: 'DESTINATION_CLEARANCE', fileId: '2092438843630393502', fileName: 'destination-clearance.pdf', fileHash: null, uploadedBy: '3', uploadedByName: '清关员', uploadedAt: '2026-08-26T11:00:00', version: 2, completed: true }
|
||||
vi.mocked(getContainerOverview).mockResolvedValueOnce({ ...overview, documents: [...overview.documents, completed] } as never)
|
||||
|
||||
Reference in New Issue
Block a user