import { fireEvent, render, screen } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; import { TokenBalance } from './TokenBalance'; const mockToken = { symbol: 'ETH', address: '' as const, chainId: 8453, decimals: 18, image: null, name: 'Ethereum', cryptoBalance: 1, fiatBalance: 3300, }; describe('TokenBalance', () => { describe('Main TokenBalance component', () => { it('renders as div when no onClick provided', () => { render(); expect(screen.queryByRole('button')).toBeNull(); }); it('renders as button with onClick handler', () => { const onClick = vi.fn(); render(); const button = screen.getByRole('button'); fireEvent.click(button); expect(onClick).toHaveBeenCalledWith(mockToken); }); it('applies custom classNames to the div container', () => { const customClassNames = { container: 'custom-class' }; render(); expect(screen.getByTestId('ockTokenBalance')).toHaveClass( customClassNames.container, ); }); it('applies custom classNames to the button container', () => { const customClassNames = { container: 'custom-class' }; const handleClick = vi.fn(); render( , ); expect(screen.getByTestId('ockTokenBalanceButton')).toHaveClass( customClassNames.container, ); }); }); describe('TokenBalanceContent', () => { it('renders token details correctly', () => { render(); expect(screen.getByText('Ethereum')).toBeInTheDocument(); expect(screen.getByText('0.000 ETH Test subtitle')).toBeInTheDocument(); expect(screen.getByText('$3,300.00')).toBeInTheDocument(); }); it('shows/hides token image based on showImage prop', () => { const { rerender } = render( , ); expect(screen.getByTestId('ockTokenImage_NoImage')).toBeInTheDocument(); rerender( , ); expect(screen.queryByTestId('ockTokenImage_NoImage')).toBeNull(); }); it('renders subtitle when provided', () => { const subtitle = '(50% of balance)'; render(); expect(screen.getByText(`0.000 ETH ${subtitle}`)).toBeInTheDocument(); }); it('does not render action button when onActionPress is not provided', () => { render(); expect(screen.queryByTestId('ockTokenBalanceAction')).toBeNull(); }); it('renders action button when onActionPress is provided', () => { const onActionPress = vi.fn(); render( , ); const actionButton = screen.getByRole('button', { name: 'Custom Action', }); expect(actionButton).toBeInTheDocument(); fireEvent.click(actionButton); expect(onActionPress).toHaveBeenCalled(); }); it('applies custom class names to token elements when no action is provided', () => { const customClassNames = { tokenName: 'custom-name', tokenValue: 'custom-value', fiatValue: 'custom-fiat', }; render(); expect(screen.getByText('Ethereum')).toHaveClass('custom-name'); expect(screen.getByText('0.000 ETH')).toHaveClass('custom-value'); expect(screen.getByText('$3,300.00')).toHaveClass('custom-fiat'); }); it('applies custom class names to token elements when action is provided', () => { const customClassNames = { tokenName: 'custom-name', tokenValue: 'custom-value', action: 'custom-action', }; render( {}} />, ); expect(screen.getByText('Ethereum')).toHaveClass('custom-name'); expect(screen.getByText('0.000 ETH')).toHaveClass('custom-value'); expect(screen.getByTestId('ockTokenBalanceAction')).toHaveClass( 'custom-action', ); }); it('handles token with empty/null name', () => { const tokenWithoutName = { ...mockToken, name: null as unknown as string, }; render( , ); const nameElement = screen.getByText('', { selector: 'span.font-ock.font-semibold', }); expect(nameElement).toBeInTheDocument(); }); it('handles token size prop correctly', () => { const customSize = 60; render( , ); const imageContainer = screen.getByTestId('ockTokenImage_NoImage'); expect(imageContainer).toHaveStyle({ width: `${customSize}px`, height: `${customSize}px`, minWidth: `${customSize}px`, minHeight: `${customSize}px`, }); }); }); });