import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; import { TextInputGroupMain } from '../TextInputGroupMain'; import { TextInputGroupContext } from '../TextInputGroup'; import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; describe('TextInputGroupMain', () => { it('renders without children', () => { render(); expect(screen.getByTestId('TextInputGroupMain')).toBeVisible(); }); it('renders children', () => { render(Test); expect(screen.getByText('Test')).toBeVisible(); }); it('renders with class pf-v5-c-text-input-group__main', () => { render(Test); const inputGroupMain = screen.getByText('Test'); expect(inputGroupMain).toHaveClass('pf-v5-c-text-input-group__main'); }); it('does not render with class pf-m-icon when an icon prop is not passed', () => { render(Test); const inputGroupMain = screen.getByText('Test'); expect(inputGroupMain).not.toHaveClass('pf-m-icon'); }); it('renders with class pf-m-icon when an icon prop is passed', () => { render(Test); const inputGroupMain = screen.getByText('Test'); expect(inputGroupMain).toHaveClass('pf-m-icon'); }); it('renders with custom class names provided via prop', () => { render(Test); const inputGroupMain = screen.getByText('Test'); expect(inputGroupMain).toHaveClass('custom-class'); }); it('renders with class pf-v5-c-text-input-group__text on the inputs parent', () => { render(Test); const inputGroupText = screen.getByRole('textbox').parentNode; expect(inputGroupText).toHaveClass('pf-v5-c-text-input-group__text'); }); it('renders the input with class pf-v5-c-text-input-group__text-input', () => { render(Test); const input = screen.getByRole('textbox'); expect(input).toHaveClass('pf-v5-c-text-input-group__text-input'); }); it('does not render the icon when it is not passed', () => { render(); const icon = screen.queryByRole('img', { hidden: true }); expect(icon).not.toBeInTheDocument(); }); it('renders the icon when passed', () => { render(} />); const icon = screen.getByRole('img', { hidden: true }); expect(icon).toBeInTheDocument(); }); it('renders the icon as aria hidden', () => { render(} />); const icon = screen.getByRole('img', { hidden: true }); expect(icon).toHaveAttribute('aria-hidden', 'true'); }); it('passes the aria-label prop to the input', () => { render(Test); const input = screen.getByRole('textbox'); expect(input).toHaveAccessibleName('Test label'); }); it('passes the value prop to the input', () => { render(Test); const inputValue = screen.getByDisplayValue('value text'); expect(inputValue).toBeVisible(); }); it('passes the placeholder prop to the input', () => { render(Test); const inputPlaceholder = screen.getByPlaceholderText('placeholder text'); expect(inputPlaceholder).toBeVisible(); }); it('defaults to an input type of text', () => { render(Test); const input = screen.getByRole('textbox'); expect(input).toHaveAttribute('type', 'text'); }); it('updates the input type when a different type is passed', () => { render(Test); const textInput = screen.queryByRole('textbox'); const searchInput = screen.getByRole('searchbox'); expect(textInput).not.toBeInTheDocument(); expect(searchInput).toBeVisible(); }); it('does not disable the input when TextInputGroupContext isDisabled is false', () => { render( ); const input = screen.getByRole('textbox'); expect(input).not.toBeDisabled(); }); it('disables the input when TextInputGroupContext isDisabled is true', () => { render( ); const input = screen.getByRole('textbox'); expect(input).toBeDisabled(); }); it("doesn't render the hint input when a hint prop isn't passed", () => { // we set the type of the main input to search here so that we can accurately target the hint input render(Test); const hintInput = screen.queryByRole('textbox', { hidden: true }); expect(hintInput).not.toBeInTheDocument(); }); it('renders the hint input when a hint prop is passed', () => { // we set the type of the main input to search here so that we can accurately target the hint input render( Test ); const hintInput = screen.getByRole('textbox', { hidden: true }); expect(hintInput).toBeInTheDocument(); }); it('renders the hint input with classes pf-v5-c-text-input-group__text-input and pf-m-hint', () => { // we set the type of the main input to search here so that we can accurately target the hint input render( Test ); const hintInput = screen.getByRole('textbox', { hidden: true }); expect(hintInput).toHaveClass('pf-m-hint'); expect(hintInput).toHaveClass('pf-v5-c-text-input-group__text-input'); }); it('renders the hint input as disabled', () => { // we set the type of the main input to search here so that we can accurately target the hint input render( Test ); const hintInput = screen.getByRole('textbox', { hidden: true }); expect(hintInput).toBeDisabled(); }); it('renders the hint input as aria-hidden', () => { // we set the type of the main input to search here so that we can accurately target the hint input render( Test ); const hintInput = screen.getByRole('textbox', { hidden: true }); expect(hintInput).toHaveAttribute('aria-hidden', 'true'); }); it('passes the hint prop to the hint input as its value', () => { // we set the type of the main input to search here so that we can accurately target the hint input render( Test ); const hintInput = screen.getByDisplayValue('value text'); expect(hintInput).toBeVisible(); }); it('does not call onChange callback when the input does not change', () => { const onChangeMock = jest.fn(); render(Test); expect(onChangeMock).not.toHaveBeenCalled(); }); it('calls the onChange callback when the input changes', async () => { const onChangeMock = jest.fn(); const user = userEvent.setup(); render(Test); const input = screen.getByRole('textbox'); await user.type(input, 'Test'); expect(onChangeMock).toHaveBeenCalledTimes(4); }); it('does not call onFocus callback when the input does not get focus', () => { const onFocusMock = jest.fn(); render(Test); expect(onFocusMock).not.toHaveBeenCalled(); }); it('calls the onFocus callback when the input is focused', async () => { const onFocusMock = jest.fn(); const user = userEvent.setup(); render(Test); const input = screen.getByRole('textbox'); await user.click(input); expect(onFocusMock).toHaveBeenCalledTimes(1); }); it('does not call onBlur callback when the input does not lose focus', async () => { const onBlurMock = jest.fn(); const user = userEvent.setup(); render(Test); const input = screen.getByRole('textbox'); await user.click(input); expect(onBlurMock).not.toHaveBeenCalled(); }); it('calls the onBlur callback when the input loses focus', async () => { const onBlurMock = jest.fn(); const user = userEvent.setup(); render(Test); const input = screen.getByRole('textbox'); await user.click(input); await user.click(document.body); expect(onBlurMock).toHaveBeenCalledTimes(1); }); it('matches the snapshot', () => { const { asFragment } = render(Test); expect(asFragment()).toMatchSnapshot(); }); });