import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { fireEvent, render, screen } from '@testing-library/react'; import { baseSepolia } from 'viem/chains'; import { type Mock, beforeEach, describe, expect, it, vi } from 'vitest'; import { http, WagmiProvider, createConfig, mock, useAccount, useConnect, } from 'wagmi'; import { useDepositButton } from '../hooks/useDepositButton'; import { useAppchainBridgeContext } from './AppchainBridgeProvider'; import { AppchainBridgeTransactionButton } from './AppchainBridgeTransactionButton'; const queryClient = new QueryClient(); const mockConfig = createConfig({ chains: [baseSepolia], connectors: [ mock({ accounts: ['0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'], }), ], transports: { [baseSepolia.id]: http(), }, }); const wrapper = ({ children }: { children: React.ReactNode }) => ( {children} ); vi.mock('wagmi', async (importOriginal) => { return { ...(await importOriginal()), useAccount: vi.fn(), useConnect: vi.fn(), }; }); vi.mock('./AppchainBridgeProvider', () => ({ useAppchainBridgeContext: vi.fn(), })); vi.mock('../hooks/useDepositButton', () => ({ useDepositButton: vi.fn(), })); describe('AppchainBridgeTransactionButton', () => { const mockHandleDeposit = vi.fn(); const mockHandleWithdraw = vi.fn(); const mockConnect = vi.fn(); beforeEach(() => { vi.resetAllMocks(); (useAccount as Mock).mockReturnValue({ isConnected: true, }); (useConnect as Mock).mockReturnValue({ connect: mockConnect, }); (useAppchainBridgeContext as Mock).mockReturnValue({ handleDeposit: mockHandleDeposit, handleWithdraw: mockHandleWithdraw, depositStatus: 'idle', withdrawStatus: 'idle', direction: 'deposit', bridgeParams: { amount: '1', token: { symbol: 'ETH', }, }, }); (useDepositButton as Mock).mockReturnValue({ isRejected: false, buttonContent: 'Confirm', isDisabled: false, }); }); it('renders with default state', () => { render(, { wrapper }); expect(screen.getByText('Confirm')).toBeInTheDocument(); }); it('handles deposit direction correctly', async () => { render(, { wrapper }); const button = screen.getByRole('button'); fireEvent.click(button); expect(mockHandleDeposit).toHaveBeenCalled(); }); it('handles withdraw direction correctly', () => { (useAppchainBridgeContext as Mock).mockReturnValue({ ...useAppchainBridgeContext(), direction: 'withdraw', }); render(, { wrapper }); const button = screen.getByRole('button'); fireEvent.click(button); expect(mockHandleWithdraw).toHaveBeenCalled(); }); it('disables button when isDisabled is true', () => { (useDepositButton as Mock).mockReturnValue({ isRejected: false, buttonContent: 'Confirm', isDisabled: true, }); render(, { wrapper }); const button = screen.getByRole('button'); expect(button).toBeDisabled(); }); it('shows error message when transaction is rejected', () => { (useDepositButton as Mock).mockReturnValue({ isRejected: true, buttonContent: 'Confirm', isDisabled: false, }); render(, { wrapper }); expect(screen.getByText('Transaction denied')).toBeInTheDocument(); }); it('shows loading state during transaction', () => { (useDepositButton as Mock).mockReturnValue({ isRejected: false, buttonContent: 'Processing...', isDisabled: true, }); render(, { wrapper }); expect(screen.getByText('Processing...')).toBeInTheDocument(); }); });