1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 03:12:42 +02:00

Increase Jest unit test coverage for the Swaps feature to ~43% (#10934)

This commit is contained in:
Daniel 2021-04-27 13:16:17 -07:00 committed by GitHub
parent 539a2b65f3
commit 37159a58e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 898 additions and 23 deletions

View File

@ -130,6 +130,7 @@ module.exports = {
rules: {
'jest/no-restricted-matchers': 'off',
'import/unambiguous': 'off',
'import/named': 'off',
},
},
{

View File

@ -1,12 +1,14 @@
module.exports = {
restoreMocks: true,
coverageDirectory: 'jest-coverage/',
collectCoverageFrom: ['<rootDir>/ui/app/**/swaps/**'],
coveragePathIgnorePatterns: ['.stories.js', '.snap'],
coverageThreshold: {
global: {
branches: 21.24,
functions: 23.01,
lines: 27.19,
statements: 27.07,
branches: 32.75,
functions: 43.31,
lines: 43.12,
statements: 43.67,
},
},
setupFiles: ['./test/setup.js', './test/env.js'],

View File

@ -33,7 +33,7 @@
"test:e2e:firefox": "SELENIUM_BROWSER=firefox test/e2e/run-all.sh",
"test:e2e:firefox:metrics": "SELENIUM_BROWSER=firefox mocha test/e2e/metrics.spec.js",
"test:coverage": "nyc --silent --check-coverage yarn test:unit:strict && nyc --silent --no-clean yarn test:unit:lax && nyc report --reporter=text --reporter=html",
"test:coverage:jest": "jest --coverage --maxWorkers=2 --collectCoverageFrom=**/ui/app/**/swaps/**",
"test:coverage:jest": "jest --coverage --maxWorkers=2",
"test:coverage:strict": "nyc --check-coverage yarn test:unit:strict",
"test:coverage:path": "nyc --check-coverage yarn test:unit:path",
"ganache:start": "./development/run-ganache.sh",

5
test/jest/background.js Normal file
View File

@ -0,0 +1,5 @@
import * as actions from '../../ui/app/store/actions';
export const setBackgroundConnection = (backgroundConnection = {}) => {
actions._setBackgroundConnection(backgroundConnection);
};

1
test/jest/constants.js Normal file
View File

@ -0,0 +1 @@
export const METASWAP_BASE_URL = 'https://api.metaswap.codefi.network';

View File

@ -1,4 +1,5 @@
import { createSwapsMockStore } from './mock-store';
import { renderWithProvider } from './rendering';
export { createSwapsMockStore, renderWithProvider };
export { createSwapsMockStore } from './mock-store';
export { renderWithProvider } from './rendering';
export { setBackgroundConnection } from './background';
export * as MOCKS from './mocks';
export * as CONSTANTS from './constants';

View File

@ -6,6 +6,7 @@ export const createSwapsMockStore = () => {
customGas: {
fallBackPrice: 5,
},
fromToken: 'ETH',
},
metamask: {
provider: {
@ -14,6 +15,15 @@ export const createSwapsMockStore = () => {
cachedBalances: {
[MAINNET_CHAIN_ID]: 5,
},
preferences: {
showFiatInTestnets: true,
},
currentCurrency: 'ETH',
conversionRate: 1,
contractExchangeRates: {
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2,
'0x1111111111111111111111111111111111111111': 0.1,
},
accounts: {
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
@ -26,6 +36,20 @@ export const createSwapsMockStore = () => {
},
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
frequentRpcListDetail: [],
tokens: [
{
erc20: true,
symbol: 'BAT',
decimals: 18,
address: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
},
{
erc20: true,
symbol: 'USDT',
decimals: 6,
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
},
],
swapsState: {
quotes: {},
fetchParams: {
@ -38,20 +62,6 @@ export const createSwapsMockStore = () => {
},
},
},
tokens: [
{
erc20: true,
symbol: 'BAT',
decimals: 18,
address: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
},
{
erc20: true,
symbol: 'USDT',
decimals: 6,
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
},
],
tradeTxId: null,
approveTxId: null,
quotesLastFetched: null,

61
test/jest/mocks.js Normal file
View File

@ -0,0 +1,61 @@
export const TOP_ASSETS_GET_RESPONSE = [
{
symbol: 'LINK',
address: '0x514910771af9ca656af840dff83e8264ecf986ca',
},
{
symbol: 'UMA',
address: '0x04fa0d235c4abf4bcf4787af4cf447de572ef828',
},
{
symbol: 'YFI',
address: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e',
},
{
symbol: 'LEND',
address: '0x80fb784b7ed66730e8b1dbd9820afd29931aab03',
},
{
symbol: 'SNX',
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
},
];
export const REFRESH_TIME_GET_RESPONSE = {
seconds: 3600,
};
export const AGGREGATOR_METADATA_GET_RESPONSE = {};
export const GAS_PRICES_GET_RESPONSE = {
SafeGasPrice: '10',
ProposeGasPrice: '20',
FastGasPrice: '30',
};
export const TOKENS_GET_RESPONSE = [
{
erc20: true,
symbol: 'META',
decimals: 18,
address: '0x617b3f8050a0BD94b6b1da02B4384eE5B4DF13F4',
},
{
erc20: true,
symbol: 'ZRX',
decimals: 18,
address: '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
},
{
erc20: true,
symbol: 'AST',
decimals: 4,
address: '0x27054b13b1B798B345b591a4d22e6562d47eA75a',
},
{
erc20: true,
symbol: 'BAT',
decimals: 18,
address: '0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
},
];

View File

@ -3,4 +3,9 @@ const originalModule = jest.requireActual('react-router-dom');
module.exports = {
...originalModule,
useHistory: jest.fn(),
useLocation: jest.fn(() => {
return {
pathname: '/swaps/build-quote',
};
}),
};

View File

@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Swap renders the component with initial props 1`] = `
<div>
<div
class="swaps"
>
<div
class="swaps__container"
>
<div
class="swaps__header"
>
<div
class="swaps__title"
>
Swap
</div>
<div
class="swaps__header-cancel"
>
Cancel
</div>
</div>
<div
class="swaps__content"
/>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`QuotesTimeoutIcon renders the component 1`] = `
<div>
<svg
fill="none"
height="44"
viewBox="0 0 44 44"
width="44"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22 0C9.96768 0 0.178406 9.78928 0.178406 21.8216C0.178406 33.8539 9.96768 43.6432 22 43.6432C34.0323 43.6432 43.8216 33.8539 43.8216 21.8216C43.8216 9.78929 34.0323 0 22 0ZM22 3.27324C32.2633 3.27324 40.5484 11.5583 40.5484 21.8216C40.5484 32.0849 32.2633 40.3699 22 40.3699C11.7367 40.3699 3.45164 32.0849 3.45164 21.8216C3.45164 11.5583 11.7367 3.27324 22 3.27324ZM22 6.00094C21.0961 6.00094 20.3634 6.73371 20.3634 7.63756V21.8216C20.3634 22.4269 20.6932 22.9534 21.1817 23.2366L32.5187 29.783C33.3014 30.235 34.3001 29.9692 34.752 29.1864C35.2039 28.4036 34.938 27.405 34.1553 26.953L23.6366 20.8839V7.63756C23.6366 6.73371 22.9039 6.00094 22 6.00094Z"
fill="#037DD6"
/>
</svg>
</div>
`;

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SwapFailureIcon renders the component 1`] = `
<div>
<svg
fill="none"
height="39"
viewBox="0 0 45 39"
width="45"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22.203 0.424438L0.285706 38.2816H44.1203L22.203 0.424438ZM22.203 8.39436L37.2064 34.2966H7.19961L22.203 8.39436ZM20.2105 16.3643V24.3342H24.1955V16.3643H20.2105ZM20.2105 28.3192V32.3041H24.1955V28.3192"
fill="#D73A49"
/>
</svg>
</div>
`;

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SwapSuccessIcon renders the component 1`] = `
<div>
<svg
fill="none"
height="38"
viewBox="0 0 38 38"
width="38"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M34.1429 19C34.1429 23.0161 32.5474 26.8678 29.7076 29.7076C26.8678 32.5474 23.0161 34.1428 19 34.1428C14.9839 34.1428 11.1322 32.5474 8.29238 29.7076C5.45254 26.8678 3.85714 23.0161 3.85714 19C3.85714 14.9838 5.45254 11.1322 8.29238 8.29237C11.1322 5.45253 14.9839 3.85713 19 3.85713C20.4386 3.85713 21.8393 4.06534 23.1643 4.44391L26.1361 1.47213C23.9404 0.563554 21.5364 0.0714111 19 0.0714111C16.5143 0.0714111 14.0529 0.561013 11.7563 1.51226C9.45983 2.46351 7.37316 3.85778 5.61548 5.61546C2.06568 9.16526 0.0714264 13.9798 0.0714264 19C0.0714264 24.0201 2.06568 28.8347 5.61548 32.3845C7.37316 34.1422 9.45983 35.5364 11.7563 36.4877C14.0529 37.4389 16.5143 37.9286 19 37.9286C24.0202 37.9286 28.8347 35.9343 32.3845 32.3845C35.9343 28.8347 37.9286 24.0201 37.9286 19H34.1429ZM11.2582 15.3657L8.58928 18.0536L17.1071 26.5714L36.0357 7.64284L33.3668 4.95498L17.1071 21.2146L11.2582 15.3657Z"
fill="#28A745"
/>
</svg>
</div>
`;

View File

@ -0,0 +1,11 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import QuotesTimeoutIcon from './quotes-timeout-icon';
describe('QuotesTimeoutIcon', () => {
it('renders the component', () => {
const { container } = renderWithProvider(<QuotesTimeoutIcon />);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,11 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import SwapFailureIcon from './swap-failure-icon';
describe('SwapFailureIcon', () => {
it('renders the component', () => {
const { container } = renderWithProvider(<SwapFailureIcon />);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,11 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import SwapSuccessIcon from './swap-success-icon';
describe('SwapSuccessIcon', () => {
it('renders the component', () => {
const { container } = renderWithProvider(<SwapSuccessIcon />);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ViewOnEtherScanLink renders the component with a custom block explorer link 1`] = `
<div>
<div
class="awaiting-swap__view-on-etherscan awaiting-swap__view-on-etherscan--visible"
>
View at custom-blockchain.explorer
</div>
</div>
`;
exports[`ViewOnEtherScanLink renders the component with initial props 1`] = `
<div>
<div
class="awaiting-swap__view-on-etherscan awaiting-swap__view-on-etherscan--visible"
>
View on Etherscan
</div>
</div>
`;

View File

@ -0,0 +1,37 @@
import React from 'react';
import { renderWithProvider } from '../../../../../../test/jest';
import ViewOnEtherScanLink from '.';
const createProps = (customProps = {}) => {
return {
txHash:
'0x58e5a0fc7fbc849eddc100d44e86276168a8c7baaa5604e44ba6f5eb8ba1b7eb',
blockExplorerUrl: 'https://block.explorer',
isCustomBlockExplorerUrl: false,
...customProps,
};
};
describe('ViewOnEtherScanLink', () => {
it('renders the component with initial props', () => {
const { container, getByText } = renderWithProvider(
<ViewOnEtherScanLink {...createProps()} />,
);
expect(getByText('View on Etherscan')).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
it('renders the component with a custom block explorer link', () => {
const { container, getByText } = renderWithProvider(
<ViewOnEtherScanLink
{...createProps({
blockExplorerUrl: 'https://custom-blockchain.explorer',
isCustomBlockExplorerUrl: true,
})}
/>,
);
expect(getByText('View at custom-blockchain.explorer')).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,66 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BuildQuote renders the component with initial props 1`] = `
<div
class="button-group slippage-buttons__button-group radio-button-group"
role="radiogroup"
>
<button
aria-checked="false"
class="button-group__button radio-button"
role="radio"
>
2%
</button>
<button
aria-checked="false"
class="button-group__button radio-button"
role="radio"
>
3%
</button>
<button
aria-checked="true"
class="button-group__button slippage-buttons__button-group-custom-button radio-button--danger radio-button button-group__button--active radio-button--active"
role="radio"
>
15
<div
class="slippage-buttons__percentage-suffix"
>
%
</div>
</button>
</div>
`;
exports[`BuildQuote renders the component with initial props 2`] = `
<div
class="swaps-footer"
>
<div
class="swaps-footer__buttons"
>
<div
class="page-container__footer swaps-footer__custom-page-container-footer-class"
>
<footer>
<button
class="button btn-primary page-container__footer-button swaps-footer__custom-page-container-footer-button-class swaps-footer__custom-page-container-footer-button-class--single"
data-testid="page-container-footer-next"
disabled=""
role="button"
tabindex="0"
>
Review Swap
</button>
</footer>
</div>
</div>
<div
class="swaps-footer__bottom-text"
>
Terms of Service
</div>
</div>
`;

View File

@ -0,0 +1,47 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import {
renderWithProvider,
createSwapsMockStore,
setBackgroundConnection,
} from '../../../../../test/jest';
import BuildQuote from '.';
const middleware = [thunk];
const createProps = (customProps = {}) => {
return {
inputValue: '5',
onInputChange: jest.fn(),
ethBalance: '6 ETH',
setMaxSlippage: jest.fn(),
maxSlippage: 15,
selectedAccountAddress: 'selectedAccountAddress',
isFeatureFlagLoaded: false,
...customProps,
};
};
setBackgroundConnection({
resetPostFetchState: jest.fn(),
});
describe('BuildQuote', () => {
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('ETH')).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();
expect(document.querySelector('.swaps-footer')).toMatchSnapshot();
});
});

View File

@ -0,0 +1,11 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import PigIcon from './pig-icon';
describe('PigIcon', () => {
it('renders the component', () => {
const { container } = renderWithProvider(<PigIcon />);
expect(container.firstChild.nodeName).toBe('svg');
});
});

View File

@ -0,0 +1,63 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import nock from 'nock';
import { waitFor } from '@testing-library/react';
import {
renderWithProvider,
createSwapsMockStore,
setBackgroundConnection,
MOCKS,
CONSTANTS,
} from '../../../../test/jest';
import Swap from '.';
const middleware = [thunk];
setBackgroundConnection({
resetPostFetchState: jest.fn(),
resetSwapsState: jest.fn(),
setSwapsLiveness: jest.fn(() => true),
setSwapsTokens: jest.fn(),
setSwapsTxGasPrice: jest.fn(),
});
describe('Swap', () => {
let tokensNock;
beforeEach(() => {
nock(CONSTANTS.METASWAP_BASE_URL)
.get('/topAssets')
.reply(200, MOCKS.TOP_ASSETS_GET_RESPONSE);
nock(CONSTANTS.METASWAP_BASE_URL)
.get('/refreshTime')
.reply(200, MOCKS.REFRESH_TIME_GET_RESPONSE);
nock(CONSTANTS.METASWAP_BASE_URL)
.get('/aggregatorMetadata')
.reply(200, MOCKS.AGGREGATOR_METADATA_GET_RESPONSE);
nock(CONSTANTS.METASWAP_BASE_URL)
.get('/gasPrices')
.reply(200, MOCKS.GAS_PRICES_GET_RESPONSE);
tokensNock = nock(CONSTANTS.METASWAP_BASE_URL)
.get('/tokens')
.reply(200, MOCKS.TOKENS_GET_RESPONSE);
});
afterAll(() => {
nock.cleanAll();
});
it('renders the component with initial props', async () => {
const store = configureMockStore(middleware)(createSwapsMockStore());
const { container, getByText } = renderWithProvider(<Swap />, store);
await waitFor(() => expect(tokensNock.isDone()).toBe(true));
expect(getByText('Swap')).toBeInTheDocument();
expect(getByText('Cancel')).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AggregatorLogo renders the component with initial props 1`] = `
<div>
<div
class="loading-swaps-quotes__logo"
>
<div
style="background: rgb(0, 0, 0); box-shadow: 0px 4px 20px rgba(0, 0, NaN, 0.25);"
>
<img
alt=""
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASkAAAB5CAYAAABlYNfBAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAlASURBVHgB7d3/eeO2GcDx1336f3UThNcF4g3KLNA4HaDnywC5Xgeo6Q5Q+zpAz+kCd+0AJyUDxNcFTsoCsbtA3gIVFL0CIRGgKMm2vp/nwWPxF0hT4isABCERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADhCJ4LeVLVyf05d+sylZy7dufSjS7OTk5OPgrXcufN/KpfO16zyfqhzmLGvEjOX7mWA9zgcVx3SwrXL916AvtwHa+TShUtT3cwvfxUCGSLuvJy4dLPh/H2Qgfhg4NIXOrw7l9659EJ6CMfVmPx+5vOCrYSgc6dlpi79SbBC50FquuG8+Qt2JAPQ3QUp65NLdY/jIkh1+LUgi/vwXLk/qWDz/6J/+Ov56p+9uCqXrtz2n7li/GvBoppzJvNzs8m5S9eyG/eyfM9KjGT1/V147tIH979duvf5UoB98gEq8c35dt03p5t/qumqzFvBohT1zpyXqUvnLr3U1ZLqIFU+bZekfInlXHoIefkq/9ma99jnnVVypiSFQei8/UmjC6rO3LZOfIiPuuoXLszn0Tn5h1kWX7RbV/mGDFKJfKtEsPo55zNCkMLWwgcwDlBVwfYXmnYqRypcmC+jC/PULIvbjhrZ0q6ClMnflwyvo+PuLAUSpLA194EZRx+8unD7qaaN5UiFC9qe108dy3+QLe06SIV9xMfdWZoiSOX5lSApfMBqM+vGNYhOJFO4CCoz61vzutbCgPcU6LK/Um1m/zNezaXvzPTpIzlX/rj/aqZ9H8RasDWC1Hrn0XTpHZsL83oi7TuDF3KcavPaX9g3iXXemNf+Yv9SHoe4c+fngq0RpNazF8bElaJmkilRiroMvYgnZp4vIQzSD+gR8QHnGzP9MT6vbtr/ic9Vr86S+2SOe2ZmE6QGQJBKCNULG0BupMxKKcpUE22Vz+d/NA3ooap3Ksv/2c94s251l/5tpkePqHo8EwyKIJV2Fk1/J5lSpSjz+n3HfuK8LnTeH8unRrag897yi7wO0V/LFzVeRfM2ndebaNs/CoC56C7NtHDbqdn2tmP5uCOvM13Vq4+VtrtSNLJn2n4M5kPG+mOz/k99q8e6h7t7sjzmW7OfHzKOi7t7HShJpdlq2EwyabsUlXqkY+XOlWzgqom+5DUxsy56Xqg2GPqn9xvZI10+7V8tZslq1Te5maze+fP/95k8fPY9ZTSDARCk0mwg+I/ks21RPhikLkT7wR1lBJ3X0XEV3RVMBM5G9s9X1+LG75wqtA/S9yaPB1vlC4H4PJr9vQBDS1SNcp/DOo+2e5G5XpWRd9ybuZYM4X+Zmu0O8uygtqt67wq2exdVh4pLkrq/zpzTaB+nGcdFda8DJam2KprOLbLnlKJy9pfSRMeRW5pqZH0j/l5oe8QDP+N97uYu/T2ady4PTPgf/XtSmdkTBj4cBkGq26xrhVCyqcyspiC/30iH0MfKVvtq7RhoLXyL23UuS/p6DSiupt0XBHDPX+i2yvd7eSBCSciPyOpLqPaLw0etrwXYBW2PXFBnbDM2608L8z+X/GOz+7nbVPWJqh5FdyiHohtGPCjII354t7hKpLsbquVa04MgNgV5Ud3rwKB3bVXJytp+xq+R3bk0+1o0or9OHJPvj1SZWYccbK82r+M7djn8Nv+SZR8rX5o6l+3Os8/DjxHW59GkdYPeLVzu++4pjoy2+ybVHeuPS0osukVJKmwfN6KfRssfRGN5OJaNIx4U5nPXNx9l+OBHjTaptrihfG2bUfhA1WZWI+XuCtdvZPUYrxLLq/B6JgdoLPc0PeLBRPqz7ViVPozHZBbPGH7lSk+/LRklA/mo7nV7tmFZY17n3tGLqwr/lQK+Ed1doD7wLILTohHd9zuqZLWx/M2BGssXbOdLH7W+36KkYPurLUZGmEh/76WsD9zCLPz9yN07HIRm9pNKrJf1pL62+0nV0oO2B+SLHaSx3Bxf16/BbOungmPZeT+pPpTqXhaqe21xda9as15jXs8k/yHkKpru+23cVY17KQeiyxEPKtmdxzQyArZAkIqEPkk2ULXapMK3nS05fVtQrfo8sb8+ftex/JUcTmrEg13s4xvBk0ebVNpMlg+K1onlTbTujeSrzOtepagQJBtZPQaf7BhV/i5lfcDGXBtE/WgQf5Dt+cDk+1nVYdq3x434WXIcHW3f5h+ZZXFb1FVBvqNo217dA7TdqbMy+dtb9VPd8+ifa9p/sp5/zMz7dWnetEk9blT30uISji0VNNGydaNLptTR9EQKhYurNrN+edwllChsW1Ul6V9d3qXUiAe5z+rluIn29WAekwH2Zl2JJ1GKKioJaftHJKvC7eOOmtM1642j/ZzKnmi74+Ugv0Ic5T+OSh+jjm0oSeHp0cRzctsEGW0HuLEUyt2/zn/mXXcVKDYcn0/xD39mdc0o3EdRlY8ghSdJ24+vvI2nC/O7iLYvuni13b+q6Vj/uuRCHoKmx3+qZEDhwn4WnYsPGdsQpPD06ObOiFVBPnEpqnTc9FF0LP71KGMbW+3qPUZ45jGmRjzYSQlOC38tmCD1uNFwvtm6DpE3uf2iQmCIq3aNlIlHNWgybrv75X820/7xnr/JbtXmdc445n3Foynwa8E4XtpuB1ItG773Ntr2WgroFo31pSWObWiPBu0t9rWo8q2UFDvWpySFp0nn1aY40ExdeqHrG679NhfaHhDttvTC1XY1ryrYNlUF+6QDBw8dYHC7Hvv0QfEmusBrWX98BCk8XWsC1cJYzY9uhunUaI19AtRFlEfxnbLEheA1MiBN33H7UnZI02NEXWWuS5DC06Ttnui5/HalAcpX82ywu5UedFk1mu7qYtD2iAfZIxQMsN/OmwNKkHrUaDgv4Bqr/W3855LfIDxx6Qu/XY/ny3ypyW8zC+kr6cHt1//xA+t9bfL60aW/yAB0ObidmPx31WDe2r3Mf4B1FtK9rB95wZ5Ln0oHG9wVfxwzkxA5EfQSvrFrmT/Q618vRkvwAcA/VjPhwVcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJH7H5NlZI/0GQ+cAAAAAElFTkSuQmCC"
/>
</div>
</div>
</div>
`;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,22 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import AggregatorLogo from './aggregator-logo';
const createProps = (customProps = {}) => {
return {
color: '#000',
icon:
'data:image/png;base64,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',
...customProps,
};
};
describe('AggregatorLogo', () => {
it('renders the component with initial props', () => {
const { container } = renderWithProvider(
<AggregatorLogo {...createProps()} />,
);
expect(container).toMatchSnapshot();
});
});

View File

@ -0,0 +1,12 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import BackgroundAnimation from './background-animation';
describe('BackgroundAnimation', () => {
it('renders the component', () => {
const { container } = renderWithProvider(<BackgroundAnimation />);
expect(container.firstChild.nodeName).toBe('DIV');
expect(container.firstChild.firstChild.nodeName).toBe('svg');
});
});

View File

@ -0,0 +1,7 @@
import { storiesMetadata } from './loading-swaps-quotes-stories-metadata';
describe('storiesMetadata', () => {
it('matches expected values for storiesMetadata', () => {
expect(storiesMetadata).toMatchSnapshot();
});
});

View File

@ -0,0 +1,74 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`QuotesBackdrop renders the component with initial props 1`] = `
<g
filter="url(#filter0_d)"
>
<path
d="M25.4749 54C25.4749 49.5817 29.0566 46 33.4749 46H328.475C332.893 46 336.475 49.5817 336.475 54V185.5C336.475 189.918 332.893 193.5 328.475 193.5H33.4749C29.0566 193.5 25.4749 189.918 25.4749 185.5V54Z"
fill="url(#paint0_linear)"
/>
</g>
`;
exports[`QuotesBackdrop renders the component with initial props 2`] = `
<filter
color-interpolation-filters="sRGB"
filterUnits="userSpaceOnUse"
height="242.164"
id="filter0_d"
width="389"
x="-13.5251"
y="0.335938"
>
<feflood
flood-opacity="0"
result="BackgroundImageFix"
/>
<fecolormatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
/>
<feoffset
dy="10"
/>
<fegaussianblur
stdDeviation="19.5"
/>
<fecolormatrix
type="matrix"
values="0 0 0 0 0.0117647 0 0 0 0 0.491686 0 0 0 0 0.839216 0 0 0 0.15 0"
/>
<feblend
in2="BackgroundImageFix"
mode="normal"
result="effect1_dropShadow"
/>
<feblend
in="SourceGraphic"
in2="effect1_dropShadow"
mode="normal"
result="shape"
/>
</filter>
`;
exports[`QuotesBackdrop renders the component with initial props 3`] = `
<lineargradient
gradientUnits="userSpaceOnUse"
id="paint0_linear"
x1="25.4749"
x2="342.234"
y1="90.693"
y2="90.693"
>
<stop
stop-color="#037DD6"
/>
<stop
offset="0.994792"
stop-color="#1098FC"
/>
</lineargradient>
`;

View File

@ -0,0 +1,23 @@
import React from 'react';
import { renderWithProvider } from '../../../../../test/jest';
import QuotesBackdrop from './quote-backdrop';
const createProps = (customProps = {}) => {
return {
withTopTab: false,
...customProps,
};
};
describe('QuotesBackdrop', () => {
it('renders the component with initial props', () => {
const { container } = renderWithProvider(
<QuotesBackdrop {...createProps()} />,
);
expect(container.firstChild.nodeName).toBe('svg');
expect(document.querySelector('g')).toMatchSnapshot();
expect(document.querySelector('filter')).toMatchSnapshot();
expect(document.querySelector('linearGradient')).toMatchSnapshot();
});
});

View File

@ -0,0 +1,18 @@
import quoteDataRows from './mock-quote-data';
describe('quoteDataRows', () => {
it('matches expected values for quoteDataRows', () => {
expect(quoteDataRows[0].aggId).toBe('Agg1');
expect(quoteDataRows[0].amountReceiving).toBe('100 DAI');
expect(quoteDataRows[1].aggId).toBe('Agg2');
expect(quoteDataRows[1].amountReceiving).toBe('101 DAI');
expect(quoteDataRows[2].aggId).toBe('Agg3');
expect(quoteDataRows[2].amountReceiving).toBe('102 DAI');
expect(quoteDataRows[3].aggId).toBe('Agg4');
expect(quoteDataRows[3].amountReceiving).toBe('150 DAI');
expect(quoteDataRows[4].aggId).toBe('Agg5');
expect(quoteDataRows[4].amountReceiving).toBe('104 DAI');
expect(quoteDataRows[5].aggId).toBe('Agg6');
expect(quoteDataRows[5].amountReceiving).toBe('105 DAI');
});
});

View File

@ -0,0 +1,139 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SortList renders the component with initial props 1`] = `
<div
class="select-quote-popover__column-header select-quote-popover__receiving"
>
<span
class="select-quote-popover__receiving-symbol"
>
WETH
</span>
<div
class="select-quote-popover__receiving-label"
>
<span>
Receiving
</span>
<div
class="info-tooltip"
>
<div>
<div
aria-describedby="tippy-tooltip-1"
class="info-tooltip__tooltip-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<img
alt=""
src="images/mm-info-icon.svg"
/>
</div>
</div>
</div>
<svg
fill="none"
height="9"
viewBox="0 0 6 9"
width="6"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.7948 4.96973C0.365112 4.96973 0.150269 5.47754 0.462769 5.77051L2.78699 8.09473C2.96277 8.29004 3.25574 8.29004 3.45105 8.09473L5.77527 5.77051C6.06824 5.47754 5.85339 4.96973 5.44324 4.96973H0.7948ZM5.77527 2.91895L3.45105 0.594727C3.25574 0.418945 2.96277 0.418945 2.78699 0.594727L0.462769 2.91895C0.150269 3.23145 0.365112 3.71973 0.7948 3.71973H5.44324C5.85339 3.71973 6.06824 3.23145 5.77527 2.91895Z"
fill="#037DD6"
/>
</svg>
</div>
</div>
`;
exports[`SortList renders the component with initial props 2`] = `
<div
class="select-quote-popover__column-header select-quote-popover__network-fees select-quote-popover__network-fees-header"
>
<span>
Estimated network fees
</span>
<div
class="info-tooltip"
>
<div>
<div
aria-describedby="tippy-tooltip-2"
class="info-tooltip__tooltip-container"
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<img
alt=""
src="images/mm-info-icon.svg"
/>
</div>
</div>
</div>
<svg
fill="none"
height="9"
viewBox="0 0 6 9"
width="6"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0.7948 4.96973C0.365112 4.96973 0.150269 5.47754 0.462769 5.77051L2.78699 8.09473C2.96277 8.29004 3.25574 8.29004 3.45105 8.09473L5.77527 5.77051C6.06824 5.47754 5.85339 4.96973 5.44324 4.96973H0.7948ZM5.77527 2.91895L3.45105 0.594727C3.25574 0.418945 2.96277 0.418945 2.78699 0.594727L0.462769 2.91895C0.150269 3.23145 0.365112 3.71973 0.7948 3.71973H5.44324C5.85339 3.71973 6.06824 3.23145 5.77527 2.91895Z"
fill="#037DD6"
/>
</svg>
</div>
`;
exports[`SortList renders the component with initial props 3`] = `
<div
class="select-quote-popover__row select-quote-popover__row--selected"
>
<div
class="select-quote-popover__receiving"
>
<div
class="select-quote-popover__receiving-value"
>
<div
class="select-quote-popover__receiving-value-text"
title="101000000000000000000"
>
101000000000000000000
</div>
</div>
<span
class="select-quote-popover__zero-slippage"
>
0% Slippage
</span>
</div>
<div
class="select-quote-popover__network-fees"
>
$14.26
</div>
<div
class="select-quote-popover__quote-source"
>
<div
class="select-quote-popover__quote-source-label select-quote-popover__quote-source-label--orange"
>
RFQ
</div>
</div>
<div
class="select-quote-popover__caret-right"
>
<i
class="fa fa-angle-up"
/>
</div>
</div>
`;

View File

@ -0,0 +1,83 @@
import React from 'react';
import { renderWithProvider } from '../../../../../../test/jest';
import SortList from './sort-list';
const createProps = (customProps = {}) => {
return {
selectedAggId: 'Agg2',
onSelect: jest.fn(),
onCaretClick: jest.fn(),
swapToSymbol: 'WETH',
quoteDataRows: [
{
aggId: 'Agg1',
amountReceiving: '100 DAI',
destinationTokenDecimals: 18,
destinationTokenSymbol: 'DAI',
destinationTokenValue: '100000000000000000000',
isBestQuote: false,
networkFees: '$15.25',
quoteSource: 'AGG',
rawNetworkFees: '10.25',
slippage: 3,
sourceTokenDecimals: 18,
sourceTokenSymbol: 'ETH',
sourceTokenValue: '250000000000000000',
},
{
aggId: 'Agg2',
amountReceiving: '101 DAI',
destinationTokenDecimals: 18,
destinationTokenSymbol: 'DAI',
destinationTokenValue: '101000000000000000000',
isBestQuote: false,
networkFees: '$14.26',
quoteSource: 'RFQ',
rawNetworkFees: '10.26',
slippage: 3,
sourceTokenDecimals: 18,
sourceTokenSymbol: 'ETH',
sourceTokenValue: '250000000000000000',
},
{
aggId: 'Agg3',
amountReceiving: '102 DAI',
destinationTokenDecimals: 18,
destinationTokenSymbol: 'DAI',
destinationTokenValue: '102000000000000000000',
isBestQuote: false,
networkFees: '$13.27',
quoteSource: 'DEX',
rawNetworkFees: '10.27',
slippage: 3,
sourceTokenDecimals: 18,
sourceTokenSymbol: 'ETH',
sourceTokenValue: '250000000000000000',
},
],
sortDirection: 1,
setSortDirection: jest.fn(),
sortColumn: 'slippage',
setSortColumn: jest.fn(),
...customProps,
};
};
describe('SortList', () => {
it('renders the component with initial props', () => {
const { getByText } = renderWithProvider(<SortList {...createProps()} />);
expect(getByText('$15.25')).toBeInTheDocument();
expect(getByText('$14.26')).toBeInTheDocument();
expect(getByText('$13.27')).toBeInTheDocument();
expect(
document.querySelector('.select-quote-popover__receiving'),
).toMatchSnapshot();
expect(
document.querySelector('.select-quote-popover__network-fees-header'),
).toMatchSnapshot();
expect(
document.querySelector('.select-quote-popover__row--selected'),
).toMatchSnapshot();
});
});