import userEvent from '@testing-library/user-event'
import * as React from 'react'
import renderWithTheme from '../../tests/helpers/renderWithTheme'
import FileInput from './FileInput'
// Fake File object; aren't dynamic languages great?
const file: File = Object.create(File.prototype)
Object.defineProperty(file, 'name', { enumerable: true, value: 'boolest.txt' })
Object.defineProperty(file, 'size', { enumerable: true, value: 42 })
const fakeValue = [FileInput.toFileObj(file)]
describe('component: FileInput', () => {
test('should clear input with empty string', () => {
const { getByText, rerender } = renderWithTheme(
)
const span = getByText('boolest.txt')
rerender()
expect(span).not.toBeInTheDocument()
})
test('should forward input-specific props to input', () => {
const { getByLabelText, getByTestId } = renderWithTheme(
)
const wrapper = getByTestId('wrapper')
expect(wrapper.matches(`div${FileInput}`)).toBe(true)
expect(wrapper).toHaveAttribute('aria-hidden', 'true')
expect(wrapper).toHaveAttribute('aria-disabled', 'true')
expect(wrapper).not.toHaveAttribute('id')
expect(wrapper).not.toHaveAttribute('aria-label')
const input = getByLabelText('Oh Yeah!')
expect(input.matches('input#punchthroat')).toBe(true)
expect(input).not.toHaveAttribute('aria-hidden')
expect(input).not.toHaveAttribute('aria-disabled')
expect(input).toHaveAttribute('aria-label', 'Oh Yeah!')
expect(input).toHaveAttribute('aria-labelledby', 'punchthroat')
expect(input).toHaveAttribute('aria-describedby', 'desc')
expect(input).toHaveAttribute('aria-details', 'details')
expect(input).toHaveAttribute('aria-errormessage', 'Oh no!')
expect(input).toHaveAttribute('aria-invalid', 'true')
expect(input).toHaveAttribute('aria-placeholder', 'Hold my _____')
expect(input).toHaveAttribute('capture', 'user')
expect(input).toHaveAttribute('form', 'other')
expect(input).toHaveAttribute('multiple')
expect(input).toHaveAttribute('disabled')
expect(input).toHaveAttribute('required')
expect(input).toHaveAttribute('aria-required', 'true')
})
test('should fire focus/blur events at element boundary', () => {
let focusTarget: any = undefined,
blurTarget: any = undefined
const focus = jest.fn((e: any) => {
focusTarget = { ...e.target }
})
const blur = jest.fn((e: any) => {
blurTarget = { ...e.target }
})
renderWithTheme(
)
userEvent.tab()
expect(document.activeElement).toHaveAttribute('name', 'throatpunch')
expect(focus).toHaveBeenCalledTimes(1)
expect(blur).toHaveBeenCalledTimes(0)
userEvent.tab()
expect(document.activeElement).toHaveTextContent('boolest.txt')
expect(focus).toHaveBeenCalledTimes(1)
expect(blur).toHaveBeenCalledTimes(0)
userEvent.tab()
expect(document.activeElement).toHaveAttribute('aria-label', 'Delete File')
expect(focus).toHaveBeenCalledTimes(1)
expect(blur).toHaveBeenCalledTimes(0)
userEvent.tab()
expect(focus).toHaveBeenCalledTimes(1)
expect(blur).toHaveBeenCalledTimes(1)
expect(focusTarget).toEqual({ name: 'throatpunch', value: fakeValue })
expect(blurTarget).toEqual(focusTarget)
})
test('should be able to delete file', () => {
let changeTarget: any = undefined
const Controlled = () => {
const [state, setState] = React.useState(fakeValue)
const change = jest.fn((e) => {
changeTarget = { ...e.target }
setState(e.target.value)
})
return
}
const { getByLabelText } = renderWithTheme()
const deleteButton = getByLabelText('Delete File')
userEvent.click(deleteButton)
expect(deleteButton).not.toBeInTheDocument()
expect(changeTarget).toEqual({ name: 'controlled', value: [] })
})
/** TODO: Add integration tests to theme-components example using puppeteer. We can't put them here because
* @types/puppeteer brings in @types/node and sets everything else on fire
* */
})