import { fireEvent } from '@testing-library/react' import pick from 'lodash/pick' import * as React from 'react' import renderWithTheme from '../../tests/helpers/renderWithTheme' import SelectField from './SelectField' function closest(el: HTMLElement, matcher: (el: HTMLElement) => boolean): HTMLElement | null { while (el && el !== document.body) { if (el && matcher(el)) { return el } el = el.parentNode as HTMLElement } return null } describe('component: SelectField', () => { test('render with complex options', () => { const { getByLabelText } = renderWithTheme( ) expect(getByLabelText('Requires a label')).not.toBeNull() }) test('should render a disabled SelectField', () => { const { getByLabelText } = renderWithTheme( ) expect(getByLabelText('Requires a label')).toBeDisabled() }) test('should render an attached label', () => { const { getByLabelText } = renderWithTheme( ) expect(getByLabelText('Requires a label')).not.toBeNull() }) test('should render an attached tooltip', () => { const { getByText, getByLabelText } = renderWithTheme( ) const tooltipTextEl = getByText('This is some information') const tooltipEl = closest(tooltipTextEl, (el): boolean => el.getAttribute('role') === 'tooltip') expect(tooltipEl).not.toBeNull() const select = getByLabelText('Requires a label') expect(select.getAttribute('aria-describedby')).toContain((tooltipEl as HTMLElement).id) }) test('should render a provided placeholder', () => { const { getByText } = renderWithTheme( ) expect(getByText('This is that placeholder')).not.toBeNull() }) test('should render an accessible success message', () => { const { getByText, getByLabelText } = renderWithTheme( ) const statusEl = getByText(`You're GREAT!`) as HTMLElement const select = getByLabelText('Requires a label') expect(select.getAttribute('aria-describedby')).toContain(statusEl.id) }) test('should render an accessible warning message', () => { const { getByText, getByLabelText } = renderWithTheme( ) const statusEl = getByText(`You got a ridiculous warning`) as HTMLElement const select = getByLabelText('Requires a label') expect(select.getAttribute('aria-describedby')).toContain(statusEl.id) }) test('should render an accessible error message', () => { const { getByText, getByLabelText } = renderWithTheme( ) const statusEl = getByText(`You've done this incorrectly`) as HTMLElement const select = getByLabelText('Requires a label') expect(select.getAttribute('aria-describedby')).toContain(statusEl.id) }) test('supports margin props', () => { const { container } = renderWithTheme( ) expect(container.firstElementChild).toHaveStyle('margin-left: 8px') expect(container.firstElementChild).toHaveStyle('margin-right: 8px') expect(container.firstElementChild).toHaveStyle('margin-top: 8px') expect(container.firstElementChild).toHaveStyle('margin-bottom: 8px') }) test('should support flex item props', () => { const { container } = renderWithTheme( ) expect(container.firstElementChild).toHaveStyle('flex: 1') expect(container.firstElementChild).toHaveStyle('flex-grow: 1') expect(container.firstElementChild).toHaveStyle('flex-shrink: 0') expect(container.firstElementChild).toHaveStyle('flex-basis: 0') }) describe('should accept form event', () => { test('onChange', () => { const box: any = {} const onChange = jest.fn((e) => Object.assign(box, pick(e.target, ['name', 'value']))) const { getByLabelText, getByText } = renderWithTheme( ) const select = getByLabelText('Requires a label') as HTMLElement fireEvent.click(select) fireEvent.click(getByText('basic')) expect(onChange).toHaveBeenCalledTimes(1) expect(box).toEqual({ name: 'the-test-select-field', value: 'basic' }) }) test('onBlur', async (): Promise => { const box: any = {} const onBlur = jest.fn((e) => Object.assign(box, pick(e.target, ['name', 'value']))) const { getByLabelText } = renderWithTheme( ) const select = getByLabelText('Requires a label') as HTMLElement fireEvent.blur(select) expect(onBlur).toHaveBeenCalledTimes(1) expect(box).toEqual({ name: 'the-test-select-field', value: null }) }) test('onFocus', async (): Promise => { const box: any = {} const onFocus = jest.fn((e) => { box.name = e.target.name }) const { getByLabelText } = renderWithTheme( ) const select = getByLabelText('Requires a label') as HTMLElement fireEvent.focus(select) expect(onFocus).toHaveBeenCalledTimes(1) expect(box).toEqual({ name: 'the-test-select-field' }) }) }) })