import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { Input } from './Input';
import { fireEvent, render, waitFor, screen } from '../../../../../tests/test-utils';
describe('Input', () => {
it('should render without errors', () => {
// arrange
const { container } = render();
// assert
expect(container).toBeTruthy();
});
it('should render the label if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toBeInTheDocument();
});
it('should render the placeholder if provided', () => {
// arrange
render();
// assert
const input = screen.getByPlaceholderText('Test Placeholder');
expect(input).toBeInTheDocument();
});
it('should render the error message if provided', () => {
// arrange
render();
// assert
const error = screen.getByText('Test Error');
expect(error).toBeInTheDocument();
});
it('should call onChange when the input value is changed', async () => {
// arrange
const onChange = jest.fn();
render();
const input = screen.getByLabelText('Test Label');
// act
fireEvent.change(input, { target: { value: 'changed' } });
// assert
await waitFor(() => expect(onChange).toHaveBeenCalledTimes(1));
});
it('should call onBlur when the input is blurred', async () => {
// arrange
const onBlur = jest.fn();
render();
const input = screen.getByLabelText('Test Label');
// act
fireEvent.blur(input);
// assert
await waitFor(() => expect(onBlur).toHaveBeenCalledTimes(1));
});
it('should set the input type if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label') as HTMLInputElement;
// assert
expect(input.type).toBe('password');
});
it('should set the input value if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label') as HTMLInputElement;
// assert
expect(input.value).toBe('Test Value');
});
it('should apply the isInvalid prop to the input element', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toHaveClass('is-invalid', 'is-invalid-lite');
});
it('should apply the disabled prop to the input element', () => {
// arrange
render();
// assert
const input = screen.getByLabelText('Test Label');
expect(input).toBeDisabled();
});
it('should set the input name attribute if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toHaveAttribute('name', 'test-input');
});
it('should set the input id attribute if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toHaveAttribute('id', 'test-input');
});
it('should set the input ref if provided', () => {
// arrange
const ref = React.createRef();
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toEqual(ref.current);
});
it('should set the input type attribute to "text" if not provided or if an invalid value is provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label') as HTMLInputElement;
// assert
expect(input.type).toBe('text');
});
it('should set the input placeholder attribute if provided', () => {
// arrange
render();
const input = screen.getByLabelText('Test Label');
// assert
expect(input).toHaveAttribute('placeholder', 'Test Placeholder');
});
});