mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-01 21:57:06 +01:00
efaaf4fab2
* Use tokenList to get token details, when available, in getTokenStandardAndDetails Previously, every call to getTokenStandardAndDetails would fetch data via the provider. This would result in at least 3 network requests whenever that method is called for an ERC20 token, contributing to unneccesary loading and lagging in multiple places. This commit takes advantage of stored data we already have available to avoid the unnecessary loading. * Lint fix * Fix build-quote test * bump coverage targets * Pass provider to token-util, for use in ethers Contract module * Check all possible sources of ERC20 token data before async call to assetsContractController * Add and update tests * Update app/scripts/metamask-controller.js Co-authored-by: Alex Donesky <adonesky@gmail.com> * Update app/scripts/metamask-controller.js Co-authored-by: Alex Donesky <adonesky@gmail.com> * Remove unnecessary this.ethQuery changes * Use metamask-eth-abis instead of human-standard-token-abi in token-util.ts * Add explanatory comments to getTokenStandardAndDetails * lint fix * Cleanup * fix test * Update app/scripts/metamask-controller.js Co-authored-by: Alex Donesky <adonesky@gmail.com> * update error message --------- Co-authored-by: Alex Donesky <adonesky@gmail.com>
187 lines
5.9 KiB
JavaScript
187 lines
5.9 KiB
JavaScript
import React from 'react';
|
|
import configureMockStore from 'redux-mock-store';
|
|
import thunk from 'redux-thunk';
|
|
|
|
import {
|
|
renderWithProvider,
|
|
createSwapsMockStore,
|
|
setBackgroundConnection,
|
|
fireEvent,
|
|
} from '../../../../test/jest';
|
|
import { createTestProviderTools } from '../../../../test/stub/provider';
|
|
import {
|
|
setSwapsFromToken,
|
|
setSwapToToken,
|
|
setFromTokenInputValue,
|
|
} from '../../../ducks/swaps/swaps';
|
|
import BuildQuote from '.';
|
|
|
|
const middleware = [thunk];
|
|
const createProps = (customProps = {}) => {
|
|
return {
|
|
ethBalance: '0x8',
|
|
selectedAccountAddress: 'selectedAccountAddress',
|
|
isFeatureFlagLoaded: false,
|
|
shuffledTokensList: [],
|
|
...customProps,
|
|
};
|
|
};
|
|
|
|
setBackgroundConnection({
|
|
resetPostFetchState: jest.fn(),
|
|
ignoreTokens: jest.fn(),
|
|
setBackgroundSwapRouteState: jest.fn(),
|
|
clearSwapsQuotes: jest.fn(),
|
|
stopPollingForQuotes: jest.fn(),
|
|
clearSmartTransactionFees: jest.fn(),
|
|
setSwapsFromToken: jest.fn(),
|
|
setSwapToToken: jest.fn(),
|
|
setFromTokenInputValue: jest.fn(),
|
|
});
|
|
|
|
jest.mock('../../../ducks/swaps/swaps', () => {
|
|
const actual = jest.requireActual('../../../ducks/swaps/swaps');
|
|
return {
|
|
...actual,
|
|
setSwapsFromToken: jest.fn(),
|
|
setSwapToToken: jest.fn(),
|
|
setFromTokenInputValue: jest.fn(() => {
|
|
return {
|
|
type: 'MOCK_ACTION',
|
|
};
|
|
}),
|
|
};
|
|
});
|
|
|
|
jest.mock('../swaps.util', () => {
|
|
const actual = jest.requireActual('../swaps.util');
|
|
return {
|
|
...actual,
|
|
fetchTokenBalance: jest.fn(() => Promise.resolve()),
|
|
fetchTokenPrice: jest.fn(() => Promise.resolve()),
|
|
};
|
|
});
|
|
|
|
const providerResultStub = {
|
|
eth_getCode: '0x123',
|
|
eth_call:
|
|
'0x00000000000000000000000000000000000000000000000029a2241af62c0000',
|
|
};
|
|
const { provider } = createTestProviderTools({
|
|
scaffold: providerResultStub,
|
|
networkId: '5',
|
|
chainId: '5',
|
|
});
|
|
|
|
describe('BuildQuote', () => {
|
|
beforeAll(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
beforeEach(() => {
|
|
global.ethereumProvider = provider;
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('renders the component with initial props', () => {
|
|
const store = configureMockStore(middleware)(createSwapsMockStore());
|
|
const props = createProps();
|
|
const { getByText } = renderWithProvider(<BuildQuote {...props} />, store);
|
|
expect(getByText('Swap from')).toBeInTheDocument();
|
|
expect(getByText('Swap to')).toBeInTheDocument();
|
|
expect(getByText('Select')).toBeInTheDocument();
|
|
expect(getByText('Slippage tolerance')).toBeInTheDocument();
|
|
expect(getByText('2%')).toBeInTheDocument();
|
|
expect(getByText('3%')).toBeInTheDocument();
|
|
expect(getByText('Review swap')).toBeInTheDocument();
|
|
expect(
|
|
document.querySelector('.slippage-buttons__button-group'),
|
|
).toMatchSnapshot();
|
|
});
|
|
|
|
it('switches swap from and to tokens', () => {
|
|
const setSwapFromTokenMock = jest.fn(() => {
|
|
return {
|
|
type: 'MOCK_ACTION',
|
|
};
|
|
});
|
|
setSwapsFromToken.mockImplementation(setSwapFromTokenMock);
|
|
const setSwapToTokenMock = jest.fn(() => {
|
|
return {
|
|
type: 'MOCK_ACTION',
|
|
};
|
|
});
|
|
setSwapToToken.mockImplementation(setSwapToTokenMock);
|
|
const mockStore = createSwapsMockStore();
|
|
const store = configureMockStore(middleware)(mockStore);
|
|
const props = createProps();
|
|
const { getByText, getByTestId } = renderWithProvider(
|
|
<BuildQuote {...props} />,
|
|
store,
|
|
);
|
|
expect(getByText('Swap from')).toBeInTheDocument();
|
|
fireEvent.click(getByTestId('build-quote__swap-arrows'));
|
|
expect(setSwapsFromToken).toHaveBeenCalledWith(mockStore.swaps.toToken);
|
|
expect(setSwapToToken).toHaveBeenCalled();
|
|
});
|
|
|
|
it('renders the block explorer link, only 1 verified source', () => {
|
|
const mockStore = createSwapsMockStore();
|
|
mockStore.swaps.toToken.occurances = 1;
|
|
const store = configureMockStore(middleware)(mockStore);
|
|
const props = createProps();
|
|
const { getByText } = renderWithProvider(<BuildQuote {...props} />, store);
|
|
expect(getByText('Swap from')).toBeInTheDocument();
|
|
expect(getByText('Only verified on 1 source.')).toBeInTheDocument();
|
|
expect(getByText('Etherscan')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders the block explorer link, 0 verified sources', () => {
|
|
const mockStore = createSwapsMockStore();
|
|
mockStore.swaps.toToken.occurances = 0;
|
|
const store = configureMockStore(middleware)(mockStore);
|
|
const props = createProps();
|
|
const { getByText } = renderWithProvider(<BuildQuote {...props} />, store);
|
|
expect(getByText('Swap from')).toBeInTheDocument();
|
|
expect(
|
|
getByText('This token has been added manually.'),
|
|
).toBeInTheDocument();
|
|
expect(getByText('Etherscan')).toBeInTheDocument();
|
|
});
|
|
|
|
it('clicks on a block explorer link', () => {
|
|
global.platform = { openTab: jest.fn() };
|
|
const mockStore = createSwapsMockStore();
|
|
mockStore.swaps.toToken.occurances = 1;
|
|
const store = configureMockStore(middleware)(mockStore);
|
|
const props = createProps();
|
|
const { getByText } = renderWithProvider(<BuildQuote {...props} />, store);
|
|
const blockExplorer = getByText('Etherscan');
|
|
expect(blockExplorer).toBeInTheDocument();
|
|
fireEvent.click(blockExplorer);
|
|
expect(global.platform.openTab).toHaveBeenCalledWith({
|
|
url: 'https://etherscan.io/token/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
});
|
|
});
|
|
|
|
it('clicks on the "max" link', () => {
|
|
const setFromTokenInputValueMock = jest.fn(() => {
|
|
return {
|
|
type: 'MOCK_ACTION',
|
|
};
|
|
});
|
|
setFromTokenInputValue.mockImplementation(setFromTokenInputValueMock);
|
|
const mockStore = createSwapsMockStore();
|
|
mockStore.swaps.fromToken = 'DAI';
|
|
const store = configureMockStore(middleware)(mockStore);
|
|
const props = createProps();
|
|
const { getByText } = renderWithProvider(<BuildQuote {...props} />, store);
|
|
const maxLink = getByText('Max');
|
|
fireEvent.click(maxLink);
|
|
expect(setFromTokenInputValue).toHaveBeenCalled();
|
|
});
|
|
});
|