Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTL migration: file inputs #590

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ module.exports = {
node: false,
'shared-node-browser': true,
},
globals: {
File: true,
},
}
97 changes: 50 additions & 47 deletions test/forms/inputs/cloudinary-file-input.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react'
import { mount } from 'enzyme'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { CloudinaryFileInput } from '../../../src/'
import { mockFileReader, flushPromises } from './file-input.test'
import { act } from 'react-dom/test-utils'

const name = 'name.of.field'
const value = { name: 'existingFileName', url: 'value of field' }
Expand All @@ -22,10 +21,6 @@ jest.mock(
// These tests rely on the mock implementation of cloudinaryUploader in __mocks__,
// which just passes all props through to its child.

beforeEach(() => {
jest.clearAllMocks()
})

test('CloudinaryFileInput adds uploadStatus to className', () => {
const className = 'foo'
const props = {
Expand All @@ -37,64 +32,68 @@ test('CloudinaryFileInput adds uploadStatus to className', () => {
cloudName,
bucket,
}
const wrapper = mount(<CloudinaryFileInput {...props} />)
expect(wrapper.find('fieldset.foo.upload-success').exists()).toEqual(true)
render(<CloudinaryFileInput {...props} />)

const fieldset = screen.getByRole('group')
expect(fieldset).toHaveClass(className)
expect(fieldset).toHaveClass(uploadStatus)
})

test('CloudinaryFileInput sets returned url within value', async () => {
const fakeFileEvent = {
target: { files: [{ name: 'fileName', type: 'image/png' }] },
}
mockFileReader('data')
const file = new File(['content'], 'fileName.png', { type: 'image/png' })
const onChange = jest.fn()
const props = {
input: { ...input, onChange },
input: { name, value, onChange },
meta: {},
upload,
uploadStatus,
cloudName,
bucket,
}
const wrapper = mount(<CloudinaryFileInput {...props} />)
const internalOnChange = wrapper.find('input').prop('onChange')
// internally calls upload, which resolves with file
internalOnChange(fakeFileEvent)

await flushPromises()
expect(onChange).toHaveBeenCalled()
expect(onChange.mock.calls[0][0][0].url).toBe(PUBLIC_URL)

render(<CloudinaryFileInput {...props} />)

const user = userEvent.setup()
const input = screen.getByLabelText(/select file/i)

await user.upload(input, file)

expect(onChange).toHaveBeenCalledWith([
expect.objectContaining({ url: PUBLIC_URL }),
])
})

test('CloudinaryFileInput calls success handler with response on successful upload of a single file', async () => {
const fakeFileEvent = { target: { files: [{ name: 'fileName' }] } }
const file = new File(['content'], 'fileName.png', { type: 'image/png' })
const onUploadSuccess = jest.fn()
mockFileReader()

const props = {
input: { ...input, onChange: jest.fn() },
input: { name, value, onChange: jest.fn() },
meta: {},
upload,
uploadStatus,
cloudName,
bucket,
onUploadSuccess,
}
const wrapper = mount(<CloudinaryFileInput {...props} />)
const internalOnChange = wrapper.find('input').prop('onChange')
internalOnChange(fakeFileEvent)

await flushPromises()
expect(onUploadSuccess).toHaveBeenCalled()
expect(onUploadSuccess.mock.calls[0][0].url).toBe(PUBLIC_URL)
render(<CloudinaryFileInput {...props} />)

const user = userEvent.setup()
const input = screen.getByLabelText(/select file/i)
await user.upload(input, file)

expect(onUploadSuccess).toHaveBeenCalledWith(
expect.objectContaining({ url: PUBLIC_URL })
)
})

test('CloudinaryFileInput calls success handler with array of responses on successful uploads of multiple files', async () => {
const fakeFileEvent = { target: { files: [{ name: 'fileName' }] } }
const file = new File(['content'], 'fileName.png', { type: 'image/png' })
const onUploadSuccess = jest.fn()
mockFileReader()

const props = {
input: { ...input, onChange: jest.fn() },
input: { name, value, onChange: jest.fn() },
meta: {},
upload,
uploadStatus,
Expand All @@ -103,35 +102,39 @@ test('CloudinaryFileInput calls success handler with array of responses on succe
onUploadSuccess,
multiple: true,
}
const wrapper = mount(<CloudinaryFileInput {...props} />)
const internalOnChange = wrapper.find('input').prop('onChange')
internalOnChange(fakeFileEvent)

await flushPromises()
expect(onUploadSuccess).toHaveBeenCalled()
expect(onUploadSuccess.mock.calls[0][0][0].url).toBe(PUBLIC_URL)
render(<CloudinaryFileInput {...props} />)

const user = userEvent.setup()
const input = screen.getByLabelText(/select file/i)
await user.upload(input, file)

expect(onUploadSuccess).toHaveBeenCalledWith([
expect.objectContaining({ url: PUBLIC_URL }),
])
})

test('CloudinaryFileInput calls error handler with error on failed upload', async () => {
const fakeFileEvent = { target: { files: [{}] } }
const file = new File(['content'], '*&^*^(*&', { type: 'image/png' })
const onUploadFailure = jest.fn()
const failureResponse = { errors: 'Invalid filename' }
const upload = () => Promise.reject(failureResponse)
mockFileReader()

const props = {
input: { ...input, onChange: jest.fn() },
input: { name, value: '', onChange: jest.fn() },
meta: {},
upload,
uploadStatus,
cloudName,
bucket,
onUploadFailure,
}
const wrapper = mount(<CloudinaryFileInput {...props} />)
const internalOnChange = wrapper.find('input').prop('onChange')

// Ensure that any state changes have occurred before asserting (e.g., setErrors(e))
await act(() => internalOnChange(fakeFileEvent))
render(<CloudinaryFileInput {...props} />)

const user = userEvent.setup()
const input = screen.getByLabelText(/select file/i)
await user.upload(input, file)

expect(onUploadFailure).toHaveBeenCalledWith(failureResponse)
})
Loading