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)