Skip to content

Commit a7c715a

Browse files
committed
perf(upload): handle higher range of mime types
1 parent 831e922 commit a7c715a

File tree

2 files changed

+48
-12
lines changed

2 files changed

+48
-12
lines changed

src/__tests__/upload.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,31 +164,55 @@ test('should call onChange/input bubbling up the event when a file is selected',
164164
expect(onInputForm).toHaveBeenCalledTimes(1)
165165
})
166166

167-
test('should not upload file with invalid unaccepted format', () => {
167+
test('should upload file with accepted format', () => {
168168
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
169+
const {element} = setup('<input type="file" accept="image/png" />')
169170

171+
userEvent.upload(element, file)
172+
173+
expect(element.files).toHaveLength(1)
174+
})
175+
176+
test('should upload multiple files with accepted format', () => {
177+
const files = [
178+
new File(['hello'], 'hello.png', {type: 'image/png'}),
179+
new File(['there'], 'there.jpg', {type: 'audio/mp3'}),
180+
new File(['there'], 'there.csv', {type: 'text/csv'}),
181+
new File(['there'], 'there.jpg', {type: 'video/mp4'}),
182+
]
183+
const {element} = setup(`
184+
<input
185+
type="file"
186+
accept="image/*,audio/*,text/csv" multiple
187+
/>
188+
`)
189+
190+
userEvent.upload(element, files)
191+
192+
expect(element.files).toHaveLength(3)
193+
})
194+
195+
test('should not upload file with unaccepted format', () => {
196+
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
170197
const {element} = setup('<input type="file" accept="image/jpg" />')
171198

172199
userEvent.upload(element, file)
173200

174-
expect(element.files[0]).toBeUndefined()
175-
expect(element.files.item(0)).toBeNull()
176201
expect(element.files).toHaveLength(0)
177202
})
178203

179-
test('should not upload multiple files with invalid unaccepted formats', () => {
204+
test('should not upload multiple files with unaccepted formats', () => {
180205
const files = [
181206
new File(['hello'], 'hello.txt', {type: 'text/plain'}),
182207
new File(['there'], 'there.pdf', {type: 'application/pdf'}),
208+
new File(['there'], 'there.png', {type: 'image/png'}),
209+
new File(['there'], 'there.mp4', {type: 'video/mp4'}),
183210
]
184-
185211
const {element} = setup(`
186-
<input id="files" type="file" accept="image/jpeg,image/png" multiple />
212+
<input id="files" type="file" accept="video/*" multiple />
187213
`)
188214

189215
userEvent.upload(element, files)
190216

191-
expect(element.files[0]).toBeUndefined()
192-
expect(element.files.item(0)).toBeNull()
193-
expect(element.files).toHaveLength(0)
217+
expect(element.files).toHaveLength(1)
194218
})

src/upload.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,24 @@ import {click} from './click'
33
import {blur} from './blur'
44
import {focus} from './focus'
55

6+
const isValidFileType = (acceptAttribute, type) => {
7+
const acceptManyExtensions = /(video|audio|image)\/?\*/.test(acceptAttribute)
8+
9+
if (!acceptManyExtensions) {
10+
return acceptAttribute.includes(type)
11+
}
12+
13+
const fileMimeType = type.match(/\w+\/+/g)
14+
const isValidMimeType = acceptAttribute.includes(fileMimeType)
15+
16+
return isValidMimeType
17+
}
18+
619
function upload(element, fileOrFiles, init) {
720
const hasFileWithInvalidType =
821
!Array.isArray(fileOrFiles) &&
922
Boolean(element.accept) &&
10-
!element.accept.includes(fileOrFiles.type)
23+
!isValidFileType(element.accept, fileOrFiles.type)
1124

1225
if (hasFileWithInvalidType || element.disabled) return
1326

@@ -19,14 +32,13 @@ function upload(element, fileOrFiles, init) {
1932

2033
if (Array.isArray(fileOrFiles)) {
2134
files = element.accept
22-
? fileOrFiles.filter(file => element.accept.includes(file.type))
35+
? fileOrFiles.filter(file => isValidFileType(element.accept, file.type))
2336
: fileOrFiles
2437
} else {
2538
files = [fileOrFiles]
2639
}
2740

2841
const hasFilesWithInvalidTypes = files.length === 0
29-
3042
if (hasFilesWithInvalidTypes) return
3143

3244
files = files.slice(0, input.multiple ? undefined : 1)

0 commit comments

Comments
 (0)