Skip to content

Commit

Permalink
RTL migration: inputs (#604)
Browse files Browse the repository at this point in the history
* Migrate input

* Migrate textarea

* Remove unused import

* Migrate switch

* Remove unused import

* Migrate range-input

* Migrate select

* Migrate masked input

* Migrate replace empty string value hoc

* Migrate blur dirty

* Migrate radio group input

* Migrate cloudinary uploader

* Be more explicit

* Use toHaveAttribute

* Do not reference id directly
  • Loading branch information
chawes13 committed Aug 25, 2023
1 parent 7eec13e commit 8ecd5fb
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 221 deletions.
58 changes: 37 additions & 21 deletions test/forms/helpers/blur-dirty.test.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
import { blurDirty } from '../../../src/'
import { noop } from '../../../src/utils'
import React from 'react'
import { mount } from 'enzyme'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

const InputToWrap = ({ input: { value, onBlur }}) => (
<input value={value} onBlur={onBlur} />
)

test('has correct displayName', () => {
const MyInput = () => <input />
const WrappedInput = blurDirty()(MyInput)
expect(WrappedInput.displayName).toEqual('blurDirty(MyInput)')
const WrappedInput = blurDirty()(InputToWrap)
expect(WrappedInput.displayName).toEqual('blurDirty(InputToWrap)')
})

test('when input is pristine, blurDirty replaces onBlur with empty function', () => {
const MyInput = () => <input />
const WrappedInput = blurDirty()(MyInput)
const onBlur = () => console.log('I blurred!')
const wrapper = mount(
test('when input is pristine, blurDirty replaces onBlur with empty function', async () => {
const user = userEvent.setup()
const WrappedInput = blurDirty()(InputToWrap)
const onBlur = jest.fn()
const { container, rerender } = render(
<WrappedInput {...{ input: { onBlur }, meta: { pristine: true } }} />
)
expect(wrapper.find(MyInput).props().input.onBlur).toEqual(noop)
wrapper.setProps({ meta: { pristine: false } })
expect(wrapper.find(MyInput).props().input.onBlur).toEqual(onBlur)

await user.click(screen.getByRole('textbox'))
await user.click(container)

expect(onBlur).not.toHaveBeenCalled()

rerender(
<WrappedInput {...{ input: { onBlur }, meta: { pristine: false } }} />
)

await user.click(screen.getByRole('textbox'))
await user.click(container)

expect(onBlur).toHaveBeenCalledTimes(1)
})

test('when alwaysBlur is set to true, blurDirty does not replace onBlur', () => {
const MyInput = () => <input />
const WrappedInput = blurDirty()(MyInput)
const onBlur = () => console.log('I blurred!')
const wrapper = mount(
test('when alwaysBlur is set to true, blurDirty does not replace onBlur', async () => {
const user = userEvent.setup()
const WrappedInput = blurDirty()(InputToWrap)
const onBlur = jest.fn()
const { container } = render(
<WrappedInput
{...{ input: { onBlur }, meta: { pristine: true }, alwaysBlur: true }}
/>
)
expect(wrapper.find(MyInput).props().input.onBlur).toEqual(onBlur)
wrapper.setProps({ meta: { pristine: false } })
expect(wrapper.find(MyInput).props().input.onBlur).toEqual(onBlur)

await user.click(screen.getByRole('textbox'))
await user.click(container)

expect(onBlur).toHaveBeenCalled()
})
27 changes: 13 additions & 14 deletions test/forms/helpers/replace-empty-string-value.test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import { replaceEmptyStringValue } from '../../../src/'
import React from 'react'
import { mount } from 'enzyme'
import { render, screen } from '@testing-library/react'

const InputToWrap = ({ input: { value } }) => (
<input value={value} readOnly={true} />
)

test('has correct displayName', () => {
const MyInput = () => <input />
const WrappedInput = replaceEmptyStringValue()(MyInput)
expect(WrappedInput.displayName).toEqual('replaceEmptyStringValue(MyInput)')
const WrappedInput = replaceEmptyStringValue()(InputToWrap)
expect(WrappedInput.displayName).toEqual('replaceEmptyStringValue(InputToWrap)')
})

test('replaces empty string with given value', () => {
const MyInput = () => <input />
const WrappedInput = replaceEmptyStringValue('foo')(MyInput)
const wrapper = mount(
<WrappedInput {...{ input: { value: '' }, meta: {} }} />
)
expect(wrapper.find(MyInput).props().input.value).toEqual('foo')
const WrappedInput = replaceEmptyStringValue('foo')(InputToWrap)
render(<WrappedInput {...{ input: { value: '' }, meta: {} }} />)
expect(screen.getByRole('textbox')).toHaveValue('foo')
})

test("doesn't replace other values", () => {
const MyInput = () => <input />
const WrappedInput = replaceEmptyStringValue('foo')(MyInput)
const wrapper = mount(
const WrappedInput = replaceEmptyStringValue('foo')(InputToWrap)
render(
<WrappedInput {...{ input: { value: 'other' }, meta: {} }} />
)
expect(wrapper.find(MyInput).props().input.value).toEqual('other')
expect(screen.getByRole('textbox')).toHaveValue('other')
})
130 changes: 63 additions & 67 deletions test/forms/inputs/cloudinary-file-input/cloudinary-uploader.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { shallow } from 'enzyme'
import { render } from '@testing-library/react'
import cloudinaryUploader from '../../../../src/forms/inputs/cloudinary-file-input/cloudinary-uploader'

class MockResponse {
Expand Down Expand Up @@ -64,49 +64,50 @@ test('cloudinaryUploader has correct displayName', () => {
})

test('cloudinaryUploader throws an error if `bucket`, `cloudName`, or `apiAdapter` are not provided', () => {
jest.spyOn(console, 'error').mockImplementation(() => null) // avoid console bloat
const Wrapped = () => <h1>Hi</h1>
const Wrapper = cloudinaryUploader()(Wrapped)
expect(() => shallow(<Wrapper />)).toThrow()
expect(() => render(<Wrapper />)).toThrow()
jest.restoreAllMocks()
})

test('cloudinaryUploader can receive arguments via env vars', () => {
// eslint-disable-next-line no-undef
process.env.CLOUDINARY_CLOUD_NAME = 'foo'
// eslint-disable-next-line no-undef
process.env.CLOUDINARY_BUCKET = 'bar'
const Wrapped = () => <h1>Hi</h1>
const Wrapper = cloudinaryUploader({ apiAdapter: props.apiAdapter })(Wrapped)
expect(() => shallow(<Wrapper />)).not.toThrow()
})

test('cloudinaryUploader adds upload props to component', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapper = cloudinaryUploader(props)(Wrapped)
const component = shallow(<Wrapper />)
expect(component.props()).toMatchObject({
upload: expect.any(Function),
uploadStatus: expect.any(String),
})
expect(() => render(<Wrapper />)).not.toThrow()
})

test('cloudinaryUploader can receive options as props', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapper = cloudinaryUploader()(Wrapped)
const component = shallow(
expect(() => render(
<Wrapper cloudName="foo" bucket="bar" apiAdapter={() => {}} />
)
expect(component.props()).toMatchObject({
)).not.toThrow()
})

test('cloudinaryUploader adds upload props to component', () => {
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader(props)(Wrapped)
render(<Wrapper />)
expect(Wrapped).toHaveBeenCalledWith(expect.objectContaining({
upload: expect.any(Function),
uploadStatus: expect.any(String),
})
}), {})
})

test('cloudinaryUploader sends the api request with the correct options', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader(props)(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)

const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, file).then((response) => {
component.update()
const { uploadStatus } = component.props()
const { uploadStatus } = Wrapped.mock.calls[2][0]
expect(uploadStatus).toEqual('upload-success')
const responseJson = JSON.parse(response.body)
expect(responseJson.file).toEqual(fileData)
Expand All @@ -117,61 +118,61 @@ test('cloudinaryUploader sends the api request with the correct options', () =>
})

test('cloudinaryUploader sets `publicId`', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader({
...props,
cloudinaryPublicId: 'custom-name',
})(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, file).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('custom-name')
})
})

test('cloudinaryUploader allows custom `publicId` creator', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const createPublicId = (file) => 'foo-' + file.name
const Wrapper = cloudinaryUploader({ ...props, createPublicId })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, file).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('foo-test')
})
})

test('cloudinaryUploader overrides custom `publicId` creator with `cloudinaryPublicId`', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const createPublicId = (file) => 'foo-' + file.name
const Wrapper = cloudinaryUploader({
...props,
createPublicId,
cloudinaryPublicId: 'custom-name',
})(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, file).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('custom-name')
})
})

test('cloudinaryUploader adds extension to `publicId` of raw files', () => {
const rawFile = { name: 'test.xls', type: 'application/xls' }
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader({
...props,
cloudinaryPublicId: 'custom-name',
})(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, rawFile).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('custom-name.xls')
})
Expand All @@ -183,13 +184,13 @@ test('cloudinaryUploader removes invalid characters from the default `publicId`'
name: 'Final \\ Master %20 Schedule? #S1&S2 <100%> & finished.pdf',
type: 'application/pdf',
}
const Wrapped = () => <h1>Howdy</h1>
const Wrapped = jest.fn(() => <h1>Howdy</h1>)
const Wrapper = cloudinaryUploader({ ...props })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]


return upload(fileData, illegallyNamedFile).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).not.toMatch(FORBIDDEN_PATTERN)
})
Expand All @@ -200,13 +201,12 @@ test('cloudinaryUploader removes html escaped characters from the default `publi
name: 'SY%20S1%26S2.pdf',
type: 'application/pdf',
}
const Wrapped = () => <h1>Howdy</h1>
const Wrapped = jest.fn(() => <h1>Howdy</h1>)
const Wrapper = cloudinaryUploader({ ...props })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, illegallyNamedFile).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('SY_S1_S2')
})
Expand All @@ -217,13 +217,12 @@ test('cloudinaryUploader replaces spaces and removes superfluous underscores fro
name: ' SY S1___S2.pdf',
type: 'application/pdf',
}
const Wrapped = () => <h1>Howdy</h1>
const Wrapped = jest.fn(() => <h1>Howdy</h1>)
const Wrapper = cloudinaryUploader({ ...props })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, illegallyNamedFile).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('SY_S1_S2')
})
Expand All @@ -234,29 +233,27 @@ test('cloudinaryUploader trims spaces from the start of the default `publicId`',
name: ' Example.pdf',
type: 'application/pdf',
}
const Wrapped = () => <h1>Howdy</h1>
const Wrapped = jest.fn(() => <h1>Howdy</h1>)
const Wrapper = cloudinaryUploader({ ...props })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

return upload(fileData, illegallyNamedFile).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toEqual('Example')
})
})

test('cloudinaryUploader defaults file name if not provided when creating the default `publicId`', () => {
const fileWithNoName = { name: '', type: 'application/pdf' }
const Wrapped = () => <h1>Howdy</h1>
const Wrapped = jest.fn(() => <h1>Howdy</h1>)
const Wrapper = cloudinaryUploader({ ...props })(Wrapped)
const component = shallow(<Wrapper />)
const { upload } = component.props()

render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]
// eslint-disable-next-line no-undef
const spy = jest.spyOn(global.Date, 'now')

return upload(fileData, fileWithNoName).then((response) => {
component.update()
const responseJson = JSON.parse(response.body)
expect(responseJson.public_id).toContain('file_upload')
expect(spy).toHaveBeenCalled()
Expand All @@ -266,30 +263,29 @@ test('cloudinaryUploader defaults file name if not provided when creating the de
})

test('cloudinaryUploader throws an error if request fails', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader({ ...props, endpoint: '/failure' })(
Wrapped
)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

expect.assertions(1)

return expect(upload(fileData, file)).rejects.toThrow()
})

test('cloudinaryUploader updates the `uploadStatus` prop if request fails', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapped = jest.fn(() => <h1>Hi</h1>)
const Wrapper = cloudinaryUploader({ ...props, endpoint: '/failure' })(
Wrapped
)
const component = shallow(<Wrapper />)
const { upload } = component.props()
render(<Wrapper />)
const { upload } = Wrapped.mock.calls[0][0]

expect.assertions(1)
return upload(fileData, file).catch(() => {
component.update()
const { uploadStatus } = component.props()
const { uploadStatus } = Wrapped.mock.calls[2][0]
expect(uploadStatus).toEqual('upload-failure')
})
})
Loading

0 comments on commit 8ecd5fb

Please sign in to comment.