1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 09:23:21 +01:00

Edit gas fee modal more changes (#12660)

This commit is contained in:
Jyoti Puri 2021-11-19 00:38:29 +05:30 committed by GitHub
parent d6d35d9acb
commit 2c6fb06114
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 380 additions and 109 deletions

View File

@ -581,6 +581,9 @@
"dappSuggested": {
"message": "Site suggested"
},
"dappSuggestedShortLabel": {
"message": "Site"
},
"dappSuggestedTooltip": {
"message": "$1 has recommended this price.",
"description": "$1 represents the Dapp's origin"
@ -1035,9 +1038,6 @@
"gasPriceInfoTooltipContent": {
"message": "Gas price specifies the amount of Ether you are willing to pay for each unit of gas."
},
"gasPriceLabel": {
"message": "Gas price"
},
"gasTimingHoursShort": {
"message": "$1 hrs",
"description": "$1 represents a number of hours"

View File

@ -30,6 +30,17 @@ export const GAS_RECOMMENDATIONS = {
HIGH: 'high',
};
/**
* These represent types of gas estimation
*/
export const PRIORITY_LEVELS = {
LOW: 'low',
MEDIUM: 'medium',
HIGH: 'high',
CUSTOM: 'custom',
DAPP_SUGGESTED: 'dappSuggested',
};
/**
* Represents the user customizing their gas preference
*/

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { PRIORITY_LEVELS } from '../../../../shared/constants/gas';
import { useI18nContext } from '../../../hooks/useI18nContext';
import Popover from '../../ui/popover';
import I18nValue from '../../ui/i18n-value';
@ -32,9 +33,27 @@ const EditGasFeePopover = ({ onClose }) => {
<I18nValue messageKey="maxFee" />
</span>
</div>
<EditGasItem estimateType="low" onClose={onClose} />
<EditGasItem estimateType="medium" onClose={onClose} />
<EditGasItem estimateType="high" onClose={onClose} />
<EditGasItem
priorityLevel={PRIORITY_LEVELS.LOW}
onClose={onClose}
/>
<EditGasItem
priorityLevel={PRIORITY_LEVELS.MEDIUM}
onClose={onClose}
/>
<EditGasItem
priorityLevel={PRIORITY_LEVELS.HIGH}
onClose={onClose}
/>
<div className="edit-gas-fee-popover__content__separator" />
<EditGasItem
priorityLevel={PRIORITY_LEVELS.DAPP_SUGGESTED}
onClose={onClose}
/>
<EditGasItem
priorityLevel={PRIORITY_LEVELS.CUSTOM}
onClose={onClose}
/>
</div>
</div>
</>

View File

@ -71,16 +71,18 @@ describe('EditGasFeePopover', () => {
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('🦊')).toBeInTheDocument();
expect(screen.queryByText('🦍')).toBeInTheDocument();
expect(screen.queryByText('🌐')).toBeInTheDocument();
expect(screen.queryByText('⚙')).toBeInTheDocument();
expect(screen.queryByText('Low')).toBeInTheDocument();
expect(screen.queryByText('Market')).toBeInTheDocument();
expect(screen.queryByText('Aggressive')).toBeInTheDocument();
expect(screen.queryByText('Site')).toBeInTheDocument();
expect(screen.queryByText('Advanced')).toBeInTheDocument();
});
it('should show time estimates', () => {
renderComponent();
console.log(document.body.innerHTML);
expect(screen.queryByText('6 min')).toBeInTheDocument();
expect(screen.queryByText('30 sec')).toBeInTheDocument();
expect(screen.queryAllByText('5 min')).toHaveLength(2);
expect(screen.queryByText('15 sec')).toBeInTheDocument();
});

View File

@ -1,14 +1,18 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import { getMaximumGasTotalInHexWei } from '../../../../../shared/modules/gas.utils';
import { PRIORITY_LEVELS } from '../../../../../shared/constants/gas';
import { PRIORITY_LEVEL_ICON_MAP } from '../../../../helpers/constants/gas';
import { PRIMARY } from '../../../../helpers/constants/common';
import {
decGWEIToHexWEI,
decimalToHex,
hexWEIToDecGWEI,
} from '../../../../helpers/utils/conversions.util';
import { getAdvancedGasFeeValues } from '../../../../selectors';
import { toHumanReadableTime } from '../../../../helpers/utils/util';
import { useGasFeeContext } from '../../../../contexts/gasFee';
import { useI18nContext } from '../../../../hooks/useI18nContext';
@ -16,59 +20,121 @@ import I18nValue from '../../../ui/i18n-value';
import InfoTooltip from '../../../ui/info-tooltip';
import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display';
const EditGasItem = ({ estimateType, onClose }) => {
import { useCustomTimeEstimate } from './useCustomTimeEstimate';
const EditGasItem = ({ priorityLevel, onClose }) => {
const {
estimateUsed,
gasFeeEstimates,
gasLimit,
setEstimateToUse,
updateTransaction,
maxFeePerGas: maxFeePerGasValue,
maxPriorityFeePerGas: maxPriorityFeePerGasValue,
updateTransactionUsingGasFeeEstimates,
transaction: { dappSuggestedGasFees },
} = useGasFeeContext();
const t = useI18nContext();
const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues);
let maxFeePerGas;
let maxPriorityFeePerGas;
let minWaitTime;
const { minWaitTimeEstimate, suggestedMaxFeePerGas } =
gasFeeEstimates[estimateType] || {};
const hexMaximumTransactionFee = suggestedMaxFeePerGas
if (gasFeeEstimates[priorityLevel]) {
maxFeePerGas = gasFeeEstimates[priorityLevel].suggestedMaxFeePerGas;
} else if (
priorityLevel === PRIORITY_LEVELS.DAPP_SUGGESTED &&
dappSuggestedGasFees
) {
maxFeePerGas = hexWEIToDecGWEI(dappSuggestedGasFees.maxFeePerGas);
maxPriorityFeePerGas = hexWEIToDecGWEI(
dappSuggestedGasFees.maxPriorityFeePerGas,
);
} else if (priorityLevel === PRIORITY_LEVELS.CUSTOM) {
if (estimateUsed === PRIORITY_LEVELS.CUSTOM) {
maxFeePerGas = maxFeePerGasValue;
maxPriorityFeePerGas = maxPriorityFeePerGasValue;
} else if (advancedGasFeeValues) {
maxFeePerGas =
gasFeeEstimates.estimatedBaseFee *
parseFloat(advancedGasFeeValues.maxBaseFee);
maxPriorityFeePerGas = advancedGasFeeValues.priorityFee;
}
}
const { waitTimeEstimate } = useCustomTimeEstimate({
gasFeeEstimates,
maxFeePerGas,
maxPriorityFeePerGas,
});
if (gasFeeEstimates[priorityLevel]) {
minWaitTime =
priorityLevel === PRIORITY_LEVELS.HIGH
? gasFeeEstimates?.high.minWaitTimeEstimate
: gasFeeEstimates?.low.maxWaitTimeEstimate;
} else {
minWaitTime = waitTimeEstimate;
}
const hexMaximumTransactionFee = maxFeePerGas
? getMaximumGasTotalInHexWei({
gasLimit: decimalToHex(gasLimit),
maxFeePerGas: decGWEIToHexWEI(suggestedMaxFeePerGas),
maxFeePerGas: decGWEIToHexWEI(maxFeePerGas),
})
: null;
const onOptionSelect = () => {
setEstimateToUse(estimateType);
updateTransaction(estimateType);
if (priorityLevel !== PRIORITY_LEVELS.CUSTOM) {
updateTransactionUsingGasFeeEstimates(priorityLevel);
}
// todo: open advance modal if priorityLevel is custom
onClose();
};
return (
<div
className={classNames('edit-gas-item', {
'edit-gas-item--selected': estimateType === estimateUsed,
'edit-gas-item-selected': priorityLevel === estimateUsed,
'edit-gas-item-disabled':
priorityLevel === PRIORITY_LEVELS.DAPP_SUGGESTED &&
!dappSuggestedGasFees,
})}
role="button"
onClick={onOptionSelect}
>
<span className="edit-gas-item__name">
<span className="edit-gas-item__icon">
{PRIORITY_LEVEL_ICON_MAP[estimateType]}
<span
className={`edit-gas-item__icon edit-gas-item__icon-${priorityLevel}`}
>
{PRIORITY_LEVEL_ICON_MAP[priorityLevel]}
</span>
<I18nValue messageKey={estimateType} />
</span>
<span
className={`edit-gas-item__time-estimate edit-gas-item__time-estimate-${estimateType}`}
>
{minWaitTimeEstimate && toHumanReadableTime(t, minWaitTimeEstimate)}
</span>
<span
className={`edit-gas-item__fee-estimate edit-gas-item__fee-estimate-${estimateType}`}
>
<UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount"
type={PRIMARY}
value={hexMaximumTransactionFee}
<I18nValue
messageKey={
priorityLevel === PRIORITY_LEVELS.DAPP_SUGGESTED
? 'dappSuggestedShortLabel'
: priorityLevel
}
/>
</span>
<span
className={`edit-gas-item__time-estimate edit-gas-item__time-estimate-${priorityLevel}`}
>
{minWaitTime
? minWaitTime && toHumanReadableTime(t, minWaitTime)
: '--'}
</span>
<span
className={`edit-gas-item__fee-estimate edit-gas-item__fee-estimate-${priorityLevel}`}
>
{hexMaximumTransactionFee ? (
<UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount"
type={PRIMARY}
value={hexMaximumTransactionFee}
/>
) : (
'--'
)}
</span>
<span className="edit-gas-item__tooltip">
<InfoTooltip position="top" />
</span>
@ -77,7 +143,7 @@ const EditGasItem = ({ estimateType, onClose }) => {
};
EditGasItem.propTypes = {
estimateType: PropTypes.string,
priorityLevel: PropTypes.string,
onClose: PropTypes.func,
};

View File

@ -14,6 +14,9 @@ jest.mock('../../../../store/actions', () => ({
.fn()
.mockImplementation(() => Promise.resolve()),
addPollingTokenToAppState: jest.fn(),
getGasFeeTimeEstimate: jest
.fn()
.mockImplementation(() => Promise.resolve('unknown')),
}));
const MOCK_FEE_ESTIMATE = {
@ -38,7 +41,12 @@ const MOCK_FEE_ESTIMATE = {
estimatedBaseFee: '50',
};
const renderComponent = (props) => {
const DAPP_SUGGESTED_ESTIMATE = {
maxFeePerGas: '0x59682f10',
maxPriorityFeePerGas: '0x59682f00',
};
const renderComponent = (props, transactionProps, gasFeeContextProps) => {
const store = configureStore({
metamask: {
nativeCurrency: ETH,
@ -53,41 +61,78 @@ const renderComponent = (props) => {
selectedAddress: '0xAddress',
featureFlags: { advancedInlineGas: true },
gasFeeEstimates: MOCK_FEE_ESTIMATE,
advancedGasFee: {
maxBaseFee: '1.5',
priorityFee: '2',
},
},
});
return renderWithProvider(
<GasFeeContextProvider transaction={{ txParams: { gas: '0x5208' } }}>
<EditGasItem estimateType="low" {...props} />
<GasFeeContextProvider
transaction={{ txParams: { gas: '0x5208' }, ...transactionProps }}
{...gasFeeContextProps}
>
<EditGasItem priorityLevel="low" {...props} />
</GasFeeContextProvider>,
store,
);
};
describe('EditGasItem', () => {
it('should renders low gas estimate options for estimateType low', () => {
renderComponent({ estimateType: 'low' });
it('should renders low gas estimate option for priorityLevel low', () => {
renderComponent({ priorityLevel: 'low' });
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('Low')).toBeInTheDocument();
expect(screen.queryByText('6 min')).toBeInTheDocument();
expect(screen.queryByText('5 min')).toBeInTheDocument();
expect(screen.queryByTitle('0.001113 ETH')).toBeInTheDocument();
});
it('should renders market gas estimate options for estimateType medium', () => {
renderComponent({ estimateType: 'medium' });
it('should renders market gas estimate option for priorityLevel medium', () => {
renderComponent({ priorityLevel: 'medium' });
expect(screen.queryByText('🦊')).toBeInTheDocument();
expect(screen.queryByText('Market')).toBeInTheDocument();
expect(screen.queryByText('30 sec')).toBeInTheDocument();
expect(screen.queryByText('5 min')).toBeInTheDocument();
expect(screen.queryByTitle('0.00147 ETH')).toBeInTheDocument();
});
it('should renders aggressive gas estimate options for estimateType high', () => {
renderComponent({ estimateType: 'high' });
it('should renders aggressive gas estimate option for priorityLevel high', () => {
renderComponent({ priorityLevel: 'high' });
expect(screen.queryByText('🦍')).toBeInTheDocument();
expect(screen.queryByText('Aggressive')).toBeInTheDocument();
expect(screen.queryByText('15 sec')).toBeInTheDocument();
expect(screen.queryByTitle('0.0021 ETH')).toBeInTheDocument();
});
it('should highlight option is priorityLevel is currently selected', () => {
renderComponent({ priorityLevel: 'high' }, { userFeeLevel: 'high' });
expect(
document.getElementsByClassName('edit-gas-item-selected'),
).toHaveLength(1);
});
it('should renders site gas estimate option for priorityLevel dappSuggested', () => {
renderComponent(
{ priorityLevel: 'dappSuggested' },
{ dappSuggestedGasFees: DAPP_SUGGESTED_ESTIMATE },
);
expect(screen.queryByText('🌐')).toBeInTheDocument();
expect(screen.queryByText('Site')).toBeInTheDocument();
expect(screen.queryByTitle('0.0000315 ETH')).toBeInTheDocument();
});
it('should disable site gas estimate option for is transaction does not have dappSuggestedGasFees', async () => {
renderComponent({ priorityLevel: 'dappSuggested' });
expect(
document.getElementsByClassName('edit-gas-item-disabled'),
).toHaveLength(1);
});
it('should renders advance gas estimate option for priorityLevel custom', () => {
renderComponent({ priorityLevel: 'custom' });
expect(screen.queryByText('⚙')).toBeInTheDocument();
expect(screen.queryByText('Advanced')).toBeInTheDocument();
// below value of custom gas fee estimate is default obtained from state.metamask.advancedGasFee
expect(screen.queryByTitle('0.001575 ETH')).toBeInTheDocument();
});
});

View File

@ -3,6 +3,8 @@
color: $ui-4;
cursor: pointer;
font-size: 12px;
display: flex;
align-items: center;
margin: 12px 0;
padding: 4px 12px;
height: 32px;
@ -11,8 +13,13 @@
background-color: $ui-1;
}
&-disabled {
cursor: default;
}
&__name {
display: inline-block;
display: inline-flex;
align-items: center;
color: $ui-black;
font-size: 12px;
font-weight: bold;
@ -21,6 +28,11 @@
&__icon {
margin-right: 4px;
&-custom {
font-size: 20px;
line-height: 0;
}
}
&__time-estimate {

View File

@ -0,0 +1,83 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import BigNumber from 'bignumber.js';
import { GAS_ESTIMATE_TYPES } from '../../../../../shared/constants/gas';
import {
getGasEstimateType,
getIsGasEstimatesLoading,
} from '../../../../ducks/metamask/metamask';
import { getGasFeeTimeEstimate } from '../../../../store/actions';
export const useCustomTimeEstimate = ({
gasFeeEstimates,
maxFeePerGas,
maxPriorityFeePerGas,
}) => {
const gasEstimateType = useSelector(getGasEstimateType);
const isGasEstimatesLoading = useSelector(getIsGasEstimatesLoading);
const [customEstimatedTime, setCustomEstimatedTime] = useState(null);
const returnNoEstimates =
isGasEstimatesLoading ||
gasEstimateType !== GAS_ESTIMATE_TYPES.FEE_MARKET ||
!maxPriorityFeePerGas;
// If the user has chosen a value lower than the low gas fee estimate,
// We'll need to use the useEffect hook below to make a call to calculate
// the time to show
const isUnknownLow =
gasFeeEstimates?.low &&
Number(maxPriorityFeePerGas) <
Number(gasFeeEstimates.low.suggestedMaxPriorityFeePerGas);
useEffect(() => {
if (
isGasEstimatesLoading ||
gasEstimateType !== GAS_ESTIMATE_TYPES.FEE_MARKET ||
!maxPriorityFeePerGas
)
return;
if (isUnknownLow) {
// getGasFeeTimeEstimate requires parameters in string format
getGasFeeTimeEstimate(
new BigNumber(maxPriorityFeePerGas, 10).toString(10),
new BigNumber(maxFeePerGas, 10).toString(10),
).then((result) => {
setCustomEstimatedTime(result);
});
}
}, [
gasEstimateType,
isUnknownLow,
isGasEstimatesLoading,
maxFeePerGas,
maxPriorityFeePerGas,
returnNoEstimates,
]);
if (returnNoEstimates) {
return {};
}
const { low = {}, medium = {}, high = {} } = gasFeeEstimates;
let waitTimeEstimate = '';
if (
isUnknownLow &&
customEstimatedTime &&
customEstimatedTime !== 'unknown' &&
customEstimatedTime?.upperTimeBound !== 'unknown'
) {
waitTimeEstimate = Number(customEstimatedTime?.upperTimeBound);
} else if (
Number(maxPriorityFeePerGas) >= Number(medium.suggestedMaxPriorityFeePerGas)
) {
waitTimeEstimate = high.minWaitTimeEstimate;
} else {
waitTimeEstimate = low.maxWaitTimeEstimate;
}
return { waitTimeEstimate };
};

View File

@ -31,5 +31,10 @@
width: 30%;
}
}
&__separator {
border-top: 1px solid $ui-grey;
margin: 8px 12px;
}
}
}

View File

@ -17,12 +17,10 @@ export default function TransactionDetail({ rows = [], onEdit }) {
const t = useI18nContext();
const {
gasLimit,
gasPrice,
estimateUsed,
maxFeePerGas,
maxPriorityFeePerGas,
transaction,
supportsEIP1559,
} = useGasFeeContext();
if (EIP_1559_V2 && estimateUsed) {
@ -48,23 +46,14 @@ export default function TransactionDetail({ rows = [], onEdit }) {
<Typography fontSize="12px" color={COLORS.GREY}>
{t('dappSuggestedTooltip', [transaction.origin])}
</Typography>
{supportsEIP1559 ? (
<>
<Typography fontSize="12px">
<b>{t('maxBaseFee')}</b>
{maxFeePerGas}
</Typography>
<Typography fontSize="12px">
<b>{t('maxPriorityFee')}</b>
{maxPriorityFeePerGas}
</Typography>
</>
) : (
<Typography fontSize="12px">
<b>{t('gasPriceLabel')}</b>
{gasPrice}
</Typography>
)}
<Typography fontSize="12px">
<b>{t('maxBaseFee')}</b>
{maxFeePerGas}
</Typography>
<Typography fontSize="12px">
<b>{t('maxPriorityFee')}</b>
{maxPriorityFeePerGas}
</Typography>
<Typography fontSize="12px">
<b>{t('gasLimit')}</b>
{gasLimit}

View File

@ -31,7 +31,7 @@ export function useGasFeeContext() {
GasFeeContextProvider.propTypes = {
children: PropTypes.node.isRequired,
defaultEstimateToUse: PropTypes.string,
transaction: PropTypes.object.isRequired,
transaction: PropTypes.object,
minimumGasLimit: PropTypes.string,
editGasMode: PropTypes.string,
};

View File

@ -1,4 +1,4 @@
import { useCallback, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import {
@ -108,6 +108,19 @@ export function useGasFeeInputs(
return estimateToUse;
});
/**
* In EIP-1559 V2 designs change to gas estimate is always updated to transaction
* Thus callback setEstimateToUse can be deprecate in favour of this useEffect
* so that transaction is source of truth whenever possible.
*/
useEffect(() => {
if (areDappSuggestedAndTxParamGasFeesTheSame(transaction)) {
setEstimateUsed('dappSuggested');
} else if (transaction?.userFeeLevel) {
setEstimateUsed(transaction?.userFeeLevel);
}
}, [setEstimateUsed, transaction]);
const [gasLimit, setGasLimit] = useState(() =>
Number(hexToDecimal(transaction?.txParams?.gas ?? '0x0')),
);
@ -198,7 +211,7 @@ export function useGasFeeInputs(
}
}, [minimumGasLimit, gasErrors.gasLimit, transaction]);
const { updateTransaction } = useTransactionFunctions({
const { updateTransactionUsingGasFeeEstimates } = useTransactionFunctions({
defaultEstimateToUse,
gasLimit,
gasPrice,
@ -289,6 +302,6 @@ export function useGasFeeInputs(
gasWarnings,
hasGasErrors,
supportsEIP1559,
updateTransaction,
updateTransactionUsingGasFeeEstimates,
};
}

View File

@ -1,6 +1,7 @@
import { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { PRIORITY_LEVELS } from '../../../shared/constants/gas';
import {
decGWEIToHexWEI,
decimalToHex,
@ -16,24 +17,19 @@ export const useTransactionFunctions = ({
const dispatch = useDispatch();
const updateTransaction = useCallback(
(estimateType) => {
(estimateUsed, maxFeePerGas, maxPriorityFeePerGas) => {
const newGasSettings = {
gas: decimalToHex(gasLimit),
gasLimit: decimalToHex(gasLimit),
estimateSuggested: defaultEstimateToUse,
estimateUsed: estimateType,
estimateUsed,
maxFeePerGas,
maxPriorityFeePerGas,
};
newGasSettings.maxFeePerGas = decGWEIToHexWEI(
gasFeeEstimates[estimateType].suggestedMaxFeePerGas,
);
newGasSettings.maxPriorityFeePerGas = decGWEIToHexWEI(
gasFeeEstimates[estimateType].suggestedMaxPriorityFeePerGas,
);
const updatedTxMeta = {
...transaction,
userFeeLevel: estimateType || 'custom',
userFeeLevel: estimateUsed || 'custom',
txParams: {
...transaction.txParams,
...newGasSettings,
@ -42,8 +38,35 @@ export const useTransactionFunctions = ({
dispatch(updateTransactionFn(updatedTxMeta));
},
[defaultEstimateToUse, dispatch, gasLimit, gasFeeEstimates, transaction],
[defaultEstimateToUse, dispatch, gasLimit, transaction],
);
return { updateTransaction };
const updateTransactionUsingGasFeeEstimates = useCallback(
(gasFeeEstimateToUse) => {
if (gasFeeEstimateToUse === PRIORITY_LEVELS.DAPP_SUGGESTED) {
const {
maxFeePerGas,
maxPriorityFeePerGas,
} = transaction?.dappSuggestedGasFees;
updateTransaction(
PRIORITY_LEVELS.CUSTOM,
maxFeePerGas,
maxPriorityFeePerGas,
);
} else {
const {
suggestedMaxFeePerGas,
suggestedMaxPriorityFeePerGas,
} = gasFeeEstimates[gasFeeEstimateToUse];
updateTransaction(
gasFeeEstimateToUse,
decGWEIToHexWEI(suggestedMaxFeePerGas),
decGWEIToHexWEI(suggestedMaxPriorityFeePerGas),
);
}
},
[gasFeeEstimates, transaction?.dappSuggestedGasFees, updateTransaction],
);
return { updateTransactionUsingGasFeeEstimates };
};

View File

@ -26,7 +26,6 @@ const GasDetailsItem = ({
isMainnet,
maxFeePerGas,
maxPriorityFeePerGas,
supportsEIP1559,
txData,
useNativeCurrencyAsPrimaryCurrency,
}) => {
@ -120,16 +119,14 @@ const GasDetailsItem = ({
</Box>,
])}
subTitle={
supportsEIP1559 && (
<GasTiming
maxPriorityFeePerGas={hexWEIToDecGWEI(
maxPriorityFeePerGas || txData.txParams.maxPriorityFeePerGas,
)}
maxFeePerGas={hexWEIToDecGWEI(
maxFeePerGas || txData.txParams.maxFeePerGas,
)}
/>
)
<GasTiming
maxPriorityFeePerGas={hexWEIToDecGWEI(
maxPriorityFeePerGas || txData.txParams.maxPriorityFeePerGas,
)}
maxFeePerGas={hexWEIToDecGWEI(
maxFeePerGas || txData.txParams.maxFeePerGas,
)}
/>
}
/>
);
@ -141,7 +138,6 @@ GasDetailsItem.propTypes = {
isMainnet: PropTypes.bool,
maxFeePerGas: PropTypes.string,
maxPriorityFeePerGas: PropTypes.string,
supportsEIP1559: PropTypes.bool,
txData: PropTypes.object,
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
};

View File

@ -1,5 +1,5 @@
import React from 'react';
import { screen } from '@testing-library/react';
import { screen, waitFor } from '@testing-library/react';
import { ETH } from '../../../helpers/constants/common';
import { GasFeeContextProvider } from '../../../contexts/gasFee';
@ -14,6 +14,7 @@ jest.mock('../../../store/actions', () => ({
.fn()
.mockImplementation(() => Promise.resolve()),
addPollingTokenToAppState: jest.fn(),
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
}));
const render = (props) => {
@ -37,28 +38,34 @@ const render = (props) => {
return renderWithProvider(
<GasFeeContextProvider {...props}>
<GasDetailsItem txData={{}} {...props} />
<GasDetailsItem txData={{ txParams: {} }} {...props} />
</GasFeeContextProvider>,
store,
);
};
describe('GasDetailsItem', () => {
it('should render label', () => {
it('should render label', async () => {
render();
expect(screen.queryByText('Gas')).toBeInTheDocument();
expect(screen.queryByText('(estimated)')).toBeInTheDocument();
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
expect(screen.queryByText('ETH')).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByText('Gas')).toBeInTheDocument();
expect(screen.queryByText('(estimated)')).toBeInTheDocument();
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
expect(screen.queryByText('ETH')).toBeInTheDocument();
});
});
it('should show warning icon if estimates are high', () => {
it('should show warning icon if estimates are high', async () => {
render({ defaultEstimateToUse: 'high' });
expect(screen.queryByText('⚠ Max fee:')).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByText('⚠ Max fee:')).toBeInTheDocument();
});
});
it('should not show warning icon if estimates are not high', () => {
it('should not show warning icon if estimates are not high', async () => {
render({ defaultEstimateToUse: 'low' });
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
});
});
});