UNPKG

@kadena/kadena-cli

Version:

Kadena CLI tool to interact with the Kadena blockchain (manage keys, transactions, etc.)

299 lines 12.4 kB
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { log } from '../../../utils/logger.js'; import { isSignedTransaction } from '@kadena/client'; import { displayTransactionResponse } from '../utils/txDisplayHelper.js'; import { getClient } from '../utils/txHelpers.js'; vi.mock('../utils/txDisplayHelper', () => ({ displayTransactionResponse: vi.fn(), })); vi.mock('@kadena/client', async () => { const actual = await vi.importActual('@kadena/client'); return { ...actual, isSignedTransaction: vi.fn(), }; }); vi.mock('../utils/txHelpers.js', async () => { const actual = await vi.importActual('../utils/txHelpers.js'); return { ...actual, getClient: vi.fn(), logTransactionDetails: vi.fn(), }; }); import { clientInstances, pollRequests, sendTransactionAction, } from '../commands/txSend.js'; describe('pollRequests wtihin txSend', () => { const mockClientInstances = new Map(); const mockClient = { pollStatus: vi.fn(), }; const originalClientInstances = new Map(clientInstances); beforeEach(() => { mockClientInstances.clear(); vi.resetAllMocks(); }); afterEach(() => { clientInstances.clear(); originalClientInstances.forEach((value, key) => clientInstances.set(key, value)); }); const mockTransaction = { cmd: '{"networkId":"network1","payload":{"exec":{"code":"","data":{}}},"signers":[],"meta":{"chainId":"0","sender":"","gasLimit":0,"gasPrice":0,"ttl":0,"creationTime":0},"nonce":"nonce"}', hash: 'hash', sigs: [], }; const mockNetworkDetails = { network: 'network1', networkHost: 'http://localhost', networkId: 'network1', chainId: '0', networkExplorerUrl: 'http://localhost/explorer', }; it('should log an error if no client is found for a request', async () => { const requestKeys = [ { requestKey: 'fakeRequestKey1', clientKey: 'clientKey1', details: mockNetworkDetails, transaction: mockTransaction, }, ]; const logErrorSpy = vi.spyOn(log, 'error'); await pollRequests(requestKeys); expect(logErrorSpy).toHaveBeenCalledWith('No client found for requestKey: fakeRequestKey1 with clientKey: clientKey1. Polling will not be done for this request.'); }); it('should handle polling success', async () => { mockClient.pollStatus = vi.fn().mockResolvedValue({ fakeRequestKey2: { status: 'success', data: 'mockData' }, }); clientInstances.set('clientKey2', mockClient); const requestKeys = [ { requestKey: 'fakeRequestKey2', clientKey: 'clientKey2', details: { ...mockNetworkDetails, networkId: 'network2', chainId: '1', }, transaction: mockTransaction, }, ]; const logInfoSpy = vi.spyOn(log, 'info'); await pollRequests(requestKeys); expect(logInfoSpy).toHaveBeenCalledWith('Polling success for requestKey: fakeRequestKey2'); expect(displayTransactionResponse).toHaveBeenCalledWith({ data: 'mockData', status: 'success', }, 2); }); it('should handle polling error', async () => { mockClient.pollStatus = vi .fn() .mockRejectedValue(new Error('Polling failed')); clientInstances.set('clientKey3', mockClient); const requestKeys = [ { requestKey: 'fakeRequestKey3', clientKey: 'clientKey3', details: { ...mockNetworkDetails, networkId: 'network3', chainId: '2', }, transaction: mockTransaction, }, ]; const logErrorSpy = vi.spyOn(log, 'error'); await pollRequests(requestKeys); expect(logErrorSpy).toHaveBeenCalledWith('Polling error for requestKey: fakeRequestKey3, error:', new Error('Polling failed')); }); it('should log an error if polling fails entirely', async () => { const requestKeys = [ { requestKey: 'fakeRequestKey5', clientKey: 'clientKey5', details: { ...mockNetworkDetails, networkId: 'network5', chainId: '4', }, transaction: mockTransaction, }, ]; const logErrorSpy = vi.spyOn(log, 'error'); await pollRequests(requestKeys); expect(logErrorSpy).toHaveBeenCalled(); }); it('should handle multiple request keys', async () => { mockClient.pollStatus = vi.fn().mockResolvedValue({ fakeRequestKey1: { status: 'success', data: 'mockData1' }, fakeRequestKey2: { status: 'success', data: 'mockData2' }, }); clientInstances.set('clientKey1', mockClient); const requestKeys = [ { requestKey: 'fakeRequestKey1', clientKey: 'clientKey1', details: mockNetworkDetails, transaction: mockTransaction, }, { requestKey: 'fakeRequestKey2', clientKey: 'clientKey1', details: mockNetworkDetails, transaction: mockTransaction, }, ]; const logInfoSpy = vi.spyOn(log, 'info'); await pollRequests(requestKeys); expect(logInfoSpy).toHaveBeenCalledWith('Polling success for requestKey: fakeRequestKey1'); expect(logInfoSpy).toHaveBeenCalledWith('Polling success for requestKey: fakeRequestKey2'); expect(displayTransactionResponse).toHaveBeenCalledWith({ data: 'mockData1', status: 'success', }, 2); expect(displayTransactionResponse).toHaveBeenCalledWith({ data: 'mockData2', status: 'success', }, 2); }); it('should handle partially successful polling', async () => { mockClient.pollStatus = vi .fn() .mockImplementationOnce(() => Promise.resolve({ fakeRequestKey1: { status: 'success', data: 'mockData' }, })) .mockImplementationOnce(() => Promise.reject(new Error('Polling failed'))); clientInstances.set('clientKey1', mockClient); const requestKeys = [ { requestKey: 'fakeRequestKey1', clientKey: 'clientKey1', details: mockNetworkDetails, transaction: mockTransaction, }, { requestKey: 'fakeRequestKey2', clientKey: 'clientKey1', details: mockNetworkDetails, transaction: mockTransaction, }, ]; const logInfoSpy = vi.spyOn(log, 'info'); const logErrorSpy = vi.spyOn(log, 'error'); await pollRequests(requestKeys); expect(logInfoSpy).toHaveBeenCalledWith('Polling success for requestKey: fakeRequestKey1'); expect(logErrorSpy).toHaveBeenCalledWith('Polling error for requestKey: fakeRequestKey2, error:', new Error('Polling failed')); }); }); describe('sendTransactionAction within txSend', () => { const mockClient = { local: vi.fn(), submit: vi.fn(), }; const mockCommand = { cmd: '{"networkId":"network1","payload":{"exec":{"code":"","data":{}}},"signers":[],"meta":{"chainId":"0","sender":"","gasLimit":0,"gasPrice":0,"ttl":0,"creationTime":0},"nonce":"nonce"}', hash: 'hash', sigs: [{ sig: 'signature' }], }; const mockUnsignedCommand = { cmd: '{"networkId":"network1","payload":{"exec":{"code":"","data":{}}},"signers":[],"meta":{"chainId":"0","sender":"","gasLimit":0,"gasPrice":0,"ttl":0,"creationTime":0},"nonce":"nonce"}', hash: 'hash', sigs: [], }; const mockNetworkDetails = { network: 'network1', networkHost: 'http://localhost', networkId: 'network1', chainId: '0', networkExplorerUrl: 'http://localhost/explorer', }; beforeEach(() => { vi.clearAllMocks(); getClient.mockReturnValue(mockClient); }); it('should process transactions successfully', async () => { isSignedTransaction.mockReturnValue(true); mockClient.local.mockResolvedValue({ result: { status: 'success' } }); mockClient.submit.mockResolvedValue({ requestKey: 'requestKey' }); const transactionsWithDetails = [ { command: mockCommand, details: mockNetworkDetails }, ]; const result = await sendTransactionAction({ transactionsWithDetails }); if (result.status === 'success') { expect(result.data.transactions).toHaveLength(1); expect(result.data.transactions[0].requestKey).toBe('requestKey'); } else { throw new Error('Expected result status to be success'); } }); it('should handle invalid signed transactions', async () => { isSignedTransaction.mockReturnValue(false); const transactionsWithDetails = [ { command: mockUnsignedCommand, details: mockNetworkDetails }, ]; const result = await sendTransactionAction({ transactionsWithDetails }); if (result.status === 'error') { expect(result.errors).toHaveLength(1); expect(result.errors[0]).toContain('Invalid signed transaction'); } else { throw new Error('Expected result status to be error'); } }); it('should handle errors during local call', async () => { isSignedTransaction.mockReturnValue(true); mockClient.local.mockResolvedValue({ result: { status: 'failure', error: new Error('Local call failed') }, }); const transactionsWithDetails = [ { command: mockCommand, details: mockNetworkDetails }, ]; const result = await sendTransactionAction({ transactionsWithDetails }); if (result.status === 'error') { expect(result.errors).toHaveLength(1); expect(result.errors[0]).toContain('Error in processing transaction'); } else { throw new Error('Expected result status to be error'); } }); it('should handle errors during submit call', async () => { isSignedTransaction.mockReturnValue(true); mockClient.local.mockResolvedValue({ result: { status: 'success' } }); mockClient.submit.mockRejectedValue(new Error('Submit call failed')); const transactionsWithDetails = [ { command: mockCommand, details: mockNetworkDetails }, ]; const result = await sendTransactionAction({ transactionsWithDetails }); if (result.status === 'error') { expect(result.errors).toHaveLength(1); expect(result.errors[0]).toContain('Error in processing transaction'); } else { throw new Error('Expected result status to be error'); } }); it('should handle partial success with warnings', async () => { isSignedTransaction.mockReturnValue(true); mockClient.local.mockResolvedValueOnce({ result: { status: 'success' } }); mockClient.local.mockResolvedValueOnce({ result: { status: 'failure', error: new Error('Local call failed') }, }); mockClient.submit.mockResolvedValue({ requestKey: 'requestKey' }); const transactionsWithDetails = [ { command: mockCommand, details: mockNetworkDetails }, { command: mockCommand, details: mockNetworkDetails }, ]; const result = await sendTransactionAction({ transactionsWithDetails }); if (result.status === 'success') { expect(result.data.transactions).toHaveLength(1); expect(result.warnings).toHaveLength(1); } else { throw new Error('Expected result status to be success with warnings'); } }); }); //# sourceMappingURL=send.utils.test.js.map