1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00
metamask-extension/ui/ducks/swaps/swaps.test.js
2023-06-15 20:17:21 +02:00

980 lines
34 KiB
JavaScript

import nock from 'nock';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { MOCKS, createSwapsMockStore } from '../../../test/jest';
import { setSwapsLiveness, setSwapsFeatureFlags } from '../../store/actions';
import { CHAIN_IDS } from '../../../shared/constants/network';
import { setStorageItem } from '../../../shared/lib/storage-helpers';
import swapsReducer, * as swaps from './swaps';
const middleware = [thunk];
jest.mock('../../store/actions.ts', () => ({
setSwapsLiveness: jest.fn(),
setSwapsFeatureFlags: jest.fn(),
fetchSmartTransactionsLiveness: jest.fn(),
getTransactions: jest.fn(() => {
return [];
}),
}));
const providerConfigState = {
chainId: '0x1',
nickname: '',
rpcPrefs: {},
rpcUrl: '',
ticker: 'ETH',
type: 'mainnet',
};
describe('Ducks - Swaps', () => {
afterEach(() => {
nock.cleanAll();
});
describe('fetchSwapsLivenessAndFeatureFlags', () => {
const cleanFeatureFlagApiCache = () => {
setStorageItem(
'cachedFetch:https://swap.metaswap.codefi.network/featureFlags',
null,
);
};
afterEach(() => {
cleanFeatureFlagApiCache();
});
const mockFeatureFlagsApiResponse = ({
featureFlagsResponse,
replyWithError = false,
} = {}) => {
const apiNock = nock('https://swap.metaswap.codefi.network').get(
'/featureFlags',
);
if (replyWithError) {
return apiNock.replyWithError({
message: 'Server error. Try again later',
code: 'serverSideError',
});
}
return apiNock.reply(200, featureFlagsResponse);
};
const createGetState = () => {
return () => ({
metamask: {
providerConfig: { ...providerConfigState },
from: '0x64a845a5b02460acf8a3d84503b0d68d028b4bb4',
},
});
};
it('checks that Swaps for ETH are enabled and can use new API', async () => {
const mockDispatch = jest.fn();
const expectedSwapsLiveness = {
swapsFeatureIsLive: true,
};
const featureFlagsResponse = MOCKS.createFeatureFlagsResponse();
const featureFlagApiNock = mockFeatureFlagsApiResponse({
featureFlagsResponse,
});
const swapsLiveness = await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock.isDone()).toBe(true);
expect(mockDispatch).toHaveBeenCalledTimes(4);
expect(setSwapsLiveness).toHaveBeenCalledWith(expectedSwapsLiveness);
expect(setSwapsFeatureFlags).toHaveBeenCalledWith(featureFlagsResponse);
expect(swapsLiveness).toMatchObject(expectedSwapsLiveness);
});
it('checks that Swaps for ETH are disabled for API v2 and enabled for API v1', async () => {
const mockDispatch = jest.fn();
const expectedSwapsLiveness = {
swapsFeatureIsLive: true,
};
const featureFlagsResponse = MOCKS.createFeatureFlagsResponse();
featureFlagsResponse.ethereum.extensionActive = false;
const featureFlagApiNock = mockFeatureFlagsApiResponse({
featureFlagsResponse,
});
const swapsLiveness = await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock.isDone()).toBe(true);
expect(mockDispatch).toHaveBeenCalledTimes(4);
expect(setSwapsLiveness).toHaveBeenCalledWith(expectedSwapsLiveness);
expect(setSwapsFeatureFlags).toHaveBeenCalledWith(featureFlagsResponse);
expect(swapsLiveness).toMatchObject(expectedSwapsLiveness);
});
it('checks that Swaps for ETH are disabled for API v1 and v2', async () => {
const mockDispatch = jest.fn();
const expectedSwapsLiveness = {
swapsFeatureIsLive: false,
};
const featureFlagsResponse = MOCKS.createFeatureFlagsResponse();
featureFlagsResponse.ethereum.extensionActive = false;
featureFlagsResponse.ethereum.fallbackToV1 = false;
const featureFlagApiNock = mockFeatureFlagsApiResponse({
featureFlagsResponse,
});
const swapsLiveness = await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock.isDone()).toBe(true);
expect(mockDispatch).toHaveBeenCalledTimes(4);
expect(setSwapsLiveness).toHaveBeenCalledWith(expectedSwapsLiveness);
expect(setSwapsFeatureFlags).toHaveBeenCalledWith(featureFlagsResponse);
expect(swapsLiveness).toMatchObject(expectedSwapsLiveness);
});
it('checks that Swaps for ETH are disabled if the /featureFlags API call throws an error', async () => {
const mockDispatch = jest.fn();
const expectedSwapsLiveness = {
swapsFeatureIsLive: false,
};
const featureFlagApiNock = mockFeatureFlagsApiResponse({
replyWithError: true,
});
const swapsLiveness = await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock.isDone()).toBe(true);
expect(mockDispatch).toHaveBeenCalledTimes(2);
expect(setSwapsLiveness).toHaveBeenCalledWith(expectedSwapsLiveness);
expect(swapsLiveness).toMatchObject(expectedSwapsLiveness);
});
it('only calls the API once and returns response from cache for the second call', async () => {
const mockDispatch = jest.fn();
const expectedSwapsLiveness = {
swapsFeatureIsLive: true,
};
const featureFlagsResponse = MOCKS.createFeatureFlagsResponse();
const featureFlagApiNock = mockFeatureFlagsApiResponse({
featureFlagsResponse,
});
await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock.isDone()).toBe(true);
const featureFlagApiNock2 = mockFeatureFlagsApiResponse({
featureFlagsResponse,
});
const swapsLiveness = await swaps.fetchSwapsLivenessAndFeatureFlags()(
mockDispatch,
createGetState(),
);
expect(featureFlagApiNock2.isDone()).toBe(false); // Second API call wasn't made, cache was used instead.
expect(mockDispatch).toHaveBeenCalledTimes(8);
expect(setSwapsLiveness).toHaveBeenCalledWith(expectedSwapsLiveness);
expect(setSwapsFeatureFlags).toHaveBeenCalledWith(featureFlagsResponse);
expect(swapsLiveness).toMatchObject(expectedSwapsLiveness);
});
});
describe('getCustomMaxPriorityFeePerGas', () => {
it('returns "customMaxPriorityFeePerGas"', () => {
const state = createSwapsMockStore();
const customMaxPriorityFeePerGas = '3';
state.metamask.swapsState.customMaxPriorityFeePerGas =
customMaxPriorityFeePerGas;
expect(swaps.getCustomMaxPriorityFeePerGas(state)).toBe(
customMaxPriorityFeePerGas,
);
});
});
describe('getAggregatorMetadata', () => {
it('returns agg metadata', () => {
const state = createSwapsMockStore();
expect(swaps.getAggregatorMetadata(state)).toBe(
state.swaps.aggregatorMetadata,
);
});
});
describe('getBalanceError', () => {
it('returns a balance error', () => {
const state = createSwapsMockStore();
state.swaps.balanceError = 'balanceError';
expect(swaps.getBalanceError(state)).toBe(state.swaps.balanceError);
});
});
describe('getFromToken', () => {
it('returns fromToken', () => {
const state = createSwapsMockStore();
expect(swaps.getFromToken(state)).toBe(state.swaps.fromToken);
});
});
describe('getFromTokenError', () => {
it('returns fromTokenError', () => {
const state = createSwapsMockStore();
state.swaps.fromTokenError = 'fromTokenError';
expect(swaps.getFromTokenError(state)).toBe(state.swaps.fromTokenError);
});
});
describe('getFromTokenInputValue', () => {
it('returns fromTokenInputValue', () => {
const state = createSwapsMockStore();
expect(swaps.getFromTokenInputValue(state)).toBe(
state.swaps.fromTokenInputValue,
);
});
});
describe('getIsFeatureFlagLoaded', () => {
it('returns isFeatureFlagLoaded', () => {
const state = createSwapsMockStore();
expect(swaps.getIsFeatureFlagLoaded(state)).toBe(
state.swaps.isFeatureFlagLoaded,
);
});
});
describe('getSwapsSTXLoading', () => {
it('returns swapsSTXLoading', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsSTXLoading(state)).toBe(state.swaps.swapsSTXLoading);
});
});
describe('getMaxSlippage', () => {
it('returns maxSlippage', () => {
const state = createSwapsMockStore();
expect(swaps.getMaxSlippage(state)).toBe(state.swaps.maxSlippage);
});
});
describe('getTopAssets', () => {
it('returns topAssets', () => {
const state = createSwapsMockStore();
expect(swaps.getTopAssets(state)).toBe(state.swaps.topAssets);
});
});
describe('getToToken', () => {
it('returns toToken', () => {
const state = createSwapsMockStore();
expect(swaps.getToToken(state)).toBe(state.swaps.toToken);
});
});
describe('getFetchingQuotes', () => {
it('returns fetchingQuotes', () => {
const state = createSwapsMockStore();
expect(swaps.getFetchingQuotes(state)).toBe(state.swaps.fetchingQuotes);
});
});
describe('getQuotesFetchStartTime', () => {
it('returns quotesFetchStartTime', () => {
const state = createSwapsMockStore();
expect(swaps.getQuotesFetchStartTime(state)).toBe(
state.swaps.quotesFetchStartTime,
);
});
});
describe('getReviewSwapClickedTimestamp', () => {
it('returns reviewSwapClickedTimestamp', () => {
const state = createSwapsMockStore();
expect(swaps.getReviewSwapClickedTimestamp(state)).toBe(
state.swaps.reviewSwapClickedTimestamp,
);
});
});
describe('getSwapsCustomizationModalPrice', () => {
it('returns customGas.price', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsCustomizationModalPrice(state)).toBe(
state.swaps.customGas.price,
);
});
});
describe('getSwapsCustomizationModalLimit', () => {
it('returns customGas.limit', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsCustomizationModalLimit(state)).toBe(
state.swaps.customGas.limit,
);
});
});
describe('swapGasPriceEstimateIsLoading', () => {
it('returns true for swapGasPriceEstimateIsLoading', () => {
const state = createSwapsMockStore();
state.swaps.customGas.loading = swaps.GAS_PRICES_LOADING_STATES.LOADING;
expect(swaps.swapGasPriceEstimateIsLoading(state)).toBe(true);
});
});
describe('swapGasEstimateLoadingHasFailed', () => {
it('returns true for swapGasEstimateLoadingHasFailed', () => {
const state = createSwapsMockStore();
state.swaps.customGas.loading = swaps.GAS_PRICES_LOADING_STATES.INITIAL;
expect(swaps.swapGasEstimateLoadingHasFailed(state)).toBe(true);
});
});
describe('getSwapGasPriceEstimateData', () => {
it('returns customGas.priceEstimates', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapGasPriceEstimateData(state)).toBe(
state.swaps.customGas.priceEstimates,
);
});
});
describe('getSwapsFallbackGasPrice', () => {
it('returns customGas.fallBackPrice', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsFallbackGasPrice(state)).toBe(
state.swaps.customGas.fallBackPrice,
);
});
});
describe('getCurrentSmartTransactionsError', () => {
it('returns currentSmartTransactionsError', () => {
const state = createSwapsMockStore();
state.swaps.currentSmartTransactionsError =
'currentSmartTransactionsError';
expect(swaps.getCurrentSmartTransactionsError(state)).toBe(
state.swaps.currentSmartTransactionsError,
);
});
});
describe('shouldShowCustomPriceTooLowWarning', () => {
it('returns false for showCustomPriceTooLowWarning', () => {
const state = createSwapsMockStore();
expect(swaps.shouldShowCustomPriceTooLowWarning(state)).toBe(false);
});
});
describe('getSwapsFeatureIsLive', () => {
it('returns true for "swapsFeatureIsLive"', () => {
const state = createSwapsMockStore();
const swapsFeatureIsLive = true;
state.metamask.swapsState.swapsFeatureIsLive = swapsFeatureIsLive;
expect(swaps.getSwapsFeatureIsLive(state)).toBe(swapsFeatureIsLive);
});
it('returns false for "swapsFeatureIsLive"', () => {
const state = createSwapsMockStore();
const swapsFeatureIsLive = false;
state.metamask.swapsState.swapsFeatureIsLive = swapsFeatureIsLive;
expect(swaps.getSwapsFeatureIsLive(state)).toBe(swapsFeatureIsLive);
});
});
describe('getSmartTransactionsError', () => {
it('returns smartTransactionsError', () => {
const state = createSwapsMockStore();
state.appState.smartTransactionsError = 'stxError';
expect(swaps.getSmartTransactionsError(state)).toBe(
state.appState.smartTransactionsError,
);
});
});
describe('getSmartTransactionsErrorMessageDismissed', () => {
it('returns smartTransactionsErrorMessageDismissed', () => {
const state = createSwapsMockStore();
state.appState.smartTransactionsErrorMessageDismissed = true;
expect(swaps.getSmartTransactionsErrorMessageDismissed(state)).toBe(
state.appState.smartTransactionsErrorMessageDismissed,
);
});
});
describe('getSmartTransactionsEnabled', () => {
it('returns true if feature flag is enabled, not a HW and is Ethereum network', () => {
const state = createSwapsMockStore();
expect(swaps.getSmartTransactionsEnabled(state)).toBe(true);
});
it('returns false if feature flag is disabled, not a HW and is Ethereum network', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.swapsFeatureFlags.smartTransactions.extensionActive = false;
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
it('returns false if feature flag is enabled, not a HW, STX liveness is false and is Ethereum network', () => {
const state = createSwapsMockStore();
state.metamask.smartTransactionsState.liveness = false;
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
it('returns false if feature flag is enabled, is a HW and is Ethereum network', () => {
const state = createSwapsMockStore();
state.metamask.keyrings[0].type = 'Trezor Hardware';
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
it('returns false if feature flag is enabled, not a HW and is Polygon network', () => {
const state = createSwapsMockStore();
state.metamask.providerConfig.chainId = CHAIN_IDS.POLYGON;
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
it('returns false if feature flag is enabled, not a HW and is BSC network', () => {
const state = createSwapsMockStore();
state.metamask.providerConfig.chainId = CHAIN_IDS.BSC;
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
it('returns true if feature flag is enabled, not a HW and is Goerli network', () => {
const state = createSwapsMockStore();
state.metamask.providerConfig.chainId = CHAIN_IDS.GOERLI;
expect(swaps.getSmartTransactionsEnabled(state)).toBe(true);
});
it('returns false if feature flag is missing', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.swapsFeatureFlags = {};
expect(swaps.getSmartTransactionsEnabled(state)).toBe(false);
});
});
describe('getCurrentSmartTransactionsEnabled', () => {
it('returns true if STX are enabled and there is no current STX error', () => {
const state = createSwapsMockStore();
expect(swaps.getCurrentSmartTransactionsEnabled(state)).toBe(true);
});
it('returns false if STX are enabled and there is an current STX error', () => {
const state = createSwapsMockStore();
state.swaps.currentSmartTransactionsError =
'currentSmartTransactionsError';
expect(swaps.getCurrentSmartTransactionsEnabled(state)).toBe(false);
});
});
describe('getSwapsQuoteRefreshTime', () => {
it('returns swapsQuoteRefreshTime', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsQuoteRefreshTime(state)).toBe(
state.metamask.swapsState.swapsQuoteRefreshTime,
);
});
});
describe('getSwapsQuotePrefetchingRefreshTime', () => {
it('returns swapsQuotePrefetchingRefreshTime', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsQuotePrefetchingRefreshTime(state)).toBe(
state.metamask.swapsState.swapsQuotePrefetchingRefreshTime,
);
});
});
describe('getBackgroundSwapRouteState', () => {
it('returns routeState', () => {
const state = createSwapsMockStore();
expect(swaps.getBackgroundSwapRouteState(state)).toBe(
state.metamask.swapsState.routeState,
);
});
});
describe('getCustomSwapsGas', () => {
it('returns "customMaxGas"', () => {
const state = createSwapsMockStore();
const customMaxGas = '29000';
state.metamask.swapsState.customMaxGas = customMaxGas;
expect(swaps.getCustomSwapsGas(state)).toBe(customMaxGas);
});
});
describe('getCustomSwapsGasPrice', () => {
it('returns customGasPrice', () => {
const state = createSwapsMockStore();
expect(swaps.getCustomSwapsGasPrice(state)).toBe(
state.metamask.swapsState.customGasPrice,
);
});
});
describe('getCustomMaxFeePerGas', () => {
it('returns "customMaxFeePerGas"', () => {
const state = createSwapsMockStore();
const customMaxFeePerGas = '20';
state.metamask.swapsState.customMaxFeePerGas = customMaxFeePerGas;
expect(swaps.getCustomMaxFeePerGas(state)).toBe(customMaxFeePerGas);
});
});
describe('getSwapsUserFeeLevel', () => {
it('returns swapsUserFeeLevel', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsUserFeeLevel(state)).toBe(
state.metamask.swapsState.swapsUserFeeLevel,
);
});
});
describe('getFetchParams', () => {
it('returns fetchParams', () => {
const state = createSwapsMockStore();
expect(swaps.getFetchParams(state)).toBe(
state.metamask.swapsState.fetchParams,
);
});
});
describe('getQuotes', () => {
it('returns quotes for Swaps', () => {
const state = createSwapsMockStore();
expect(swaps.getQuotes(state)).toBe(state.metamask.swapsState.quotes);
});
});
describe('getQuotesLastFetched', () => {
it('returns quotesLastFetched', () => {
const state = createSwapsMockStore();
expect(swaps.getQuotesLastFetched(state)).toBe(
state.metamask.swapsState.quotesLastFetched,
);
});
});
describe('getSelectedQuote', () => {
it('returns selected quote', () => {
const state = createSwapsMockStore();
expect(swaps.getSelectedQuote(state)).toBe(
state.metamask.swapsState.quotes.TEST_AGG_2,
);
});
});
describe('getSwapsErrorKey', () => {
it('returns errorKey', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsErrorKey(state)).toBe(
state.metamask.swapsState.errorKey,
);
});
});
describe('getShowQuoteLoadingScreen', () => {
it('returns showQuoteLoadingScreen', () => {
const state = createSwapsMockStore();
expect(swaps.getShowQuoteLoadingScreen(state)).toBe(
state.swaps.showQuoteLoadingScreen,
);
});
});
describe('getSwapsTokens', () => {
it('returns tokens', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsTokens(state)).toBe(
state.metamask.swapsState.tokens,
);
});
});
describe('getSwapsWelcomeMessageSeenStatus', () => {
it('returns', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapsWelcomeMessageSeenStatus(state)).toBe(
state.metamask.swapsState.swapsWelcomeMessageHasBeenShown,
);
});
});
describe('getTopQuote', () => {
it('returns a top quote', () => {
const state = createSwapsMockStore();
expect(swaps.getTopQuote(state)).toBe(
state.metamask.swapsState.quotes.TEST_AGG_BEST,
);
});
});
describe('getApproveTxId', () => {
it('returns approveTxId', () => {
const state = createSwapsMockStore();
expect(swaps.getApproveTxId(state)).toBe(
state.metamask.swapsState.approveTxId,
);
});
});
describe('getTradeTxId', () => {
it('returns tradeTxId', () => {
const state = createSwapsMockStore();
expect(swaps.getTradeTxId(state)).toBe(
state.metamask.swapsState.tradeTxId,
);
});
});
describe('getUsedQuote', () => {
it('returns selected quote', () => {
const state = createSwapsMockStore();
expect(swaps.getUsedQuote(state)).toMatchObject(
state.metamask.swapsState.quotes.TEST_AGG_2,
);
});
it('returns best quote', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.selectedAggId = null;
expect(swaps.getUsedQuote(state)).toMatchObject(
state.metamask.swapsState.quotes.TEST_AGG_BEST,
);
});
});
describe('getDestinationTokenInfo', () => {
it('returns destinationTokenInfo', () => {
const state = createSwapsMockStore();
expect(swaps.getDestinationTokenInfo(state)).toBe(
state.metamask.swapsState.fetchParams.metaData.destinationTokenInfo,
);
});
});
describe('getUsedSwapsGasPrice', () => {
it('returns customGasPrice', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.customGasPrice = 5;
expect(swaps.getUsedSwapsGasPrice(state)).toBe(
state.metamask.swapsState.customGasPrice,
);
});
});
describe('getApproveTxParams', () => {
it('returns approveTxParams', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.quotes.TEST_AGG_2.approvalNeeded = {
data: '0x095ea7b300000000000000000000000095e6f48254609a6ee006f7d493c8e5fb97094cef0000000000000000000000000000000000000000004a817c7ffffffdabf41c00',
to: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
value: '0x0',
from: '0x2369267687A84ac7B494daE2f1542C40E37f4455',
gas: '0x12',
gasPrice: '0x34',
};
expect(swaps.getApproveTxParams(state)).toMatchObject({
...state.metamask.swapsState.quotes.TEST_AGG_2.approvalNeeded,
gasPrice: 5,
});
});
});
describe('getSmartTransactionsOptInStatus', () => {
it('returns STX opt in status', () => {
const state = createSwapsMockStore();
expect(swaps.getSmartTransactionsOptInStatus(state)).toBe(true);
});
});
describe('getCurrentSmartTransactions', () => {
it('returns current smart transactions', () => {
const state = createSwapsMockStore();
expect(swaps.getCurrentSmartTransactions(state)).toMatchObject(
state.metamask.smartTransactionsState.smartTransactions[
CHAIN_IDS.MAINNET
],
);
});
});
describe('getPendingSmartTransactions', () => {
it('returns pending smart transactions', () => {
const state = createSwapsMockStore();
const pendingSmartTransactions = swaps.getPendingSmartTransactions(state);
expect(pendingSmartTransactions).toHaveLength(1);
expect(pendingSmartTransactions[0].uuid).toBe('uuid2');
expect(pendingSmartTransactions[0].status).toBe('pending');
});
});
describe('getSmartTransactionFees', () => {
it('returns unsigned transactions and estimates', () => {
const state = createSwapsMockStore();
const smartTransactionFees = swaps.getSmartTransactionFees(state);
expect(smartTransactionFees).toMatchObject(
state.metamask.smartTransactionsState.fees,
);
});
});
describe('getSmartTransactionEstimatedGas', () => {
it('returns unsigned transactions and estimates', () => {
const state = createSwapsMockStore();
const smartTransactionFees = swaps.getSmartTransactionEstimatedGas(state);
expect(smartTransactionFees).toBe(
state.metamask.smartTransactionsState.estimatedGas,
);
});
});
describe('getSwapsNetworkConfig', () => {
it('returns Swaps network config', () => {
const state = createSwapsMockStore();
const {
swapsQuoteRefreshTime,
swapsQuotePrefetchingRefreshTime,
swapsStxGetTransactionsRefreshTime,
swapsStxBatchStatusRefreshTime,
swapsStxStatusDeadline,
swapsStxMaxFeeMultiplier,
} = state.metamask.swapsState;
const swapsNetworkConfig = swaps.getSwapsNetworkConfig(state);
expect(swapsNetworkConfig).toMatchObject({
quoteRefreshTime: swapsQuoteRefreshTime,
quotePrefetchingRefreshTime: swapsQuotePrefetchingRefreshTime,
stxGetTransactionsRefreshTime: swapsStxGetTransactionsRefreshTime,
stxBatchStatusRefreshTime: swapsStxBatchStatusRefreshTime,
stxStatusDeadline: swapsStxStatusDeadline,
stxMaxFeeMultiplier: swapsStxMaxFeeMultiplier,
});
});
});
describe('actions + reducers', () => {
const store = configureMockStore(middleware)(createSwapsMockStore());
afterEach(() => {
store.clearActions();
});
describe('clearSwapsState', () => {
it('calls the "swaps/clearSwapsState" action', () => {
store.dispatch(swaps.clearSwapsState());
const actions = store.getActions();
expect(actions).toHaveLength(1);
expect(actions[0].type).toBe('swaps/clearSwapsState');
});
});
describe('setAggregatorMetadata', () => {
it('calls the "swaps/setAggregatorMetadata" action', () => {
const state = store.getState().swaps;
const actionPayload = {
name: 'agg1',
};
store.dispatch(swaps.setAggregatorMetadata(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setAggregatorMetadata');
const newState = swapsReducer(state, actions[0]);
expect(newState.aggregatorMetadata).toBe(actionPayload);
});
});
describe('setBalanceError', () => {
it('calls the "swaps/setBalanceError" action', () => {
const state = store.getState().swaps;
const actionPayload = 'balanceError';
store.dispatch(swaps.setBalanceError(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setBalanceError');
const newState = swapsReducer(state, actions[0]);
expect(newState.balanceError).toBe(actionPayload);
});
});
describe('setFetchingQuotes', () => {
it('calls the "swaps/setFetchingQuotes" action', () => {
const state = store.getState().swaps;
const actionPayload = true;
store.dispatch(swaps.setFetchingQuotes(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setFetchingQuotes');
const newState = swapsReducer(state, actions[0]);
expect(newState.fetchingQuotes).toBe(actionPayload);
});
});
describe('setSwapsFromToken', () => {
it('calls the "swaps/setFromToken" action', () => {
const state = store.getState().swaps;
const actionPayload = 'ETH';
store.dispatch(swaps.setSwapsFromToken(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setFromToken');
const newState = swapsReducer(state, actions[0]);
expect(newState.fromToken).toBe(actionPayload);
});
});
describe('setFromTokenError', () => {
it('calls the "swaps/setFromTokenError" action', () => {
const state = store.getState().swaps;
const actionPayload = 'fromTokenError';
store.dispatch(swaps.setFromTokenError(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setFromTokenError');
const newState = swapsReducer(state, actions[0]);
expect(newState.fromTokenError).toBe(actionPayload);
});
});
describe('setFromTokenInputValue', () => {
it('calls the "swaps/setFromTokenInputValue" action', () => {
const state = store.getState().swaps;
const actionPayload = '5';
store.dispatch(swaps.setFromTokenInputValue(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setFromTokenInputValue');
const newState = swapsReducer(state, actions[0]);
expect(newState.fromTokenInputValue).toBe(actionPayload);
});
});
describe('setIsFeatureFlagLoaded', () => {
it('calls the "swaps/setIsFeatureFlagLoaded" action', () => {
const state = store.getState().swaps;
const actionPayload = true;
store.dispatch(swaps.setIsFeatureFlagLoaded(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setIsFeatureFlagLoaded');
const newState = swapsReducer(state, actions[0]);
expect(newState.isFeatureFlagLoaded).toBe(actionPayload);
});
});
describe('setMaxSlippage', () => {
it('calls the "swaps/setMaxSlippage" action', () => {
const state = store.getState().swaps;
const actionPayload = 3;
store.dispatch(swaps.setMaxSlippage(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setMaxSlippage');
const newState = swapsReducer(state, actions[0]);
expect(newState.maxSlippage).toBe(actionPayload);
});
});
describe('setSwapQuotesFetchStartTime', () => {
it('calls the "swaps/setQuotesFetchStartTime" action', () => {
const state = store.getState().swaps;
const actionPayload = '1664461886';
store.dispatch(swaps.setSwapQuotesFetchStartTime(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setQuotesFetchStartTime');
const newState = swapsReducer(state, actions[0]);
expect(newState.quotesFetchStartTime).toBe(actionPayload);
});
});
describe('setReviewSwapClickedTimestamp', () => {
it('calls the "swaps/setReviewSwapClickedTimestamp" action', () => {
const state = store.getState().swaps;
const actionPayload = '1664461886';
store.dispatch(swaps.setReviewSwapClickedTimestamp(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setReviewSwapClickedTimestamp');
const newState = swapsReducer(state, actions[0]);
expect(newState.reviewSwapClickedTimestamp).toBe(actionPayload);
});
});
describe('setTopAssets', () => {
it('calls the "swaps/setTopAssets" action', () => {
const state = store.getState().swaps;
const actionPayload = {
'0x514910771af9ca656af840dff83e8264ecf986ca': {
index: '0',
},
'0x04fa0d235c4abf4bcf4787af4cf447de572ef828': {
index: '1',
},
'0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e': {
index: '2',
},
};
store.dispatch(swaps.setTopAssets(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setTopAssets');
const newState = swapsReducer(state, actions[0]);
expect(newState.topAssets).toBe(actionPayload);
});
});
describe('setSwapToToken', () => {
it('calls the "swaps/setToToken" action', () => {
const state = store.getState().swaps;
const actionPayload = 'USDC';
store.dispatch(swaps.setSwapToToken(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/setToToken');
const newState = swapsReducer(state, actions[0]);
expect(newState.toToken).toBe(actionPayload);
});
});
describe('swapCustomGasModalPriceEdited', () => {
it('calls the "swaps/swapCustomGasModalPriceEdited" action', () => {
const state = store.getState().swaps;
const actionPayload = 5;
store.dispatch(swaps.swapCustomGasModalPriceEdited(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/swapCustomGasModalPriceEdited');
const newState = swapsReducer(state, actions[0]);
expect(newState.customGas.price).toBe(actionPayload);
});
});
describe('swapCustomGasModalLimitEdited', () => {
it('calls the "swaps/swapCustomGasModalLimitEdited" action', () => {
const state = store.getState().swaps;
const actionPayload = 100;
store.dispatch(swaps.swapCustomGasModalLimitEdited(actionPayload));
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/swapCustomGasModalLimitEdited');
const newState = swapsReducer(state, actions[0]);
expect(newState.customGas.limit).toBe(actionPayload);
});
});
describe('swapCustomGasModalClosed', () => {
it('calls the "swaps/swapCustomGasModalClosed" action', () => {
const state = store.getState().swaps;
store.dispatch(swaps.swapCustomGasModalClosed());
const actions = store.getActions();
expect(actions[0].type).toBe('swaps/swapCustomGasModalClosed');
const newState = swapsReducer(state, actions[0]);
expect(newState.customGas.price).toBe(null);
expect(newState.customGas.limit).toBe(null);
});
});
describe('getSwapRedesignEnabled', () => {
it('returns true if feature flags are not returned from backend yet', () => {
const state = createSwapsMockStore();
delete state.metamask.swapsState.swapsFeatureFlags.swapRedesign;
expect(swaps.getSwapRedesignEnabled(state)).toBe(true);
});
it('returns false if the extension feature flag for swaps redesign is false', () => {
const state = createSwapsMockStore();
state.metamask.swapsState.swapsFeatureFlags.swapRedesign.extensionActive = false;
expect(swaps.getSwapRedesignEnabled(state)).toBe(false);
});
it('returns true if the extension feature flag for swaps redesign is true', () => {
const state = createSwapsMockStore();
expect(swaps.getSwapRedesignEnabled(state)).toBe(true);
});
});
});
});