|
|
|
@@ -0,0 +1,614 @@ |
|
|
|
import mime from 'mime' |
|
|
|
import { upload } from '@/service/base' |
|
|
|
import { |
|
|
|
downloadFile, |
|
|
|
fileIsUploaded, |
|
|
|
fileUpload, |
|
|
|
getFileAppearanceType, |
|
|
|
getFileExtension, |
|
|
|
getFileNameFromUrl, |
|
|
|
getFilesInLogs, |
|
|
|
getProcessedFiles, |
|
|
|
getProcessedFilesFromResponse, |
|
|
|
getSupportFileExtensionList, |
|
|
|
getSupportFileType, |
|
|
|
isAllowedFileExtension, |
|
|
|
} from './utils' |
|
|
|
import { FileAppearanceTypeEnum } from './types' |
|
|
|
import { SupportUploadFileTypes } from '@/app/components/workflow/types' |
|
|
|
import { TransferMethod } from '@/types/app' |
|
|
|
import { FILE_EXTS } from '../prompt-editor/constants' |
|
|
|
|
|
|
|
jest.mock('mime', () => ({ |
|
|
|
__esModule: true, |
|
|
|
default: { |
|
|
|
getExtension: jest.fn(), |
|
|
|
}, |
|
|
|
})) |
|
|
|
|
|
|
|
jest.mock('@/service/base', () => ({ |
|
|
|
upload: jest.fn(), |
|
|
|
})) |
|
|
|
|
|
|
|
describe('file-uploader utils', () => { |
|
|
|
beforeEach(() => { |
|
|
|
jest.clearAllMocks() |
|
|
|
}) |
|
|
|
|
|
|
|
describe('fileUpload', () => { |
|
|
|
it('should handle successful file upload', async () => { |
|
|
|
const mockFile = new File(['test'], 'test.txt') |
|
|
|
const mockCallbacks = { |
|
|
|
onProgressCallback: jest.fn(), |
|
|
|
onSuccessCallback: jest.fn(), |
|
|
|
onErrorCallback: jest.fn(), |
|
|
|
} |
|
|
|
|
|
|
|
jest.mocked(upload).mockResolvedValue({ id: '123' }) |
|
|
|
|
|
|
|
await fileUpload({ |
|
|
|
file: mockFile, |
|
|
|
...mockCallbacks, |
|
|
|
}) |
|
|
|
|
|
|
|
expect(upload).toHaveBeenCalled() |
|
|
|
expect(mockCallbacks.onSuccessCallback).toHaveBeenCalledWith({ id: '123' }) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getFileExtension', () => { |
|
|
|
it('should get extension from mimetype', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('pdf') |
|
|
|
expect(getFileExtension('file', 'application/pdf')).toBe('pdf') |
|
|
|
}) |
|
|
|
|
|
|
|
it('should get extension from filename if mimetype fails', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue(null) |
|
|
|
expect(getFileExtension('file.txt', '')).toBe('txt') |
|
|
|
expect(getFileExtension('file.txt.docx', '')).toBe('docx') |
|
|
|
expect(getFileExtension('file', '')).toBe('') |
|
|
|
}) |
|
|
|
|
|
|
|
it('should return empty string for remote files', () => { |
|
|
|
expect(getFileExtension('file.txt', '', true)).toBe('') |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getFileAppearanceType', () => { |
|
|
|
it('should identify gif files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('gif') |
|
|
|
expect(getFileAppearanceType('image.gif', 'image/gif')) |
|
|
|
.toBe(FileAppearanceTypeEnum.gif) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify image files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('jpg') |
|
|
|
expect(getFileAppearanceType('image.jpg', 'image/jpeg')) |
|
|
|
.toBe(FileAppearanceTypeEnum.image) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('jpeg') |
|
|
|
expect(getFileAppearanceType('image.jpeg', 'image/jpeg')) |
|
|
|
.toBe(FileAppearanceTypeEnum.image) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('png') |
|
|
|
expect(getFileAppearanceType('image.png', 'image/png')) |
|
|
|
.toBe(FileAppearanceTypeEnum.image) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('webp') |
|
|
|
expect(getFileAppearanceType('image.webp', 'image/webp')) |
|
|
|
.toBe(FileAppearanceTypeEnum.image) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('svg') |
|
|
|
expect(getFileAppearanceType('image.svg', 'image/svgxml')) |
|
|
|
.toBe(FileAppearanceTypeEnum.image) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify video files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mp4') |
|
|
|
expect(getFileAppearanceType('video.mp4', 'video/mp4')) |
|
|
|
.toBe(FileAppearanceTypeEnum.video) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mov') |
|
|
|
expect(getFileAppearanceType('video.mov', 'video/quicktime')) |
|
|
|
.toBe(FileAppearanceTypeEnum.video) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mpeg') |
|
|
|
expect(getFileAppearanceType('video.mpeg', 'video/mpeg')) |
|
|
|
.toBe(FileAppearanceTypeEnum.video) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('webm') |
|
|
|
expect(getFileAppearanceType('video.web', 'video/webm')) |
|
|
|
.toBe(FileAppearanceTypeEnum.video) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify audio files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mp3') |
|
|
|
expect(getFileAppearanceType('audio.mp3', 'audio/mpeg')) |
|
|
|
.toBe(FileAppearanceTypeEnum.audio) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('m4a') |
|
|
|
expect(getFileAppearanceType('audio.m4a', 'audio/mp4')) |
|
|
|
.toBe(FileAppearanceTypeEnum.audio) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('wav') |
|
|
|
expect(getFileAppearanceType('audio.wav', 'audio/vnd.wav')) |
|
|
|
.toBe(FileAppearanceTypeEnum.audio) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('amr') |
|
|
|
expect(getFileAppearanceType('audio.amr', 'audio/AMR')) |
|
|
|
.toBe(FileAppearanceTypeEnum.audio) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mpga') |
|
|
|
expect(getFileAppearanceType('audio.mpga', 'audio/mpeg')) |
|
|
|
.toBe(FileAppearanceTypeEnum.audio) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify code files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('html') |
|
|
|
expect(getFileAppearanceType('index.html', 'text/html')) |
|
|
|
.toBe(FileAppearanceTypeEnum.code) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify PDF files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('pdf') |
|
|
|
expect(getFileAppearanceType('doc.pdf', 'application/pdf')) |
|
|
|
.toBe(FileAppearanceTypeEnum.pdf) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify markdown files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('md') |
|
|
|
expect(getFileAppearanceType('file.md', 'text/markdown')) |
|
|
|
.toBe(FileAppearanceTypeEnum.markdown) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('markdown') |
|
|
|
expect(getFileAppearanceType('file.markdown', 'text/markdown')) |
|
|
|
.toBe(FileAppearanceTypeEnum.markdown) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('mdx') |
|
|
|
expect(getFileAppearanceType('file.mdx', 'text/mdx')) |
|
|
|
.toBe(FileAppearanceTypeEnum.markdown) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify excel files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('xlsx') |
|
|
|
expect(getFileAppearanceType('doc.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) |
|
|
|
.toBe(FileAppearanceTypeEnum.excel) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('xls') |
|
|
|
expect(getFileAppearanceType('doc.xls', 'application/vnd.ms-excel')) |
|
|
|
.toBe(FileAppearanceTypeEnum.excel) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify word files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('doc') |
|
|
|
expect(getFileAppearanceType('doc.doc', 'application/msword')) |
|
|
|
.toBe(FileAppearanceTypeEnum.word) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('docx') |
|
|
|
expect(getFileAppearanceType('doc.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')) |
|
|
|
.toBe(FileAppearanceTypeEnum.word) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify word files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('ppt') |
|
|
|
expect(getFileAppearanceType('doc.ppt', 'application/vnd.ms-powerpoint')) |
|
|
|
.toBe(FileAppearanceTypeEnum.ppt) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('pptx') |
|
|
|
expect(getFileAppearanceType('doc.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation')) |
|
|
|
.toBe(FileAppearanceTypeEnum.ppt) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify document files', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('txt') |
|
|
|
expect(getFileAppearanceType('file.txt', 'text/plain')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('csv') |
|
|
|
expect(getFileAppearanceType('file.csv', 'text/csv')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('msg') |
|
|
|
expect(getFileAppearanceType('file.msg', 'application/vnd.ms-outlook')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('eml') |
|
|
|
expect(getFileAppearanceType('file.eml', 'message/rfc822')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('xml') |
|
|
|
expect(getFileAppearanceType('file.xml', 'application/rssxml')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
|
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('epub') |
|
|
|
expect(getFileAppearanceType('file.epub', 'application/epubzip')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should handle null mime extension', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue(null) |
|
|
|
expect(getFileAppearanceType('file.txt', 'text/plain')) |
|
|
|
.toBe(FileAppearanceTypeEnum.document) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getSupportFileType', () => { |
|
|
|
it('should return custom type when isCustom is true', () => { |
|
|
|
expect(getSupportFileType('file.txt', '', true)) |
|
|
|
.toBe(SupportUploadFileTypes.custom) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should return file type when isCustom is false', () => { |
|
|
|
expect(getSupportFileType('file.txt', 'text/plain')) |
|
|
|
.toBe(SupportUploadFileTypes.document) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getProcessedFiles', () => { |
|
|
|
it('should process files correctly', () => { |
|
|
|
const files = [{ |
|
|
|
id: '123', |
|
|
|
name: 'test.txt', |
|
|
|
size: 1024, |
|
|
|
type: 'text/plain', |
|
|
|
progress: 100, |
|
|
|
supportFileType: 'document', |
|
|
|
transferMethod: TransferMethod.remote_url, |
|
|
|
url: 'http://example.com', |
|
|
|
uploadedId: '123', |
|
|
|
}] |
|
|
|
|
|
|
|
const result = getProcessedFiles(files) |
|
|
|
expect(result[0]).toEqual({ |
|
|
|
type: 'document', |
|
|
|
transfer_method: TransferMethod.remote_url, |
|
|
|
url: 'http://example.com', |
|
|
|
upload_file_id: '123', |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getProcessedFilesFromResponse', () => { |
|
|
|
it('should process files correctly', () => { |
|
|
|
const files = [{ |
|
|
|
related_id: '2a38e2ca-1295-415d-a51d-65d4ff9912d9', |
|
|
|
extension: '.jpeg', |
|
|
|
filename: 'test.jpeg', |
|
|
|
size: 2881761, |
|
|
|
mime_type: 'image/jpeg', |
|
|
|
transfer_method: TransferMethod.local_file, |
|
|
|
type: 'image', |
|
|
|
url: 'https://upload.dify.dev/files/xxx/file-preview', |
|
|
|
}] |
|
|
|
|
|
|
|
const result = getProcessedFilesFromResponse(files) |
|
|
|
expect(result[0]).toEqual({ |
|
|
|
id: '2a38e2ca-1295-415d-a51d-65d4ff9912d9', |
|
|
|
name: 'test.jpeg', |
|
|
|
size: 2881761, |
|
|
|
type: 'image/jpeg', |
|
|
|
progress: 100, |
|
|
|
transferMethod: TransferMethod.local_file, |
|
|
|
supportFileType: 'image', |
|
|
|
uploadedId: '2a38e2ca-1295-415d-a51d-65d4ff9912d9', |
|
|
|
url: 'https://upload.dify.dev/files/xxx/file-preview', |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getFileNameFromUrl', () => { |
|
|
|
it('should extract filename from URL', () => { |
|
|
|
expect(getFileNameFromUrl('http://example.com/path/file.txt')) |
|
|
|
.toBe('file.txt') |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getSupportFileExtensionList', () => { |
|
|
|
it('should handle custom file types', () => { |
|
|
|
const result = getSupportFileExtensionList( |
|
|
|
[SupportUploadFileTypes.custom], |
|
|
|
['.pdf', '.txt', '.doc'], |
|
|
|
) |
|
|
|
expect(result).toEqual(['PDF', 'TXT', 'DOC']) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should handle standard file types', () => { |
|
|
|
const mockFileExts = { |
|
|
|
image: ['JPG', 'PNG'], |
|
|
|
document: ['PDF', 'TXT'], |
|
|
|
video: ['MP4', 'MOV'], |
|
|
|
} |
|
|
|
|
|
|
|
// Temporarily mock FILE_EXTS |
|
|
|
const originalFileExts = { ...FILE_EXTS } |
|
|
|
Object.assign(FILE_EXTS, mockFileExts) |
|
|
|
|
|
|
|
const result = getSupportFileExtensionList( |
|
|
|
['image', 'document'], |
|
|
|
[], |
|
|
|
) |
|
|
|
expect(result).toEqual(['JPG', 'PNG', 'PDF', 'TXT']) |
|
|
|
|
|
|
|
// Restore original FILE_EXTS |
|
|
|
Object.assign(FILE_EXTS, originalFileExts) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should return empty array for empty inputs', () => { |
|
|
|
const result = getSupportFileExtensionList([], []) |
|
|
|
expect(result).toEqual([]) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should prioritize custom types over standard types', () => { |
|
|
|
const mockFileExts = { |
|
|
|
image: ['JPG', 'PNG'], |
|
|
|
} |
|
|
|
|
|
|
|
// Temporarily mock FILE_EXTS |
|
|
|
const originalFileExts = { ...FILE_EXTS } |
|
|
|
Object.assign(FILE_EXTS, mockFileExts) |
|
|
|
|
|
|
|
const result = getSupportFileExtensionList( |
|
|
|
[SupportUploadFileTypes.custom, 'image'], |
|
|
|
['.csv', '.xml'], |
|
|
|
) |
|
|
|
expect(result).toEqual(['CSV', 'XML']) |
|
|
|
|
|
|
|
// Restore original FILE_EXTS |
|
|
|
Object.assign(FILE_EXTS, originalFileExts) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('isAllowedFileExtension', () => { |
|
|
|
it('should validate allowed file extensions', () => { |
|
|
|
jest.mocked(mime.getExtension).mockReturnValue('pdf') |
|
|
|
expect(isAllowedFileExtension( |
|
|
|
'test.pdf', |
|
|
|
'application/pdf', |
|
|
|
['document'], |
|
|
|
['.pdf'], |
|
|
|
)).toBe(true) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('getFilesInLogs', () => { |
|
|
|
const mockFileData = { |
|
|
|
dify_model_identity: '__dify__file__', |
|
|
|
related_id: '123', |
|
|
|
filename: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
mime_type: 'application/pdf', |
|
|
|
transfer_method: 'local_file', |
|
|
|
type: 'document', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
} |
|
|
|
|
|
|
|
it('should handle empty or null input', () => { |
|
|
|
expect(getFilesInLogs(null)).toEqual([]) |
|
|
|
expect(getFilesInLogs({})).toEqual([]) |
|
|
|
expect(getFilesInLogs(undefined)).toEqual([]) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should process single file object', () => { |
|
|
|
const input = { |
|
|
|
file1: mockFileData, |
|
|
|
} |
|
|
|
|
|
|
|
const expected = [{ |
|
|
|
varName: 'file1', |
|
|
|
list: [{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}], |
|
|
|
}] |
|
|
|
|
|
|
|
expect(getFilesInLogs(input)).toEqual(expected) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should process array of files', () => { |
|
|
|
const input = { |
|
|
|
files: [mockFileData, mockFileData], |
|
|
|
} |
|
|
|
|
|
|
|
const expected = [{ |
|
|
|
varName: 'files', |
|
|
|
list: [ |
|
|
|
{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}, |
|
|
|
], |
|
|
|
}] |
|
|
|
|
|
|
|
expect(getFilesInLogs(input)).toEqual(expected) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should ignore non-file objects and arrays', () => { |
|
|
|
const input = { |
|
|
|
regularString: 'not a file', |
|
|
|
regularNumber: 123, |
|
|
|
regularArray: [1, 2, 3], |
|
|
|
regularObject: { key: 'value' }, |
|
|
|
file: mockFileData, |
|
|
|
} |
|
|
|
|
|
|
|
const expected = [{ |
|
|
|
varName: 'file', |
|
|
|
list: [{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}], |
|
|
|
}] |
|
|
|
|
|
|
|
expect(getFilesInLogs(input)).toEqual(expected) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should handle mixed file types in array', () => { |
|
|
|
const input = { |
|
|
|
mixedFiles: [ |
|
|
|
mockFileData, |
|
|
|
{ notAFile: true }, |
|
|
|
mockFileData, |
|
|
|
], |
|
|
|
} |
|
|
|
|
|
|
|
const expected = [{ |
|
|
|
varName: 'mixedFiles', |
|
|
|
list: [ |
|
|
|
{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: undefined, |
|
|
|
name: undefined, |
|
|
|
progress: 100, |
|
|
|
size: 0, |
|
|
|
supportFileType: undefined, |
|
|
|
transferMethod: undefined, |
|
|
|
type: undefined, |
|
|
|
uploadedId: undefined, |
|
|
|
url: undefined, |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: '123', |
|
|
|
name: 'test.pdf', |
|
|
|
size: 1024, |
|
|
|
type: 'application/pdf', |
|
|
|
progress: 100, |
|
|
|
transferMethod: 'local_file', |
|
|
|
supportFileType: 'document', |
|
|
|
uploadedId: '123', |
|
|
|
url: 'http://example.com/test.pdf', |
|
|
|
}, |
|
|
|
], |
|
|
|
}] |
|
|
|
|
|
|
|
expect(getFilesInLogs(input)).toEqual(expected) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('fileIsUploaded', () => { |
|
|
|
it('should identify uploaded files', () => { |
|
|
|
expect(fileIsUploaded({ |
|
|
|
uploadedId: '123', |
|
|
|
progress: 100, |
|
|
|
} as any)).toBe(true) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should identify remote files as uploaded', () => { |
|
|
|
expect(fileIsUploaded({ |
|
|
|
transferMethod: TransferMethod.remote_url, |
|
|
|
progress: 100, |
|
|
|
} as any)).toBe(true) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
describe('downloadFile', () => { |
|
|
|
let mockAnchor: HTMLAnchorElement |
|
|
|
let createElementMock: jest.SpyInstance |
|
|
|
let appendChildMock: jest.SpyInstance |
|
|
|
let removeChildMock: jest.SpyInstance |
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
// Mock createElement and appendChild |
|
|
|
mockAnchor = { |
|
|
|
href: '', |
|
|
|
download: '', |
|
|
|
style: { display: '' }, |
|
|
|
target: '', |
|
|
|
title: '', |
|
|
|
click: jest.fn(), |
|
|
|
} as unknown as HTMLAnchorElement |
|
|
|
|
|
|
|
createElementMock = jest.spyOn(document, 'createElement').mockReturnValue(mockAnchor as any) |
|
|
|
appendChildMock = jest.spyOn(document.body, 'appendChild').mockImplementation((node: Node) => { |
|
|
|
return node |
|
|
|
}) |
|
|
|
removeChildMock = jest.spyOn(document.body, 'removeChild').mockImplementation((node: Node) => { |
|
|
|
return node |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
jest.resetAllMocks() |
|
|
|
}) |
|
|
|
|
|
|
|
it('should create and trigger download with correct attributes', () => { |
|
|
|
const url = 'https://example.com/test.pdf' |
|
|
|
const filename = 'test.pdf' |
|
|
|
|
|
|
|
downloadFile(url, filename) |
|
|
|
|
|
|
|
// Verify anchor element was created with correct properties |
|
|
|
expect(createElementMock).toHaveBeenCalledWith('a') |
|
|
|
expect(mockAnchor.href).toBe(url) |
|
|
|
expect(mockAnchor.download).toBe(filename) |
|
|
|
expect(mockAnchor.style.display).toBe('none') |
|
|
|
expect(mockAnchor.target).toBe('_blank') |
|
|
|
expect(mockAnchor.title).toBe(filename) |
|
|
|
|
|
|
|
// Verify DOM operations |
|
|
|
expect(appendChildMock).toHaveBeenCalledWith(mockAnchor) |
|
|
|
expect(mockAnchor.click).toHaveBeenCalled() |
|
|
|
expect(removeChildMock).toHaveBeenCalledWith(mockAnchor) |
|
|
|
}) |
|
|
|
|
|
|
|
it('should handle empty filename', () => { |
|
|
|
const url = 'https://example.com/test.pdf' |
|
|
|
const filename = '' |
|
|
|
|
|
|
|
downloadFile(url, filename) |
|
|
|
|
|
|
|
expect(mockAnchor.download).toBe('') |
|
|
|
expect(mockAnchor.title).toBe('') |
|
|
|
}) |
|
|
|
|
|
|
|
it('should handle empty url', () => { |
|
|
|
const url = '' |
|
|
|
const filename = 'test.pdf' |
|
|
|
|
|
|
|
downloadFile(url, filename) |
|
|
|
|
|
|
|
expect(mockAnchor.href).toBe('') |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |