Skip to content

Commit

Permalink
refactor: add contract concern dependency (#3424)
Browse files Browse the repository at this point in the history
* Add contract concern dependency
  • Loading branch information
agualis authored May 24, 2023
1 parent 21823d4 commit 87974b0
Show file tree
Hide file tree
Showing 21 changed files with 114 additions and 39 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ module.exports = {
message:
'Please import from src/dependencies to make this dependency more testable',
},
{
group: ['@/services/web3/transactions/concerns/contract.concern'],
importNames: ['ContractConcern'],
message:
'Please import from src/dependencies to make this dependency more testable',
},
// {
// group: ['@/services/multicalls/multicaller'],
// importNames: ['Multicaller'],
Expand Down
2 changes: 0 additions & 2 deletions src/composables/queries/usePoolsQuery.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
defaultPool2,
initPoolsFallbackRepositoryWithDefaultMocks,
} from '@/dependencies/PoolsFallbackRepository.mocks';
import { initRpcProviderServiceWithDefaultMocks } from '@/dependencies/rpc-provider.service.mocks';
import {
mountComposableWithFakeTokensProvider as mountComposable,
waitForQueryData,
Expand All @@ -15,7 +14,6 @@ import usePoolsQuery from './usePoolsQuery';

initPoolsFallbackRepositoryWithDefaultMocks();
initMulticallWithDefaultMocks();
initRpcProviderServiceWithDefaultMocks();

async function mountPoolsQuery(poolsSortField = '') {
const filterTokens = ref([]);
Expand Down
30 changes: 30 additions & 0 deletions src/dependencies/contract.concern.mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
// eslint-disable-next-line no-restricted-imports
ContractConcern,
SendTransactionOpts,
} from '@/services/web3/transactions/concerns/contract.concern';
import { initContractConcern } from './contract.concern';
import { aSigner } from '@tests/unit/builders/signer';
import { TransactionResponse } from '@ethersproject/abstract-provider';
import { mock } from 'vitest-mock-extended';

export const defaultContractTransactionResponse = mock<TransactionResponse>();
defaultContractTransactionResponse.chainId = 5;

export const sendTransactionMock = vi.fn(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(opts: SendTransactionOpts) =>
Promise.resolve(defaultContractTransactionResponse)
);

export class MockedContractConcern extends ContractConcern {
constructor() {
super(aSigner());
}

sendTransaction = (opts: SendTransactionOpts) => sendTransactionMock(opts);
}

export function initContractConcernWithDefaultMocks() {
initContractConcern(MockedContractConcern);
}
23 changes: 23 additions & 0 deletions src/dependencies/contract.concern.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// eslint-disable-next-line no-restricted-imports
import { ContractConcern } from '@/services/web3/transactions/concerns/contract.concern';
import { handleDependencyError } from '.';

let contractConcern: typeof ContractConcern | undefined;

/**
* initContractConcern uses the real Contract Concern instance by default but allows injecting Contract Concern mocks from tests
*/
export function initContractConcern(
contractConcernInstance: typeof ContractConcern = ContractConcern
) {
contractConcern = contractConcernInstance;
}

export function getContractConcern() {
if (!contractConcern) {
handleDependencyError('Contract Concern');
}
return contractConcern;
}

export type ContractConcernType = ContractConcern;
2 changes: 2 additions & 0 deletions src/dependencies/default-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { initMulticallerWithDefaultMocks } from './Multicaller.mocks';
import { initWalletConnectorsWithDefaultMocks } from './wallets/default-mocks';
import { initBalancerApiWithDefaultMocks } from './balancer-api.mocks';
import { initPoolsFallbackRepositoryWithDefaultMocks } from './PoolsFallbackRepository.mocks';
import { initContractConcernWithDefaultMocks } from './contract.concern.mocks';

export function initDependenciesWithDefaultMocks() {
initMulticallWithDefaultMocks();
Expand All @@ -19,4 +20,5 @@ export function initDependenciesWithDefaultMocks() {
initEthersContractWithDefaultMocks();
initWalletConnectorsWithDefaultMocks();
initPoolsFallbackRepositoryWithDefaultMocks();
initContractConcernWithDefaultMocks();
}
2 changes: 2 additions & 0 deletions src/dependencies/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { initOldMulticaller } from './OldMulticaller';
import { initRpcProviderService } from './rpc-provider.service';
import { initWalletConnectors } from './wallets';
import { initWeb3Provider } from './wallets/Web3Provider';
import { initContractConcern } from './contract.concern';

export function initDependencies() {
// We exclude the heavy dependencies to save bundle size:
Expand All @@ -20,6 +21,7 @@ export function initDependencies() {
initEthersContract();
initWeb3Provider();
initWalletConnectors();
initContractConcern();
}

export function handleDependencyError(dependencyName: string): never {
Expand Down
4 changes: 2 additions & 2 deletions src/providers/local/exit-pool.provider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { initBalancerSdkWithDefaultMocks } from '@/dependencies/balancer-sdk.mocks';
import { initEthersContractWithDefaultMocks } from '@/dependencies/EthersContract.mocks';
import { initRpcProviderServiceWithDefaultMocks } from '@/dependencies/rpc-provider.service.mocks';
import { hasFetchedPoolsForSor } from '@/lib/balancer.sdk';
import { poolIdThatRequiresInternalBalanceExit } from '@/lib/config/goerli/pools';
import { ExactInExitHandler } from '@/services/balancer/pools/exits/handlers/exact-in-exit.handler';
Expand All @@ -12,10 +11,11 @@ import { mountComposableWithFakeTokensProvider as mountComposable } from '@tests
import { groAddress, wethAddress } from '@tests/unit/builders/address';
import waitForExpect from 'wait-for-expect';
import { exitPoolProvider } from './exit-pool.provider';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initEthersContractWithDefaultMocks();
initBalancerSdkWithDefaultMocks();
initRpcProviderServiceWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountExitPoolProvider(pool: Pool) {
// Pretend that pools for SOR were fetched
Expand Down
2 changes: 2 additions & 0 deletions src/providers/local/join-pool.provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import { anAmountIn } from '@tests/unit/builders/join-exit.builders';
import waitForExpect from 'wait-for-expect';
import { joinPoolProvider } from './join-pool.provider';
import { groAddress, wethAddress } from '@tests/unit/builders/address';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initEthersContractWithDefaultMocks();
initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountJoinPoolProvider(pool: Pool) {
const { result } = await mountComposable(() => joinPoolProvider(ref(pool)));
Expand Down
5 changes: 3 additions & 2 deletions src/providers/wallet.provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import { lsGet } from '@/lib/utils';
import { mountComposable } from '@tests/mount-helpers';
import { SANCTIONED_ADDRESS } from '@tests/msw/rest-handlers';
import { isBlockedAddress, useWallets } from './wallet.provider';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initContractConcernWithDefaultMocks();

describe('Given that VITE_WALLET_SCREENING is false', () => {
beforeAll(() => {
Expand Down Expand Up @@ -54,8 +57,6 @@ describe('Given that VITE_WALLET_SCREENING is true', () => {
});
});

// initDependenciesWithDefaultMocks();

async function mountWalletProvider() {
const { result } = mountComposable(() => useWallets());
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
defaultGasLimit,
defaultTransactionResponse,
} from '@tests/unit/builders/signer';
import { ref } from 'vue';
import { ExactInExitHandler } from './exact-in-exit.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountExactInExitHandler(pool: Pool) {
return new ExactInExitHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import {
defaultGasLimit,
defaultTransactionResponse,
} from '@tests/unit/builders/signer';
import { ref } from 'vue';
import { ExactOutExitHandler } from './exact-out-exit.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountExactOutExitHandler(pool: Pool) {
return new ExactOutExitHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import {
defaultGasLimit,
defaultTransactionResponse,
} from '@tests/unit/builders/signer';
import { ref } from 'vue';

import { GeneralisedExitHandler } from './generalised-exit.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountGeneralizedExitHandler(pool: Pool) {
return new GeneralisedExitHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import {
} from '@tests/unit/builders/signer';
import { ExitParams, ExitType } from './exit-pool.handler';
import { RecoveryExitHandler } from './recovery-exit.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountRecoveryExitHandler(pool: Pool) {
return new RecoveryExitHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';
import { getBalancerSDK } from '@/dependencies/balancer-sdk';
import { initBalancerSdkWithDefaultMocks } from '@/dependencies/balancer-sdk.mocks';
import { Web3ProviderMock } from '@/dependencies/wallets/wallet-connector-mocks';
import { vaultService } from '@/services/contracts/vault.service';
import { Pool } from '@/services/pool/types';
import { aWeightedPool } from '@/__mocks__/weighted-pool';
import { buildExitParams } from '@tests/unit/builders/join-exit.builders';
import { ref } from 'vue';
import { ExitType } from './exit-pool.handler';
import { SwapExitHandler } from './swap-exit.handler';
import { defaultTransactionResponse } from '@tests/unit/builders/signer';
import { silenceConsoleLog } from '@tests/unit/console';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

silenceConsoleLog(vi, message => message.includes('sendTransaction'));

async function mountSwapExitHandler(pool: Pool) {
return new SwapExitHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import {
} from '@tests/unit/builders/signer';
import { ExactInJoinHandler } from './exact-in-join.handler';
import { JoinParams } from './join-pool.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountExactInJoinHandler(pool: Pool) {
return new ExactInJoinHandler(ref(pool), getBalancerSDK());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
defaultGasLimit,
defaultTransactionResponse,
} from '@tests/unit/builders/signer';
import { ref } from 'vue';
import { GeneralisedJoinHandler } from './generalised-join.handler';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

initBalancerSdkWithDefaultMocks();
initContractConcernWithDefaultMocks();

async function mountGeneralizedJoinHandler(pool: Pool) {
return new GeneralisedJoinHandler(ref(pool), getBalancerSDK());
Expand Down
20 changes: 9 additions & 11 deletions src/services/contracts/vault.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { initEthersContractWithDefaultMocks } from '@/dependencies/EthersContract.mocks';
import {
FundManagement,
SingleSwap,
Expand All @@ -7,27 +6,26 @@ import {
} from '@balancer-labs/sdk';
import { BigNumber } from '@ethersproject/bignumber';

import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';
import { walletService } from '@/services/web3/wallet.service';
import { silenceConsoleLog } from '@tests/unit/console';
import { configService } from '../config/config.service';
import { SwapToken, SwapTokenType } from '../swap/swap.service';
import VaultService from './vault.service';
import { walletProviderMock } from './vault.service.mocks';

// @ts-ignore
walletService.setUserProvider(ref(walletProviderMock));
initContractConcernWithDefaultMocks();

const vaultService = new VaultService(configService, walletService);
walletService.setUserProvider(computed(() => walletProviderMock));

initEthersContractWithDefaultMocks();
const vaultService = new VaultService(configService, walletService);

const userAddress = '0xAAA00fB39c06E7b41bEdFf8A6a4e013666141d40';

//TODO: extract to helper that accepts rules callback
// Silence Contract and Params debug
vi.spyOn(console, 'log').mockImplementation(args => {
if (!args.startsWith('Contract') && !args.startsWith('Params'))
return console.warn(args);
});
silenceConsoleLog(
vi,
message => message.startsWith('Contract') && !message.startsWith('Params')
);

describe('vault.service', () => {
let swaps: SwapV2[] = [];
Expand Down
4 changes: 2 additions & 2 deletions src/services/swap/swap.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { AddressZero } from '@ethersproject/constants';

import { configService } from '@/services/config/config.service';

import { initEthersContractWithDefaultMocks } from '@/dependencies/EthersContract.mocks';
import { lidoRelayerService } from '@/services/contracts/lido-relayer.service';
import { vaultService } from '@/services/contracts/vault.service';
import { walletService } from '@/services/web3/wallet.service';
Expand All @@ -19,11 +18,12 @@ import {
} from '../contracts/vault.service.mocks';
import { setUserAddress } from '../web3/__mocks__/web3.service';
import { SwapService, SwapToken, SwapTokenType } from './swap.service';
import { initContractConcernWithDefaultMocks } from '@/dependencies/contract.concern.mocks';

vi.mock('@/lib/utils/balancer/lido');
vi.mock('@/services/contracts/lido-relayer.service');

initEthersContractWithDefaultMocks();
initContractConcernWithDefaultMocks();

walletService.setUserProvider(computed(() => walletProviderMock));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
getEthersContract,
} from '@/dependencies/EthersContract';

type SendTransactionOpts = {
export type SendTransactionOpts = {
contractAddress: string;
abi: ContractInterface;
action: string;
Expand Down
17 changes: 6 additions & 11 deletions src/services/web3/transactions/transaction.builder.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { initEthersContract } from '@/dependencies/EthersContract';
import { initContractConcern } from '@/dependencies/contract.concern';
import { MockedContractWithSigner } from '@/dependencies/EthersContract.mocks';
import { initOldMulticallerWithDefaultMocks } from '@/dependencies/OldMulticaller.mocks';
import { AddressZero } from '@ethersproject/constants';
Expand All @@ -7,6 +8,8 @@ import { ContractConcern } from './concerns/contract.concern';
import { RawConcern } from './concerns/raw.concern';
import { TransactionBuilder } from './transaction.builder';

initContractConcern();

vi.mock('@ethersproject/providers', () => {
return {
JsonRpcSigner: vi.fn().mockImplementation(() => {
Expand All @@ -21,7 +24,7 @@ vi.mock('@ethersproject/providers', () => {
}),
};
});
vi.mock('@/services/rpc-provider/rpc-provider.service');

vi.mock('@/services/gas/gas.service', () => {
return {
gasService: {
Expand All @@ -34,15 +37,6 @@ vi.mock('@/services/gas/gas.service', () => {
},
};
});
vi.mock('ethers', () => {
return {
Contract: vi.fn().mockImplementation(() => {
return {
test: vi.fn(),
};
}),
};
});

const contractActionMock = vi.fn(() => 1e5);

Expand All @@ -51,9 +45,10 @@ class ContractMock extends MockedContractWithSigner {
}

initOldMulticallerWithDefaultMocks();

//@ts-ignore
initEthersContract(ContractMock);
// Init real implementation to be tested
initContractConcern();

const SignerMock = JsonRpcSigner;

Expand Down
Loading

0 comments on commit 87974b0

Please sign in to comment.