From 61b134feb16a39a421622aec85ce07929509ec77 Mon Sep 17 00:00:00 2001 From: Paul Cramer Date: Mon, 12 Aug 2024 12:27:45 -0700 Subject: [PATCH] chore: Add transaction provider tests. --- .../components/TransactionProvider.test.tsx | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/src/transaction/components/TransactionProvider.test.tsx b/src/transaction/components/TransactionProvider.test.tsx index b6a2508005..1031a68091 100644 --- a/src/transaction/components/TransactionProvider.test.tsx +++ b/src/transaction/components/TransactionProvider.test.tsx @@ -5,8 +5,11 @@ import { useSwitchChain, useWaitForTransactionReceipt, } from 'wagmi'; +import { useConfig } from 'wagmi'; +import { waitForTransactionReceipt } from 'wagmi/actions'; import { useCallsStatus } from '../hooks/useCallsStatus'; import { useWriteContract } from '../hooks/useWriteContract'; + import { useWriteContracts } from '../hooks/useWriteContracts'; import { TransactionProvider, @@ -175,6 +178,123 @@ describe('TransactionProvider', () => { expect(testComponent.textContent).toBe('true'); }); }); + + it('should not fetch receipts if contract list is empty', async () => { + const waitForTransactionReceiptMock = vi.fn(); + render( + + + , + ); + const button = screen.getByText('Submit'); + fireEvent.click(button); + await waitFor(() => { + expect(waitForTransactionReceiptMock).not.toHaveBeenCalled(); + }); + }); + + it('should handle user rejected request', async () => { + const writeContractsAsyncMock = vi + .fn() + .mockRejectedValue({ cause: { name: 'UserRejectedRequestError' } }); + (useWriteContracts as ReturnType).mockReturnValue({ + statusWriteContracts: 'IDLE', + writeContractsAsync: writeContractsAsyncMock, + }); + + render( + + + , + ); + + const button = screen.getByText('Submit'); + fireEvent.click(button); + + await waitFor(() => { + const errorMessage = screen.getByTestId('context-value-errorMessage'); + expect(errorMessage.textContent).toBe('Request denied.'); + }); + }); + + it('should call onSuccess when receipts are available', async () => { + const onSuccessMock = vi.fn(); + (useWaitForTransactionReceipt as ReturnType).mockReturnValue({ + data: { status: 'success' }, + }); + (useCallsStatus as ReturnType).mockReturnValue({ + transactionHash: 'hash', + }); + + render( + + + , + ); + + await waitFor(() => { + expect(onSuccessMock).toHaveBeenCalledWith({ + transactionReceipts: [{ status: 'success' }], + }); + }); + }); + + it('should handle chain switching', async () => { + const switchChainAsyncMock = vi.fn(); + (useSwitchChain as ReturnType).mockReturnValue({ + switchChainAsync: switchChainAsyncMock, + }); + (useAccount as ReturnType).mockReturnValue({ chainId: 1 }); + + render( + + + , + ); + + const button = screen.getByText('Submit'); + fireEvent.click(button); + + await waitFor(() => { + expect(switchChainAsyncMock).toHaveBeenCalledWith({ chainId: 2 }); + }); + }); + + it('should handle generic error during fallback', async () => { + const writeContractsAsyncMock = vi + .fn() + .mockRejectedValue(new Error('Method not supported')); + const writeContractAsyncMock = vi + .fn() + .mockRejectedValue(new Error('Generic error')); + (useWriteContracts as ReturnType).mockReturnValue({ + statusWriteContracts: 'IDLE', + writeContractsAsync: writeContractsAsyncMock, + }); + (useWriteContract as ReturnType).mockReturnValue({ + status: 'IDLE', + writeContractAsync: writeContractAsyncMock, + }); + + render( + + + , + ); + + const button = screen.getByText('Submit'); + fireEvent.click(button); + + await waitFor(() => { + expect(screen.getByTestId('context-value-errorMessage').textContent).toBe( + 'Something went wrong. Please try again.', + ); + }); + }); }); describe('useTransactionContext', () => { @@ -185,7 +305,7 @@ describe('useTransactionContext', () => { }; const consoleError = vi .spyOn(console, 'error') - .mockImplementation(() => {}); // Suppress error logging + .mockImplementation(() => {}); expect(() => render()).toThrow( 'useTransactionContext must be used within a Transaction component', );