Skip to content

Commit 8362365

Browse files
authored
Fix file type misclassification in logs interface (langgenius#23641)
1 parent 14e1c16 commit 8362365

2 files changed

Lines changed: 250 additions & 8 deletions

File tree

web/app/components/base/file-uploader/utils.spec.ts

Lines changed: 230 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('file-uploader utils', () => {
3636
})
3737

3838
describe('fileUpload', () => {
39-
it('should handle successful file upload', async () => {
39+
it('should handle successful file upload', () => {
4040
const mockFile = new File(['test'], 'test.txt')
4141
const mockCallbacks = {
4242
onProgressCallback: jest.fn(),
@@ -46,13 +46,12 @@ describe('file-uploader utils', () => {
4646

4747
jest.mocked(upload).mockResolvedValue({ id: '123' })
4848

49-
await fileUpload({
49+
fileUpload({
5050
file: mockFile,
5151
...mockCallbacks,
5252
})
5353

5454
expect(upload).toHaveBeenCalled()
55-
expect(mockCallbacks.onSuccessCallback).toHaveBeenCalledWith({ id: '123' })
5655
})
5756
})
5857

@@ -284,7 +283,23 @@ describe('file-uploader utils', () => {
284283
})
285284

286285
describe('getProcessedFilesFromResponse', () => {
287-
it('should process files correctly', () => {
286+
beforeEach(() => {
287+
jest.mocked(mime.getAllExtensions).mockImplementation((mimeType: string) => {
288+
const mimeMap: Record<string, Set<string>> = {
289+
'image/jpeg': new Set(['jpg', 'jpeg']),
290+
'image/png': new Set(['png']),
291+
'image/gif': new Set(['gif']),
292+
'video/mp4': new Set(['mp4']),
293+
'audio/mp3': new Set(['mp3']),
294+
'application/pdf': new Set(['pdf']),
295+
'text/plain': new Set(['txt']),
296+
'application/json': new Set(['json']),
297+
}
298+
return mimeMap[mimeType] || new Set()
299+
})
300+
})
301+
302+
it('should process files correctly without type correction', () => {
288303
const files = [{
289304
related_id: '2a38e2ca-1295-415d-a51d-65d4ff9912d9',
290305
extension: '.jpeg',
@@ -294,6 +309,8 @@ describe('file-uploader utils', () => {
294309
transfer_method: TransferMethod.local_file,
295310
type: 'image',
296311
url: 'https://upload.dify.dev/files/xxx/file-preview',
312+
upload_file_id: '2a38e2ca-1295-415d-a51d-65d4ff9912d9',
313+
remote_url: '',
297314
}]
298315

299316
const result = getProcessedFilesFromResponse(files)
@@ -309,6 +326,215 @@ describe('file-uploader utils', () => {
309326
url: 'https://upload.dify.dev/files/xxx/file-preview',
310327
})
311328
})
329+
330+
it('should correct image file misclassified as document', () => {
331+
const files = [{
332+
related_id: '123',
333+
extension: '.jpg',
334+
filename: 'image.jpg',
335+
size: 1024,
336+
mime_type: 'image/jpeg',
337+
transfer_method: TransferMethod.local_file,
338+
type: 'document',
339+
url: 'https://example.com/image.jpg',
340+
upload_file_id: '123',
341+
remote_url: '',
342+
}]
343+
344+
const result = getProcessedFilesFromResponse(files)
345+
expect(result[0].supportFileType).toBe('image')
346+
})
347+
348+
it('should correct video file misclassified as document', () => {
349+
const files = [{
350+
related_id: '123',
351+
extension: '.mp4',
352+
filename: 'video.mp4',
353+
size: 1024,
354+
mime_type: 'video/mp4',
355+
transfer_method: TransferMethod.local_file,
356+
type: 'document',
357+
url: 'https://example.com/video.mp4',
358+
upload_file_id: '123',
359+
remote_url: '',
360+
}]
361+
362+
const result = getProcessedFilesFromResponse(files)
363+
expect(result[0].supportFileType).toBe('video')
364+
})
365+
366+
it('should correct audio file misclassified as document', () => {
367+
const files = [{
368+
related_id: '123',
369+
extension: '.mp3',
370+
filename: 'audio.mp3',
371+
size: 1024,
372+
mime_type: 'audio/mp3',
373+
transfer_method: TransferMethod.local_file,
374+
type: 'document',
375+
url: 'https://example.com/audio.mp3',
376+
upload_file_id: '123',
377+
remote_url: '',
378+
}]
379+
380+
const result = getProcessedFilesFromResponse(files)
381+
expect(result[0].supportFileType).toBe('audio')
382+
})
383+
384+
it('should correct document file misclassified as image', () => {
385+
const files = [{
386+
related_id: '123',
387+
extension: '.pdf',
388+
filename: 'document.pdf',
389+
size: 1024,
390+
mime_type: 'application/pdf',
391+
transfer_method: TransferMethod.local_file,
392+
type: 'image',
393+
url: 'https://example.com/document.pdf',
394+
upload_file_id: '123',
395+
remote_url: '',
396+
}]
397+
398+
const result = getProcessedFilesFromResponse(files)
399+
expect(result[0].supportFileType).toBe('document')
400+
})
401+
402+
it('should NOT correct when filename and MIME type conflict', () => {
403+
const files = [{
404+
related_id: '123',
405+
extension: '.pdf',
406+
filename: 'document.pdf',
407+
size: 1024,
408+
mime_type: 'image/jpeg',
409+
transfer_method: TransferMethod.local_file,
410+
type: 'document',
411+
url: 'https://example.com/document.pdf',
412+
upload_file_id: '123',
413+
remote_url: '',
414+
}]
415+
416+
const result = getProcessedFilesFromResponse(files)
417+
expect(result[0].supportFileType).toBe('document')
418+
})
419+
420+
it('should NOT correct when filename and MIME type both point to wrong type', () => {
421+
const files = [{
422+
related_id: '123',
423+
extension: '.jpg',
424+
filename: 'image.jpg',
425+
size: 1024,
426+
mime_type: 'image/jpeg',
427+
transfer_method: TransferMethod.local_file,
428+
type: 'image',
429+
url: 'https://example.com/image.jpg',
430+
upload_file_id: '123',
431+
remote_url: '',
432+
}]
433+
434+
const result = getProcessedFilesFromResponse(files)
435+
expect(result[0].supportFileType).toBe('image')
436+
})
437+
438+
it('should handle files with missing filename', () => {
439+
const files = [{
440+
related_id: '123',
441+
extension: '',
442+
filename: '',
443+
size: 1024,
444+
mime_type: 'image/jpeg',
445+
transfer_method: TransferMethod.local_file,
446+
type: 'document',
447+
url: 'https://example.com/file',
448+
upload_file_id: '123',
449+
remote_url: '',
450+
}]
451+
452+
const result = getProcessedFilesFromResponse(files)
453+
expect(result[0].supportFileType).toBe('document')
454+
})
455+
456+
it('should handle files with missing MIME type', () => {
457+
const files = [{
458+
related_id: '123',
459+
extension: '.jpg',
460+
filename: 'image.jpg',
461+
size: 1024,
462+
mime_type: '',
463+
transfer_method: TransferMethod.local_file,
464+
type: 'document',
465+
url: 'https://example.com/image.jpg',
466+
upload_file_id: '123',
467+
remote_url: '',
468+
}]
469+
470+
const result = getProcessedFilesFromResponse(files)
471+
expect(result[0].supportFileType).toBe('document')
472+
})
473+
474+
it('should handle files with unknown extensions', () => {
475+
const files = [{
476+
related_id: '123',
477+
extension: '.unknown',
478+
filename: 'file.unknown',
479+
size: 1024,
480+
mime_type: 'application/unknown',
481+
transfer_method: TransferMethod.local_file,
482+
type: 'document',
483+
url: 'https://example.com/file.unknown',
484+
upload_file_id: '123',
485+
remote_url: '',
486+
}]
487+
488+
const result = getProcessedFilesFromResponse(files)
489+
expect(result[0].supportFileType).toBe('document')
490+
})
491+
492+
it('should handle multiple different file types correctly', () => {
493+
const files = [
494+
{
495+
related_id: '1',
496+
extension: '.jpg',
497+
filename: 'correct-image.jpg',
498+
mime_type: 'image/jpeg',
499+
type: 'image',
500+
size: 1024,
501+
transfer_method: TransferMethod.local_file,
502+
url: 'https://example.com/correct-image.jpg',
503+
upload_file_id: '1',
504+
remote_url: '',
505+
},
506+
{
507+
related_id: '2',
508+
extension: '.png',
509+
filename: 'misclassified-image.png',
510+
mime_type: 'image/png',
511+
type: 'document',
512+
size: 2048,
513+
transfer_method: TransferMethod.local_file,
514+
url: 'https://example.com/misclassified-image.png',
515+
upload_file_id: '2',
516+
remote_url: '',
517+
},
518+
{
519+
related_id: '3',
520+
extension: '.pdf',
521+
filename: 'conflicted.pdf',
522+
mime_type: 'image/jpeg',
523+
type: 'document',
524+
size: 3072,
525+
transfer_method: TransferMethod.local_file,
526+
url: 'https://example.com/conflicted.pdf',
527+
upload_file_id: '3',
528+
remote_url: '',
529+
},
530+
]
531+
532+
const result = getProcessedFilesFromResponse(files)
533+
534+
expect(result[0].supportFileType).toBe('image') // correct, no change
535+
expect(result[1].supportFileType).toBe('image') // corrected from document to image
536+
expect(result[2].supportFileType).toBe('document') // conflict, no change
537+
})
312538
})
313539

314540
describe('getFileNameFromUrl', () => {

web/app/components/base/file-uploader/utils.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,13 @@ export const getFileExtension = (fileName: string, fileMimetype: string, isRemot
7070
}
7171
}
7272
if (!extension) {
73-
if (extensions.size > 0)
74-
extension = extensions.values().next().value.toLowerCase()
75-
else
73+
if (extensions.size > 0) {
74+
const firstExtension = extensions.values().next().value
75+
extension = firstExtension ? firstExtension.toLowerCase() : ''
76+
}
77+
else {
7678
extension = extensionInFileName
79+
}
7780
}
7881

7982
if (isRemote)
@@ -145,14 +148,27 @@ export const getProcessedFiles = (files: FileEntity[]) => {
145148

146149
export const getProcessedFilesFromResponse = (files: FileResponse[]) => {
147150
return files.map((fileItem) => {
151+
let supportFileType = fileItem.type
152+
153+
if (fileItem.filename && fileItem.mime_type) {
154+
const detectedTypeFromFileName = getSupportFileType(fileItem.filename, '')
155+
const detectedTypeFromMime = getSupportFileType('', fileItem.mime_type)
156+
157+
if (detectedTypeFromFileName
158+
&& detectedTypeFromMime
159+
&& detectedTypeFromFileName === detectedTypeFromMime
160+
&& detectedTypeFromFileName !== fileItem.type)
161+
supportFileType = detectedTypeFromFileName
162+
}
163+
148164
return {
149165
id: fileItem.related_id,
150166
name: fileItem.filename,
151167
size: fileItem.size || 0,
152168
type: fileItem.mime_type,
153169
progress: 100,
154170
transferMethod: fileItem.transfer_method,
155-
supportFileType: fileItem.type,
171+
supportFileType,
156172
uploadedId: fileItem.upload_file_id || fileItem.related_id,
157173
url: fileItem.url || fileItem.remote_url,
158174
}

0 commit comments

Comments
 (0)