import { etherJsFetcher } from '../src' import { BigNumber, Wallet } from 'ethers' import { Contract } from '@ethersproject/contracts' import { JsonRpcSigner, BaseProvider, Provider } from '@ethersproject/providers' import TestABI from './util/test.abi.json' import { providers } from '@0xsequence/multicall' jest.mock('@ethersproject/providers') jest.mock('@ethersproject/contracts') jest.mock('@0xsequence/multicall') const ProviderMock = BaseProvider as jest.Mocked<typeof BaseProvider> const mockedMultiCallProvider = (providers.MulticallProvider as unknown) as jest.Mock const ContractMock = Contract as jest.Mocked<any> // const mockedContract = (Contract as unknown) as jest.Mock const SignerMock = JsonRpcSigner as jest.Mocked<typeof JsonRpcSigner> const buildProviderMock = (balance = 1, transactionCount = 1) => { // const jsonRpcFetchFunc = jest.fn() const getBalanceMock = jest .fn() .mockImplementation(() => Promise.resolve(balance)) const getTransactionCountMock = jest .fn() .mockImplementation(() => Promise.resolve(transactionCount)) const provider = new ProviderMock('Network') provider.getTransactionCount = getTransactionCountMock provider.getBalance = getBalanceMock return provider } const buildSignerMock = (balance = 1, transactionCount = 1) => { const getBalanceMock = jest .fn() .mockImplementation(() => Promise.resolve(balance)) const getTransactionCountMock = jest .fn() .mockImplementation(() => Promise.resolve(transactionCount)) const signer = new SignerMock('0x00', 'provider' as any) as any // signer.provider signer.address signer.getBalance = getBalanceMock signer.getTransactionCount = getTransactionCountMock return signer } describe('ethFetcher', () => { let signer: Wallet beforeEach(() => { signer = buildSignerMock() }) it('is defined', () => { expect(etherJsFetcher).toBeDefined() }) it('return a fetcher', () => { const provider = buildProviderMock() expect(etherJsFetcher(provider)).toBeDefined() }) describe('eth', () => { it('return the balance of the signer', async () => { const balance = 1 const provider = buildProviderMock(balance) const fetcher = etherJsFetcher(provider) // SWR spreads the array when it invoke the fetcher await expect(fetcher(...['getBalance', signer.address])).resolves.toEqual( balance ) }) it('returns multiple balances', async () => { const balance = 1 mockedMultiCallProvider.mockReturnValue({ getBalance: () => Promise.resolve(balance) }) const provider = buildProviderMock(balance) const fetcher = etherJsFetcher(provider) // SWR spreads the array when it invoke the fetcher await expect( fetcher(JSON.stringify([['getBalance', signer.address]])) ).resolves.toEqual([balance]) }) it('return the getTransactionCount', async () => { const transactionCount = 3 const provider = buildProviderMock(undefined, transactionCount) const fetcher = etherJsFetcher(provider) const key = ['getTransactionCount'] // SWR spreads the array when it invoke the fetcher await expect(fetcher(...key)).resolves.toEqual(transactionCount) }) }) describe('contract', () => { let provider: BaseProvider let signer: Wallet beforeEach(() => { provider = buildProviderMock() signer = buildSignerMock() }) afterEach(() => { delete ContractMock.prototype.balanceOf }) it('return the value', async () => { const balance = 10 // workaround create a dynamic method ContractMock.prototype.balanceOf = jest .fn() .mockImplementation(() => Promise.resolve(balance)) const contract = '0x4592706f9e4E4292464967d16aa31c3d4a81a5A1' const ABIs = new Map([[contract, TestABI]]) const fetcher = etherJsFetcher(provider, ABIs) // SWR spreads the array when it invoke the fetcher await expect( fetcher(...[contract, 'balanceOf', signer.address]) ).resolves.toEqual(balance) }) it('return multiple values', async () => { const balance = 10 ContractMock.prototype.balanceOf = jest .fn() .mockImplementation(() => Promise.resolve(balance)) const contract = '0x4592706f9e4E4292464967d16aa31c3d4a81a5A1' const account = '0x4592706f9e4E4292464967d16aa31c3d4a81a5A1' const ABIs = new Map([[contract, TestABI]]) const fetcher = etherJsFetcher(provider, ABIs) // SWR spreads the array when it invoke the fetcher await expect( fetcher(JSON.stringify([[contract, 'balanceOf', account]])) ).resolves.toEqual([balance]) }) }) })