@navinc/base-react-components
Version:
Nav's Pattern Library
250 lines (199 loc) • 6.76 kB
JavaScript
import React from 'react'
import { render, fireEvent } from '../tests/with-app-context.js'
import { theme } from './theme.js'
import SearchInput from './search-input.js'
describe('<SearchInput />', () => {
it('Loads the value into the input', () => {
const { getByTestId } = render(
<SearchInput
Result={(result) => <div>{result}</div>}
resultToQuery={(result) => result.name}
value={{ name: 'yoyo' }}
/>
)
expect(getByTestId('search-input:input').value).toBe('yoyo')
})
it('doesnt render results on first render even if results are passed', () => {
const { queryByText } = render(<SearchInput Result={(result) => <div>{result}</div>} results={['yoyo', 'brolo']} />)
expect(queryByText('yoyo')).toBe(null)
})
it(
'renders results when text has been entered, updates the input value,' +
' calls search, and calls the provided onChange with null',
(done) => {
let parentValue
const onChange = (event) => {
parentValue = event.target.value
}
const search = jest.fn()
const { getByTestId, findByText } = render(
<SearchInput onChange={onChange} Result={({ result }) => result} results={['yoyo', 'def']} search={search} />
)
fireEvent.change(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
expect(parentValue).toBe(null)
expect(getByTestId('search-input:input').value).toBe('hey, listen')
findByText('yoyo').then((result) => {
expect(search).toHaveBeenCalledWith('hey, listen')
done()
})
}
)
it('shows the results after a search is fired, hides them after blur, shows them after focus', (done) => {
const { getByTestId, getByText, queryByText, findByText } = render(
<SearchInput
Result={({ result }) => result}
resultToQuery={(result) => result}
results={['abc', 'def']}
value="abc"
/>
)
fireEvent.change(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
findByText('def').then((result) => {
expect(getByText('def'))
fireEvent.blur(getByTestId('search-input:input'), {})
expect(queryByText('def')).toBe(null)
fireEvent.focus(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
findByText('def').then((result2) => {
expect(getByText('def'))
done()
})
})
})
it('closes the results and calls the provided onChange if a result is clicked', (done) => {
const onChange = jest.fn()
const { getByTestId, findByText, queryByText } = render(
<SearchInput
name="name"
onChange={onChange}
Result={({ result }) => result}
resultToQuery={(result) => result}
results={['abc', 'def']}
value="abc"
/>
)
fireEvent.change(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
findByText('def').then((result) => {
fireEvent.mouseDown(result)
expect(onChange).toHaveBeenCalledWith({
target: {
name: 'name',
value: 'def',
},
})
expect(queryByText('def')).toBe(null)
done()
})
})
it(
'focuses the next result when the results are open and down or tab is pressed' +
', focuses the previous results when up or shift tab are pressed' +
', closes the results and calls onChange with the result if enter is pressed on a result' +
', reopens the results if down is pressed, closes it if escape is pressed' +
', and clears the input if escape is pressed with no result focused',
(done) => {
const onChange = jest.fn()
const { getByTestId, getByText, queryByText, findByText } = render(
<SearchInput
name="name"
onChange={onChange}
Result={({ result }) => result}
resultToQuery={(result) => result}
results={['abc', 'def', 'ghi', 'jkl']}
/>
)
const input = getByTestId('search-input:input')
fireEvent.change(input, {
target: {
value: 'hey, listen',
},
})
findByText('def').then((result) => {
fireEvent.keyDown(input, { keyCode: 40 })
expect(getByText('abc')).toHaveStyleRule('background-color', theme.neutral100)
fireEvent.keyDown(input, { keyCode: 9 })
expect(getByText('def')).toHaveStyleRule('background-color', theme.neutral100)
fireEvent.keyDown(input, { keyCode: 40 })
expect(getByText('ghi')).toHaveStyleRule('background-color', theme.neutral100)
fireEvent.keyDown(input, { keyCode: 38 })
expect(getByText('def')).toHaveStyleRule('background-color', theme.neutral100)
fireEvent.keyDown(input, { keyCode: 9, shiftKey: true })
expect(getByText('abc')).toHaveStyleRule('background-color', theme.neutral100)
fireEvent.keyDown(input, { keyCode: 13 })
expect(onChange).toHaveBeenCalledWith({
target: {
name: 'name',
value: 'abc',
},
})
expect(queryByText('def')).toBe(null)
fireEvent.keyDown(input, {
keyCode: 40,
})
expect(getByText('def'))
fireEvent.keyDown(input, {
keyCode: 27,
})
expect(queryByText('def')).toBe(null)
fireEvent.keyDown(input, {
keyCode: 27,
})
expect(input.value).toBe('')
done()
})
}
)
it('renders defaultNoResults if none is provided and there are no results after search', (done) => {
const { getByTestId, findByText } = render(
<SearchInput
name="name"
Result={({ result }) => result}
resultToQuery={(result) => result}
results={[]}
value="abc"
/>
)
fireEvent.change(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
findByText('No results for "hey, listen"').then((result) => {
done()
})
})
it('renders the provided NoResults if there are no results after a search', (done) => {
const { getByTestId, findByText } = render(
<SearchInput
NoResults={({ query }) => `look bro I got your ${query}`}
Result={({ result }) => result}
resultToQuery={(result) => result}
results={[]}
value="abc"
/>
)
fireEvent.change(getByTestId('search-input:input'), {
target: {
value: 'hey, listen',
},
})
findByText('look bro I got your hey, listen').then((result) => {
done()
})
})
})