This commit is contained in:
92
tests/components/InputField.test.tsx
Normal file
92
tests/components/InputField.test.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { createRef } from 'react';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { InputField } from '../../src/components/InputField';
|
||||
|
||||
describe('InputField', () => {
|
||||
it('supports email type and emits change/blur callbacks', () => {
|
||||
const onChange = vi.fn();
|
||||
const onBlur = vi.fn();
|
||||
render(
|
||||
<InputField
|
||||
label="Email"
|
||||
type="email"
|
||||
value=""
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
required
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = screen.getByLabelText('Email') as HTMLInputElement;
|
||||
expect(input.type).toBe('email');
|
||||
expect(input).toBeRequired();
|
||||
|
||||
fireEvent.change(input, { target: { value: 'new@example.com' } });
|
||||
fireEvent.blur(input);
|
||||
expect(onChange).toHaveBeenCalledTimes(1);
|
||||
expect(onBlur).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('passes refs to input element', () => {
|
||||
const inputRef = createRef<HTMLInputElement>();
|
||||
render(<InputField label="Username" type="text" value="john" onChange={() => {}} inputRef={inputRef} />);
|
||||
|
||||
expect(inputRef.current).toBeInstanceOf(HTMLInputElement);
|
||||
expect(inputRef.current?.value).toBe('john');
|
||||
});
|
||||
|
||||
it('toggles password visibility', () => {
|
||||
render(<InputField label="Password" type="password" value="abc" onChange={() => {}} />);
|
||||
|
||||
expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('password');
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Show password' }));
|
||||
expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('text');
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Hide password' }));
|
||||
expect((screen.getByLabelText('Password') as HTMLInputElement).type).toBe('password');
|
||||
});
|
||||
|
||||
it('renders rightIcon for non-password input and displays errors', () => {
|
||||
const { container } = render(
|
||||
<InputField
|
||||
label="Username"
|
||||
type="text"
|
||||
value="john"
|
||||
onChange={() => {}}
|
||||
rightIcon={<span data-testid="right-icon">R</span>}
|
||||
error="Invalid username"
|
||||
inputClassName="custom-input"
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = container.querySelector('input');
|
||||
expect(input).toBeInstanceOf(HTMLInputElement);
|
||||
expect(input).toHaveClass('pr-10');
|
||||
expect(input).toHaveClass('custom-input');
|
||||
expect(screen.getByTestId('right-icon')).toBeInTheDocument();
|
||||
expect(screen.getByText('Invalid username')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('disables password toggle when input is disabled', () => {
|
||||
render(
|
||||
<InputField
|
||||
label="Password"
|
||||
type="password"
|
||||
value="secret"
|
||||
onChange={() => {}}
|
||||
disabled
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Show password' })).toBeDisabled();
|
||||
});
|
||||
|
||||
it('supports inline layout classes', () => {
|
||||
const { container } = render(
|
||||
<InputField label="Username" type="text" value="" onChange={() => {}} layout="inline" />,
|
||||
);
|
||||
|
||||
expect(container.querySelector('label')).toHaveClass('inline-flex');
|
||||
expect(container.querySelector('label > div')).not.toHaveClass('mt-1');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user