You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
7.5 KiB
257 lines
7.5 KiB
import { cleanup, renderHook } from '@testing-library/react-hooks';
|
|
import { useSelector } from 'react-redux';
|
|
import { GAS_ESTIMATE_TYPES } from '../../shared/constants/gas';
|
|
import createRandomId from '../../shared/modules/random-id';
|
|
import {
|
|
getGasEstimateType,
|
|
getGasFeeEstimates,
|
|
getIsGasEstimatesLoading,
|
|
} from '../ducks/metamask/metamask';
|
|
import { checkNetworkAndAccountSupports1559 } from '../selectors';
|
|
import {
|
|
disconnectGasFeeEstimatePoller,
|
|
getGasFeeEstimatesAndStartPolling,
|
|
} from '../store/actions';
|
|
|
|
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
|
|
|
jest.mock('../store/actions', () => ({
|
|
disconnectGasFeeEstimatePoller: jest.fn(),
|
|
getGasFeeEstimatesAndStartPolling: jest.fn(),
|
|
addPollingTokenToAppState: jest.fn(),
|
|
removePollingTokenFromAppState: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('react-redux', () => {
|
|
const actual = jest.requireActual('react-redux');
|
|
|
|
return {
|
|
...actual,
|
|
useSelector: jest.fn(),
|
|
};
|
|
});
|
|
|
|
const DEFAULT_OPTS = {
|
|
checkNetworkAndAccountSupports1559: false,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,
|
|
gasFeeEstimates: {
|
|
low: '10',
|
|
medium: '20',
|
|
high: '30',
|
|
},
|
|
isGasEstimatesLoading: true,
|
|
};
|
|
|
|
const generateUseSelectorRouter = (opts = DEFAULT_OPTS) => (selector) => {
|
|
if (selector === checkNetworkAndAccountSupports1559) {
|
|
return (
|
|
opts.checkNetworkAndAccountSupports1559 ??
|
|
DEFAULT_OPTS.checkNetworkAndAccountSupports1559
|
|
);
|
|
}
|
|
if (selector === getGasEstimateType) {
|
|
return opts.gasEstimateType ?? DEFAULT_OPTS.gasEstimateType;
|
|
}
|
|
if (selector === getGasFeeEstimates) {
|
|
return opts.gasFeeEstimates ?? DEFAULT_OPTS.gasFeeEstimates;
|
|
}
|
|
if (selector === getIsGasEstimatesLoading) {
|
|
return opts.isGasEstimatesLoading ?? DEFAULT_OPTS.isGasEstimatesLoading;
|
|
}
|
|
return undefined;
|
|
};
|
|
|
|
describe('useGasFeeEstimates', () => {
|
|
let tokens = [];
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
tokens = [];
|
|
getGasFeeEstimatesAndStartPolling.mockImplementation(() => {
|
|
const token = createRandomId();
|
|
tokens.push(token);
|
|
return Promise.resolve(token);
|
|
});
|
|
disconnectGasFeeEstimatePoller.mockImplementation((token) => {
|
|
tokens = tokens.filter((tkn) => tkn !== token);
|
|
});
|
|
});
|
|
|
|
it('registers with the controller', () => {
|
|
useSelector.mockImplementation(generateUseSelectorRouter());
|
|
renderHook(() => useGasFeeEstimates());
|
|
expect(tokens).toHaveLength(1);
|
|
});
|
|
|
|
it('clears token with the controller on unmount', async () => {
|
|
useSelector.mockImplementation(generateUseSelectorRouter());
|
|
renderHook(() => useGasFeeEstimates());
|
|
expect(tokens).toHaveLength(1);
|
|
const expectedToken = tokens[0];
|
|
await cleanup();
|
|
expect(getGasFeeEstimatesAndStartPolling).toHaveBeenCalledTimes(1);
|
|
expect(disconnectGasFeeEstimatePoller).toHaveBeenCalledWith(expectedToken);
|
|
expect(tokens).toHaveLength(0);
|
|
});
|
|
|
|
it('works with LEGACY gas prices', () => {
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
isGasEstimatesLoading: false,
|
|
}),
|
|
);
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates: DEFAULT_OPTS.gasFeeEstimates,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: false,
|
|
});
|
|
});
|
|
|
|
it('works with ETH_GASPRICE gas prices', () => {
|
|
const gasFeeEstimates = { gasPrice: '10' };
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE,
|
|
gasFeeEstimates,
|
|
isGasEstimatesLoading: false,
|
|
}),
|
|
);
|
|
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: false,
|
|
});
|
|
});
|
|
|
|
it('works with FEE_MARKET gas prices', () => {
|
|
const gasFeeEstimates = {
|
|
low: {
|
|
minWaitTimeEstimate: 180000,
|
|
maxWaitTimeEstimate: 300000,
|
|
suggestedMaxPriorityFeePerGas: '3',
|
|
suggestedMaxFeePerGas: '53',
|
|
},
|
|
medium: {
|
|
minWaitTimeEstimate: 15000,
|
|
maxWaitTimeEstimate: 60000,
|
|
suggestedMaxPriorityFeePerGas: '7',
|
|
suggestedMaxFeePerGas: '70',
|
|
},
|
|
high: {
|
|
minWaitTimeEstimate: 0,
|
|
maxWaitTimeEstimate: 15000,
|
|
suggestedMaxPriorityFeePerGas: '10',
|
|
suggestedMaxFeePerGas: '100',
|
|
},
|
|
estimatedBaseFee: '50',
|
|
};
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
checkNetworkAndAccountSupports1559: true,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
|
|
gasFeeEstimates,
|
|
isGasEstimatesLoading: false,
|
|
}),
|
|
);
|
|
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: false,
|
|
});
|
|
});
|
|
|
|
it('indicates that gas estimates are loading when gasEstimateType is NONE', () => {
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.NONE,
|
|
gasFeeEstimates: {},
|
|
}),
|
|
);
|
|
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates: {},
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.NONE,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: true,
|
|
});
|
|
});
|
|
|
|
it('indicates that gas estimates are loading when gasEstimateType is not FEE_MARKET or ETH_GASPRICE, but network supports EIP-1559', () => {
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
checkNetworkAndAccountSupports1559: true,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,
|
|
gasFeeEstimates: {
|
|
gasPrice: '10',
|
|
},
|
|
}),
|
|
);
|
|
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates: { gasPrice: '10' },
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: true,
|
|
});
|
|
});
|
|
|
|
it('indicates that gas estimates are loading when gasEstimateType is FEE_MARKET but network does not support EIP-1559', () => {
|
|
const gasFeeEstimates = {
|
|
low: {
|
|
minWaitTimeEstimate: 180000,
|
|
maxWaitTimeEstimate: 300000,
|
|
suggestedMaxPriorityFeePerGas: '3',
|
|
suggestedMaxFeePerGas: '53',
|
|
},
|
|
medium: {
|
|
minWaitTimeEstimate: 15000,
|
|
maxWaitTimeEstimate: 60000,
|
|
suggestedMaxPriorityFeePerGas: '7',
|
|
suggestedMaxFeePerGas: '70',
|
|
},
|
|
high: {
|
|
minWaitTimeEstimate: 0,
|
|
maxWaitTimeEstimate: 15000,
|
|
suggestedMaxPriorityFeePerGas: '10',
|
|
suggestedMaxFeePerGas: '100',
|
|
},
|
|
estimatedBaseFee: '50',
|
|
};
|
|
useSelector.mockImplementation(
|
|
generateUseSelectorRouter({
|
|
checkNetworkAndAccountSupports1559: false,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
|
|
gasFeeEstimates,
|
|
}),
|
|
);
|
|
|
|
const {
|
|
result: { current },
|
|
} = renderHook(() => useGasFeeEstimates());
|
|
expect(current).toMatchObject({
|
|
gasFeeEstimates,
|
|
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
|
|
estimatedGasFeeTimeBounds: undefined,
|
|
isGasEstimatesLoading: true,
|
|
});
|
|
});
|
|
});
|
|
|