Skip to content
38 changes: 38 additions & 0 deletions src/__tests__/fire-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ const eventTypes = [
elementType: 'div',
},
]

const mockFile = ({
name,
size = 0,
type = 'text/plain',
lastModified = new Date(),
}) => {
const blob = new Blob(['0'.repeat(size)], {type})
blob.lastModifiedDate = lastModified
return new File([blob], name)
}

beforeEach(() => {
jest.spyOn(console, 'warn').mockImplementation(() => {})
})
Expand Down Expand Up @@ -215,6 +227,32 @@ test('fireEvent.update does not trigger warning messages', async () => {
expect(console.warn).not.toHaveBeenCalled()
})

test('fireEvent.update should not crash with input file', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test example not enough? @afontcu

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is! But as mentioned, I wouldn't make fireEvent.update() smarter when it comes to type="file" inputs. I would just trigger the proper event, and then add a test showcasing how to handle files as in React Testing Library (and probably also a comment suggesting userEvent to do so:

test('fireEvent.update should not crash with input file', async () => {
  const {getByTestId} = render({
    template: `<input type="file" data-testid="test-update" />`
  })

  const file = new File(['(⌐□_□)'], 'chucknorris.png', { type: 'image/png' })

  const inputEl = getByTestId('test-update')

  Object.defineProperty(inputEl, 'files', {
    value: [file],
  })

  await fireEvent.update(inputEl)

  expect(console.warn).not.toHaveBeenCalled()
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a suggestion with the change I mention above 👍

const spy = jest.fn()

const {getByTestId} = render({
render(h) {
return h('input', {
on: {
change: spy,
},
attrs: {
type: 'file',
'data-testid': 'test-update',
},
})
},
})

// should expect an array of list since it's a fileList
await fireEvent.update(getByTestId('test-update'), [
mockFile({name: 'random.txt', size: 524288}),
])

expect(spy).toHaveBeenCalledTimes(1)
expect(console.warn).not.toHaveBeenCalled()
})

test('fireEvent.update does not crash if non-input element is passed in', async () => {
const {getByText} = render({
template: `<div>Hi</div>`,
Expand Down
3 changes: 3 additions & 0 deletions src/vue-testing-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ fireEvent.update = (elem, value) => {
if (['checkbox', 'radio'].includes(type)) {
elem.checked = true
return fireEvent.change(elem)
} else if (type === 'file') {
Object.defineProperty(elem, 'files', {value})
return fireEvent.change(elem)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if (type === 'file') {
Object.defineProperty(elem, 'files', {value})
return fireEvent.change(elem)
} else if (type === 'file') {
return fireEvent.change(elem)

(also not 100% sure if we should trigger a change event over an input one? 🤔 haven't checked, so it might be okay)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems pretty okay to me since we know we can't use v-model to an input file and the only reasonable event to use in this case is change.

} else {
elem.value = value
return fireEvent.input(elem)
Expand Down