vega-frontend-monorepo/libs/wallet/src/use-vega-transaction-manager.spec.tsx

124 lines
3.7 KiB
TypeScript

import { useVegaTransactionManager } from './use-vega-transaction-manager';
import { renderHook } from '@testing-library/react';
import waitForNextTick from 'flush-promises';
import type { TransactionResponse } from './connectors/vega-connector';
import type {
VegaTransactionStore,
VegaStoredTxState,
} from './use-vega-transaction-store';
import { VegaTxStatus } from './use-vega-transaction';
const mockSendTx = jest.fn<Promise<Partial<TransactionResponse> | null>, []>();
const pubKey = 'pubKey';
const mockDisconnect = jest.fn();
jest.mock('./use-vega-wallet', () => ({
useVegaWallet: () => ({
sendTx: mockSendTx,
pubKey,
disconnect: mockDisconnect,
}),
}));
const transactionHash = 'txHash';
const signature = 'signature';
const receivedAt = 'receivedAt';
const sentAt = 'sentAt';
const transactionResponse: TransactionResponse = {
transactionHash,
signature,
receivedAt,
sentAt,
};
const pendingTransactionUpdate = {
status: VegaTxStatus.Pending,
txHash: transactionHash,
signature,
};
const update = jest.fn();
const del = jest.fn();
const defaultState: Partial<VegaTransactionStore> = {
transactions: [
{
id: 0,
status: VegaTxStatus.Requested,
} as VegaStoredTxState,
{
id: 1,
status: VegaTxStatus.Requested,
} as VegaStoredTxState,
],
update,
delete: del,
};
const mockTransactionStoreState = jest.fn<Partial<VegaTransactionStore>, []>();
jest.mock('./use-vega-transaction-store', () => ({
useVegaTransactionStore: (
selector: (state: Partial<VegaTransactionStore>) => void
) => selector(mockTransactionStoreState()),
}));
describe('useVegaTransactionManager', () => {
beforeEach(() => {
update.mockReset();
del.mockReset();
mockSendTx.mockReset();
mockTransactionStoreState.mockReset();
});
it('sendTx of first pending transaction', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
mockSendTx.mockResolvedValue(transactionResponse);
let result = renderHook(useVegaTransactionManager);
result.rerender();
expect(update).not.toBeCalled();
await waitForNextTick();
expect(update.mock.calls[0]).toEqual([0, pendingTransactionUpdate]);
expect(update.mock.calls[1]).toEqual([1, pendingTransactionUpdate]);
update.mockReset();
result = renderHook(useVegaTransactionManager);
await waitForNextTick();
expect(update).toBeCalled();
expect(update.mock.calls[0]).toEqual([0, pendingTransactionUpdate]);
result.rerender();
await waitForNextTick();
expect(update.mock.calls[1]).toEqual([1, pendingTransactionUpdate]);
});
it('del transaction on null response', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
mockSendTx.mockResolvedValue(null);
renderHook(useVegaTransactionManager);
await waitForNextTick();
expect(update).not.toBeCalled();
expect(del).toBeCalled();
});
it('sets error on reject', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
mockSendTx.mockRejectedValue(null);
renderHook(useVegaTransactionManager);
await waitForNextTick();
expect(mockDisconnect).not.toHaveBeenCalledWith();
expect(update).toBeCalled();
expect(update.mock.calls[0][1]?.status).toEqual(VegaTxStatus.Error);
});
it('call disconnect if detect no service error', async () => {
mockTransactionStoreState.mockReturnValue(defaultState);
mockSendTx.mockRejectedValue(new TypeError('Failed to fetch'));
renderHook(useVegaTransactionManager);
await waitForNextTick();
expect(mockDisconnect).toHaveBeenCalledWith();
expect(update).toBeCalled();
expect(update.mock.calls[0][1]?.status).toEqual(VegaTxStatus.Error);
});
});