import React from 'react'; import '@testing-library/jest-dom'; import { render, fireEvent, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import CurrencyInput from '../CurrencyInput'; import { act } from 'react-dom/test-utils'; describe('', () => { const onValueChangeSpy = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); it('Renders without error', () => { render( ); const input = screen.getByRole('textbox'); expect(input).toMatchSnapshot(); expect(input).toHaveValue(''); }); it('Renders with default value', () => { render(); const input = screen.getByRole('textbox'); expect(input).toMatchSnapshot(); expect(input).toHaveValue('£1,234.56'); }); it('Renders with default value 0', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0'); }); it('Renders with default value undefined', () => { render(); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('Renders with default value null', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any render(); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('Renders with default value 0 with decimalScale 2', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0.00'); }); it('Renders with value prop', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£49.99'); }); it('Renders with value 0', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0'); }); it('Renders with value undefined', () => { render(); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('Renders with value null', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any render(); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('Renders with value 0 with decimalScale 2', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0.00'); }); it('Renders with value 0.1 with decimalScale 2', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0.10'); userEvent.type(screen.getByRole('textbox'), '{backspace}'); expect(screen.getByRole('textbox')).toHaveValue('£0.1'); }); it('should go to end of string on focus', () => { render(); userEvent.type(screen.getByRole('textbox'), '{arrowleft}4{arrowright}6'); expect(screen.getByRole('textbox')).toHaveValue('12,436'); }); it('should allow value change with number', () => { render(); userEvent.type(screen.getByRole('textbox'), '100'); expect(onValueChangeSpy).toHaveBeenLastCalledWith('100', undefined, { float: 100, formatted: '£100', value: '100', }); }); it('should prefix 0 value', () => { render(); expect(screen.getByRole('textbox')).toHaveValue('£0'); }); it('should allow 0 value on change', () => { render(); userEvent.type(screen.getByRole('textbox'), '0'); expect(onValueChangeSpy).toHaveBeenLastCalledWith('0', undefined, { float: 0, formatted: '£0', value: '0', }); expect(screen.getByRole('textbox')).toHaveValue('£0'); }); it('should allow empty value', () => { render(); userEvent.clear(screen.getByRole('textbox')); expect(onValueChangeSpy).toHaveBeenLastCalledWith(undefined, undefined, { float: null, formatted: '', value: '', }); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('should callback name as second parameter if name prop provided', () => { const name = 'inputName'; render(); userEvent.type(screen.getByRole('textbox'), '123'); expect(onValueChangeSpy).toHaveBeenLastCalledWith('123', name, { float: 123, formatted: '£123', value: '123', }); }); it('should not allow invalid characters', () => { render(); userEvent.type(screen.getByRole('textbox'), 'hello'); expect(onValueChangeSpy).toHaveBeenLastCalledWith(undefined, undefined, { float: null, formatted: '', value: '', }); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('should ignore invalid characters', () => { render(); userEvent.type(screen.getByRole('textbox'), '£123hello'); expect(onValueChangeSpy).toHaveBeenLastCalledWith('123', undefined, { float: 123, formatted: '£123', value: '123', }); expect(screen.getByRole('textbox')).toHaveValue('£123'); }); it('should clear decimal point only input', () => { render(); userEvent.type(screen.getByRole('textbox'), '.'); expect(onValueChangeSpy).toHaveBeenLastCalledWith(undefined, undefined, { float: null, formatted: '', value: '', }); fireEvent.focusOut(screen.getByRole('textbox')); expect(screen.getByRole('textbox')).toHaveValue(''); }); it('should allow .3 decimal inputs', () => { render(); userEvent.type(screen.getByRole('textbox'), '.3'); expect(onValueChangeSpy).toHaveBeenLastCalledWith('.3', undefined, { float: 0.3, formatted: '£0.3', value: '.3', }); fireEvent.focusOut(screen.getByRole('textbox')); expect(screen.getByRole('textbox')).toHaveValue('£0.3'); }); it('should call onChange', () => { const onChangeSpy = jest.fn(); render(); userEvent.type(screen.getByRole('textbox'), '123'); expect(onChangeSpy).toHaveBeenCalledTimes(3); expect(screen.getByRole('textbox')).toHaveValue('£123'); }); it('should call onBlur', () => { const onBlurSpy = jest.fn(); render(); userEvent.click(screen.getByRole('textbox')); fireEvent.focusOut(screen.getByRole('textbox')); expect(onBlurSpy).toHaveBeenCalledTimes(1); }); it('should call onFocus', () => { const onFocusSpy = jest.fn(); render(); fireEvent.focusIn(screen.getByRole('textbox')); expect(onFocusSpy).toHaveBeenCalledTimes(1); }); it('should call onKeyDown', () => { const onKeyDownSpy = jest.fn(); render(); userEvent.type(screen.getByRole('textbox'), '1'); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); it('should call onKeyUp', () => { const onKeyUpSpy = jest.fn(); render(); userEvent.type(screen.getByRole('textbox'), '1'); expect(onKeyUpSpy).toHaveBeenCalledTimes(1); }); it('should update the input when prop value changes to another number', () => { const { rerender } = render( ); const field = screen.getByRole('textbox'); expect(field).toHaveValue('£1'); act(() => { rerender(); }); expect(field).toHaveValue('£2'); }); it('should update the input when prop value changes to undefined', () => { const { rerender } = render(); const field = screen.getByRole('textbox'); expect(field).toHaveValue('£1'); act(() => { rerender(); }); expect(field).toHaveValue(''); }); });