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`,
});
});
});
});