vega-frontend-monorepo/libs/web3/src/lib/use-ethereum-transaction.spec.tsx
2022-11-04 10:47:53 +00:00

132 lines
3.5 KiB
TypeScript

import { renderHook, act } from '@testing-library/react';
import { EthTxStatus } from './use-ethereum-transaction';
import { useEthereumTransaction } from './use-ethereum-transaction';
import type { ethers } from 'ethers';
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
class MockContract {
static txHash = 'tx-hash';
contract = {
callStatic: {
deposit_asset() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 10);
});
},
},
} as unknown as ethers.Contract;
deposit_asset(assetSource: string, amount: string, vegaPublicKey: string) {
return Promise.resolve({
hash: MockContract.txHash,
wait: () => {
confirmations++;
return new Promise((resolve) => {
setTimeout(() => {
resolve({
from: 'foo',
confirmations,
} as ethers.ContractReceipt);
}, 100);
});
},
} as ethers.ContractTransaction);
}
}
let confirmations = 0;
const mockContract = new MockContract();
const requiredConfirmations = 3;
function setup(methodName: 'deposit_asset' = 'deposit_asset') {
return renderHook(() =>
useEthereumTransaction<MockContract, 'deposit_asset'>(
mockContract,
methodName,
requiredConfirmations
)
);
}
it('Ethereum transaction flow', async () => {
const { result } = setup();
expect(result.current).toEqual({
transaction: {
status: EthTxStatus.Default,
txHash: null,
error: null,
confirmations: 0,
receipt: null,
dialogOpen: false,
},
Dialog: expect.any(Function),
TxContent: expect.any(Object),
setConfirmed: expect.any(Function),
perform: expect.any(Function),
reset: expect.any(Function),
});
act(() => {
result.current.perform('asset-source', '100', 'vega-key');
});
expect(result.current.transaction.status).toEqual(EthTxStatus.Requested); // still default as we await result of static call
expect(result.current.transaction.confirmations).toBe(0);
await act(async () => {
jest.advanceTimersByTime(10);
});
expect(result.current.transaction.status).toEqual(EthTxStatus.Pending);
expect(result.current.transaction.txHash).toEqual(MockContract.txHash);
expect(result.current.transaction.confirmations).toBe(0);
await act(async () => {
jest.advanceTimersByTime(100);
});
expect(result.current.transaction.confirmations).toBe(1);
expect(result.current.transaction.status).toEqual(EthTxStatus.Pending);
await act(async () => {
jest.advanceTimersByTime(100);
});
expect(result.current.transaction.confirmations).toBe(2);
expect(result.current.transaction.status).toEqual(EthTxStatus.Pending);
await act(async () => {
jest.advanceTimersByTime(100);
});
expect(result.current.transaction.confirmations).toBe(3);
// Now complete as required confirmations have been surpassed
expect(result.current.transaction.status).toEqual(EthTxStatus.Confirmed);
expect(result.current.transaction.receipt).toEqual({
from: 'foo',
confirmations: result.current.transaction.confirmations,
});
});
describe('error handling', () => {
it('ensures correct method is used', async () => {
const { result } = setup('non-existing-method' as 'deposit_asset');
act(() => {
result.current.perform('asset-rouce', '100', 'vega-key');
});
expect(result.current.transaction.status).toEqual(EthTxStatus.Error);
});
});