import '@testing-library/jest-dom'; import { fireEvent, render, screen } from '@testing-library/react'; import { act } from 'react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { AmountInput } from './AmountInput'; // Mock ResizeObserver class ResizeObserverMock { observe() {} unobserve() {} disconnect() {} } describe('AmountInput', () => { beforeEach(() => { global.ResizeObserver = ResizeObserverMock; vi.clearAllMocks(); }); const defaultProps = { asset: 'ETH', currency: 'USD', fiatAmount: '', cryptoAmount: '', selectedInputType: 'fiat' as const, setFiatAmount: vi.fn(), setCryptoAmount: vi.fn(), exchangeRate: '1200', }; it('renders correctly with fiat input type', () => { render(); expect(screen.getByTestId('ockTextInput_Input')).toBeInTheDocument(); expect(screen.getByTestId('ockCurrencySpan')).toHaveTextContent('USD'); }); it('renders correctly with crypto input type', () => { render(); expect(screen.getByTestId('ockCurrencySpan')).toHaveTextContent('ETH'); }); it('handles input change in fiat mode', () => { render(); const input = screen.getByTestId('ockTextInput_Input'); fireEvent.change(input, { target: { value: '100' } }); expect(defaultProps.setFiatAmount).toHaveBeenCalledWith('100'); }); it('handles input change in crypto mode', () => { render(); const input = screen.getByTestId('ockTextInput_Input'); fireEvent.change(input, { target: { value: '1' } }); expect(defaultProps.setCryptoAmount).toHaveBeenCalledWith('1'); }); it('applies custom className', () => { render(); expect(screen.getByTestId('ockAmountInputContainer')).toHaveClass( 'custom-class', ); }); it('updates width based on currency label', async () => { const mockResizeObserver = vi.fn(); global.ResizeObserver = vi.fn().mockImplementation((callback) => { callback([ { contentRect: { width: 300 }, target: document.createElement('div'), }, ]); return { observe: mockResizeObserver, unobserve: vi.fn(), disconnect: vi.fn(), }; }); render(); const input = screen.getByTestId('ockTextInput_Input'); const container = screen.getByTestId('ockAmountInputContainer'); Object.defineProperty(container, 'getBoundingClientRect', { value: () => ({ width: 300 }), configurable: true, }); const currencyLabel = screen.getByTestId('ockCurrencySpan'); Object.defineProperty(currencyLabel, 'getBoundingClientRect', { value: () => ({ width: 50 }), configurable: true, }); act(() => { fireEvent.change(input, { target: { value: '100' } }); window.dispatchEvent(new Event('resize')); }); }); it('focuses input when input type changes', () => { const { rerender } = render(); const input = screen.getByTestId('ockTextInput_Input'); const focusSpy = vi.spyOn(input, 'focus'); rerender(); expect(focusSpy).toHaveBeenCalled(); }); it('displays placeholder when value is empty', () => { render(); const input = screen.getByTestId('ockTextInput_Input'); expect(input).toHaveAttribute('placeholder', '0'); }); it('updates hidden span content correctly', () => { const { rerender } = render(); const hiddenSpan = screen.getByTestId('ockHiddenSpan'); expect(hiddenSpan).toHaveTextContent('0.'); rerender(); expect(hiddenSpan).toHaveTextContent('100.'); }); it('prevents invalid input', () => { render(); const input = screen.getByTestId('ockTextInput_Input'); fireEvent.change(input, { target: { value: 'abc' } }); expect(defaultProps.setFiatAmount).not.toHaveBeenCalled(); }); it('maintains focus after value change', () => { render(); const input = screen.getByTestId('ockTextInput_Input'); input.focus(); fireEvent.change(input, { target: { value: '100' } }); expect(document.activeElement).toBe(input); }); });