import { render, screen, fireEvent } from '@testing-library/react';
import {
RenderWithdrawButton,
type RenderWithdrawButtonProps,
} from './RenderWithdrawButton';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { TransactionReceipt } from 'node_modules/viem/_types/types/transaction';
vi.mock('@/internal/components/Spinner', () => ({
Spinner: () =>
Loading...
,
}));
describe('RenderWithdrawButton', () => {
const defaultProps = {
context: {
receipt: null,
errorMessage: null,
isLoading: false,
},
onSubmit: vi.fn(),
onSuccess: vi.fn(),
isDisabled: false,
withdrawAmountError: null,
withdrawnAmount: '100',
vaultToken: { symbol: 'ETH' },
} as unknown as RenderWithdrawButtonProps;
afterEach(() => {
vi.clearAllMocks();
});
it('renders withdraw button in default state', () => {
const button = RenderWithdrawButton(defaultProps);
render(button);
const buttonElement = screen.getByRole('button', { name: 'Withdraw' });
expect(buttonElement).toBeInTheDocument();
expect(buttonElement).not.toBeDisabled();
fireEvent.click(buttonElement);
expect(defaultProps.onSubmit).toHaveBeenCalledTimes(1);
});
it('renders disabled withdraw button', () => {
const button = RenderWithdrawButton({
...defaultProps,
isDisabled: true,
});
render(button);
const buttonElement = screen.getByRole('button', { name: 'Withdraw' });
expect(buttonElement).toBeInTheDocument();
expect(buttonElement).toBeDisabled();
});
it('renders loading state with spinner', () => {
const button = RenderWithdrawButton({
...defaultProps,
context: {
...defaultProps.context,
isLoading: true,
},
});
render(button);
const buttonElement = screen.getByRole('button');
const spinner = screen.getByTestId('spinner');
expect(buttonElement).toBeInTheDocument();
expect(spinner).toBeInTheDocument();
});
it('renders error state with error message', () => {
const errorMessage = 'Insufficient funds';
const button = RenderWithdrawButton({
...defaultProps,
context: {
...defaultProps.context,
errorMessage: 'Some error occurred',
},
withdrawAmountError: errorMessage,
});
render(button);
const buttonElement = screen.getByRole('button', { name: errorMessage });
expect(buttonElement).toBeInTheDocument();
fireEvent.click(buttonElement);
expect(defaultProps.onSubmit).toHaveBeenCalledTimes(1);
});
it('renders error state with default message when withdrawAmountError is null', () => {
const button = RenderWithdrawButton({
...defaultProps,
context: {
...defaultProps.context,
errorMessage: 'Some error occurred',
},
withdrawAmountError: null,
});
render(button);
const buttonElement = screen.getByRole('button', { name: 'Try again' });
expect(buttonElement).toBeInTheDocument();
});
it('renders success state with withdrawn amount', () => {
const button = RenderWithdrawButton({
...defaultProps,
context: {
...defaultProps.context,
receipt: {} as unknown as TransactionReceipt,
},
});
render(button);
const expectedText = `Withdrew ${defaultProps.withdrawnAmount} ${defaultProps?.vaultToken?.symbol}`;
const buttonElement = screen.getByRole('button', { name: expectedText });
expect(buttonElement).toBeInTheDocument();
fireEvent.click(buttonElement);
expect(defaultProps.onSuccess).toHaveBeenCalledTimes(1);
});
it('handles missing vaultToken gracefully', () => {
const button = RenderWithdrawButton({
...defaultProps,
vaultToken: undefined,
context: {
...defaultProps.context,
receipt: {} as unknown as TransactionReceipt,
},
});
render(button);
const expectedText = `Withdrew ${defaultProps.withdrawnAmount} undefined`;
const buttonElement = screen.getByRole('button', { name: expectedText });
expect(buttonElement).toBeInTheDocument();
});
});