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();
});
});