Files
IM/frontend/pc/IM/tests/uploader.test.js
T

101 lines
3.1 KiB
JavaScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const mocks = vi.hoisted(() => ({
getFileHash: vi.fn(),
sliceFile: vi.fn(),
initUploadTask: vi.fn(),
getProgress: vi.fn(),
getUploadUrl: vi.fn(),
getTaskStatus: vi.fn(),
completeTask: vi.fn(),
uploadPart: vi.fn(),
uploadPartToUrl: vi.fn()
}))
vi.mock('@/utils/uploadTools', () => ({
getFileHash: mocks.getFileHash,
sliceFile: mocks.sliceFile
}))
vi.mock('@/services/upload/uploadService', () => ({
uploadService: {
initUploadTask: mocks.initUploadTask,
getProgress: mocks.getProgress,
getUploadUrl: mocks.getUploadUrl,
getTaskStatus: mocks.getTaskStatus,
completeTask: mocks.completeTask,
uploadPart: mocks.uploadPart,
uploadPartToUrl: mocks.uploadPartToUrl
}
}))
import { uploadFile } from '@/services/upload/uploader'
const file = {
name: 'demo.bin',
size: 10,
type: 'application/octet-stream'
}
describe('uploadFile', () => {
beforeEach(() => {
vi.clearAllMocks()
mocks.getFileHash.mockResolvedValue('0123456789abcdef0123456789abcdef')
mocks.sliceFile.mockReturnValue([{ size: 5 }, { size: 5 }])
})
it('returns the final file immediately on an instant upload hit', async () => {
const finalFile = { id: 'file-1', url: 'https://files.test/file-1' }
mocks.initUploadTask.mockResolvedValue({
data: { taskId: 'file-1', instant: true, uploadMode: 'Instant', file: finalFile }
})
await expect(uploadFile(file, { chatType: 'PRIVATE', targetId: 'user-2' }))
.resolves.toEqual(finalFile)
expect(mocks.uploadPart).not.toHaveBeenCalled()
expect(mocks.completeTask).not.toHaveBeenCalled()
})
it('uploads every local part, completes, and waits for the final file', async () => {
const finalFile = { id: 'file-2', url: null }
mocks.initUploadTask.mockResolvedValue({
data: {
taskId: 'task-2',
uploadSessionId: 'session-2',
uploadMode: 'LocalMultipart',
totalPartCount: 2,
partSizeBytes: 5,
instant: false
}
})
mocks.uploadPart.mockImplementation((_session, partNumber) =>
Promise.resolve({ data: { eTag: `etag-${partNumber}` } })
)
mocks.completeTask.mockResolvedValue({ data: { state: 'Merging' } })
mocks.getTaskStatus.mockResolvedValue({ data: { state: 'Completed', file: finalFile } })
await expect(uploadFile(file, { chatType: 'GROUP', targetId: 'group-1' }))
.resolves.toEqual(finalFile)
expect(mocks.uploadPart).toHaveBeenCalledTimes(2)
expect(mocks.completeTask).toHaveBeenCalledOnce()
expect(mocks.getTaskStatus).toHaveBeenCalledWith('task-2')
})
it('does not call complete when a part keeps failing', async () => {
mocks.initUploadTask.mockResolvedValue({
data: {
taskId: 'task-3',
uploadSessionId: 'session-3',
uploadMode: 'LocalMultipart',
totalPartCount: 2,
partSizeBytes: 5,
instant: false
}
})
mocks.uploadPart.mockRejectedValue(new Error('part failed'))
await expect(uploadFile(file)).rejects.toThrow('part failed')
expect(mocks.completeTask).not.toHaveBeenCalled()
})
})