From b3c4cf14dc46716b9aeaa3053b3e6d69b686290f Mon Sep 17 00:00:00 2001 From: Laura Beatris <48022589+LauraBeatris@users.noreply.github.com> Date: Thu, 18 Feb 2021 19:51:40 -0300 Subject: [PATCH] perf(upload): handle higher range of mime types --- src/__tests__/upload.js | 42 ++++++++++++++++++++++++++++++++--------- src/upload.js | 20 +++++++++++++++++--- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/__tests__/upload.js b/src/__tests__/upload.js index bb6a64eeb..f8879e1d1 100644 --- a/src/__tests__/upload.js +++ b/src/__tests__/upload.js @@ -164,31 +164,55 @@ test('should call onChange/input bubbling up the event when a file is selected', expect(onInputForm).toHaveBeenCalledTimes(1) }) -test('should not upload file with invalid unaccepted format', () => { +test('should upload file with accepted format', () => { const file = new File(['hello'], 'hello.png', {type: 'image/png'}) + const {element} = setup('') + userEvent.upload(element, file) + + expect(element.files).toHaveLength(1) +}) + +test('should upload multiple files with accepted format', () => { + const files = [ + new File(['hello'], 'hello.png', {type: 'image/png'}), + new File(['there'], 'there.jpg', {type: 'audio/mp3'}), + new File(['there'], 'there.csv', {type: 'text/csv'}), + new File(['there'], 'there.jpg', {type: 'video/mp4'}), + ] + const {element} = setup(` + + `) + + userEvent.upload(element, files) + + expect(element.files).toHaveLength(3) +}) + +test('should not upload file with unaccepted format', () => { + const file = new File(['hello'], 'hello.png', {type: 'image/png'}) const {element} = setup('') userEvent.upload(element, file) - expect(element.files[0]).toBeUndefined() - expect(element.files.item(0)).toBeNull() expect(element.files).toHaveLength(0) }) -test('should not upload multiple files with invalid unaccepted formats', () => { +test('should not upload multiple files with unaccepted formats', () => { const files = [ new File(['hello'], 'hello.txt', {type: 'text/plain'}), new File(['there'], 'there.pdf', {type: 'application/pdf'}), + new File(['there'], 'there.png', {type: 'image/png'}), + new File(['there'], 'there.mp4', {type: 'video/mp4'}), ] - const {element} = setup(` - + `) userEvent.upload(element, files) - expect(element.files[0]).toBeUndefined() - expect(element.files.item(0)).toBeNull() - expect(element.files).toHaveLength(0) + expect(element.files).toHaveLength(1) }) diff --git a/src/upload.js b/src/upload.js index a0972f278..58dd39250 100644 --- a/src/upload.js +++ b/src/upload.js @@ -3,11 +3,26 @@ import {click} from './click' import {blur} from './blur' import {focus} from './focus' +const isValidFileType = (acceptAttribute, type) => { + const acceptManyExtensions = /(video|audio|image)\/?\*/.test(acceptAttribute) + + console.log({acceptAttribute, type, acceptManyExtensions}) + + if (!acceptManyExtensions) { + return acceptAttribute.includes(type) + } + + const fileMimeType = type.match(/\w+\/+/g) + const isValidMimeType = acceptAttribute.includes(fileMimeType) + + return isValidMimeType +} + function upload(element, fileOrFiles, init) { const hasFileWithInvalidType = !Array.isArray(fileOrFiles) && Boolean(element.accept) && - !element.accept.includes(fileOrFiles.type) + !isValidFileType(element.accept, fileOrFiles.type) if (hasFileWithInvalidType || element.disabled) return @@ -19,14 +34,13 @@ function upload(element, fileOrFiles, init) { if (Array.isArray(fileOrFiles)) { files = element.accept - ? fileOrFiles.filter(file => element.accept.includes(file.type)) + ? fileOrFiles.filter(file => isValidFileType(element.accept, file.type)) : fileOrFiles } else { files = [fileOrFiles] } const hasFilesWithInvalidTypes = files.length === 0 - if (hasFilesWithInvalidTypes) return files = files.slice(0, input.multiple ? undefined : 1)