- {warning && !isGasEstimatesLoading && (
-
- )}
{showTopError && (
@@ -156,6 +148,16 @@ export default function EditGasDisplay({
/>
)}
+ {isNetworkBusy ? (
+
+ ) : null}
{mode === EDIT_GAS_MODES.SPEED_UP && (
, store);
+}
+
+describe('EditGasDisplay', () => {
+ describe('if getIsNetworkBusy returns a truthy value', () => {
+ it('informs the user', () => {
+ render({ componentProps: { isNetworkBusy: true } });
+ expect(
+ screen.getByText(
+ 'Network is busy. Gas prices are high and estimates are less accurate.',
+ ),
+ ).toBeInTheDocument();
+ });
+ });
+
+ describe('if getIsNetworkBusy does not return a truthy value', () => {
+ it('does not inform the user', () => {
+ render({ componentProps: { isNetworkBusy: false } });
+ expect(
+ screen.queryByText(
+ 'Network is busy. Gas prices are high and estimates are less accurate.',
+ ),
+ ).not.toBeInTheDocument();
+ });
+ });
+});
diff --git a/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.js b/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.js
index 7f4f34e77823..13987af3bc4d 100644
--- a/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.js
+++ b/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.js
@@ -1,5 +1,6 @@
import React from 'react';
+import { NETWORK_CONGESTION_THRESHOLDS } from '../../../../../../shared/constants/gas';
import { useGasFeeContext } from '../../../../../contexts/gasFee';
import I18nValue from '../../../../ui/i18n-value';
import { NetworkStabilityTooltip } from '../tooltips';
@@ -24,24 +25,24 @@ const determineStatusInfo = (givenNetworkCongestion) => {
const color = GRADIENT_COLORS[colorIndex];
const sliderTickValue = colorIndex * 10;
- if (networkCongestion <= 0.33) {
+ if (networkCongestion >= NETWORK_CONGESTION_THRESHOLDS.BUSY) {
return {
- statusLabel: 'notBusy',
- tooltipLabel: 'lowLowercase',
+ statusLabel: 'busy',
+ tooltipLabel: 'highLowercase',
color,
sliderTickValue,
};
- } else if (networkCongestion > 0.66) {
+ } else if (networkCongestion >= NETWORK_CONGESTION_THRESHOLDS.STABLE) {
return {
- statusLabel: 'busy',
- tooltipLabel: 'highLowercase',
+ statusLabel: 'stable',
+ tooltipLabel: 'stableLowercase',
color,
sliderTickValue,
};
}
return {
- statusLabel: 'stable',
- tooltipLabel: 'stableLowercase',
+ statusLabel: 'notBusy',
+ tooltipLabel: 'lowLowercase',
color,
sliderTickValue,
};
diff --git a/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js b/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
index 004838aa0d67..29940d981d88 100644
--- a/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
+++ b/ui/components/app/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js
@@ -20,31 +20,31 @@ const renderComponent = ({ networkCongestion }) => {
describe('StatusSlider', () => {
it('should show "Not busy" when networkCongestion is less than 0.33', () => {
- const { queryByText } = renderComponent({ networkCongestion: 0.32 });
- expect(queryByText('Not busy')).toBeInTheDocument();
+ const { getByText } = renderComponent({ networkCongestion: 0.32 });
+ expect(getByText('Not busy')).toBeInTheDocument();
});
- it('should show "Not busy" when networkCongestion is 0.33', () => {
- const { queryByText } = renderComponent({ networkCongestion: 0.33 });
- expect(queryByText('Not busy')).toBeInTheDocument();
+ it('should show "Stable" when networkCongestion is 0.33', () => {
+ const { getByText } = renderComponent({ networkCongestion: 0.33 });
+ expect(getByText('Stable')).toBeInTheDocument();
});
it('should show "Stable" when networkCongestion is between 0.33 and 0.66', () => {
- const { queryByText } = renderComponent({ networkCongestion: 0.5 });
- expect(queryByText('Stable')).toBeInTheDocument();
+ const { getByText } = renderComponent({ networkCongestion: 0.5 });
+ expect(getByText('Stable')).toBeInTheDocument();
});
- it('should show "Stable" when networkCongestion is 0.66', () => {
- const { queryByText } = renderComponent({ networkCongestion: 0.66 });
- expect(queryByText('Stable')).toBeInTheDocument();
+ it('should show "Busy" when networkCongestion is 0.66', () => {
+ const { getByText } = renderComponent({ networkCongestion: 0.66 });
+ expect(getByText('Busy')).toBeInTheDocument();
});
it('should show "Busy" when networkCongestion is greater than 0.66', () => {
- const { queryByText } = renderComponent({ networkCongestion: 0.67 });
- expect(queryByText('Busy')).toBeInTheDocument();
+ const { getByText } = renderComponent({ networkCongestion: 0.67 });
+ expect(getByText('Busy')).toBeInTheDocument();
});
- it('should show "Stable" if networkCongestion has not been set yet', () => {
+ it('should show "Stable" if networkCongestion is not available yet', () => {
const { getByText } = renderComponent({});
expect(getByText('Stable')).toBeInTheDocument();
});
diff --git a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js
index 314627cece19..d66f13af69d3 100644
--- a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js
+++ b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js
@@ -61,8 +61,6 @@ export default function EditGasPopover({
supportsEIP1559;
const [showEducationContent, setShowEducationContent] = useState(false);
- const [warning] = useState(null);
-
const [
dappSuggestedGasFeeAcknowledged,
setDappSuggestedGasFeeAcknowledged,
@@ -109,6 +107,7 @@ export default function EditGasPopover({
balanceError,
estimatesUnavailableWarning,
estimatedBaseFee,
+ isNetworkBusy,
} = useGasFeeInputs(
defaultEstimateToUse,
updatedTransaction,
@@ -264,7 +263,6 @@ export default function EditGasPopover({
{process.env.IN_TEST ? null :
}
>
diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js
index 99d9b7d9f75d..09635ae045f5 100644
--- a/ui/ducks/metamask/metamask.js
+++ b/ui/ducks/metamask/metamask.js
@@ -1,6 +1,10 @@
import { addHexPrefix, isHexString, stripHexPrefix } from 'ethereumjs-util';
import * as actionConstants from '../../store/actionConstants';
import { ALERT_TYPES } from '../../../shared/constants/alerts';
+import {
+ GAS_ESTIMATE_TYPES,
+ NETWORK_CONGESTION_THRESHOLDS,
+} from '../../../shared/constants/gas';
import { NETWORK_TYPE_RPC } from '../../../shared/constants/network';
import {
accountsWithSendEtherInfoSelector,
@@ -11,7 +15,7 @@ import { updateTransaction } from '../../store/actions';
import { setCustomGasLimit, setCustomGasPrice } from '../gas/gas.duck';
import { decGWEIToHexWEI } from '../../helpers/utils/conversions.util';
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
-import { GAS_ESTIMATE_TYPES } from '../../../shared/constants/gas';
+
import { KEYRING_TYPES } from '../../../shared/constants/hardware-wallets';
export default function reduceMetamask(state = {}, action) {
@@ -361,6 +365,13 @@ export function getIsGasEstimatesLoading(state) {
return isGasEstimatesLoading;
}
+export function getIsNetworkBusy(state) {
+ const gasFeeEstimates = getGasFeeEstimates(state);
+ return (
+ gasFeeEstimates?.networkCongestion >= NETWORK_CONGESTION_THRESHOLDS.BUSY
+ );
+}
+
export function getCompletedOnboarding(state) {
return state.metamask.completedOnboarding;
}
diff --git a/ui/ducks/metamask/metamask.test.js b/ui/ducks/metamask/metamask.test.js
index 0c75e7f47ff7..b14c4ed5c199 100644
--- a/ui/ducks/metamask/metamask.test.js
+++ b/ui/ducks/metamask/metamask.test.js
@@ -3,6 +3,7 @@ import * as actionConstants from '../../store/actionConstants';
import reduceMetamask, {
getBlockGasLimit,
getConversionRate,
+ getIsNetworkBusy,
getNativeCurrency,
getSendHexDataFeatureFlagState,
getSendToAccounts,
@@ -414,4 +415,30 @@ describe('MetaMask Reducers', () => {
).toStrictEqual(false);
});
});
+
+ describe('getIsNetworkBusy', () => {
+ it('should return true if state.metamask.gasFeeEstimates.networkCongestion is over the "busy" threshold', () => {
+ expect(
+ getIsNetworkBusy({
+ metamask: { gasFeeEstimates: { networkCongestion: 0.67 } },
+ }),
+ ).toBe(true);
+ });
+
+ it('should return true if state.metamask.gasFeeEstimates.networkCongestion is right at the "busy" threshold', () => {
+ expect(
+ getIsNetworkBusy({
+ metamask: { gasFeeEstimates: { networkCongestion: 0.66 } },
+ }),
+ ).toBe(true);
+ });
+
+ it('should return false if state.metamask.gasFeeEstimates.networkCongestion is not over the "busy" threshold', () => {
+ expect(
+ getIsNetworkBusy({
+ metamask: { gasFeeEstimates: { networkCongestion: 0.65 } },
+ }),
+ ).toBe(false);
+ });
+ });
});
diff --git a/ui/hooks/gasFeeInput/useGasFeeInputs.js b/ui/hooks/gasFeeInput/useGasFeeInputs.js
index ade4f0382e2d..63b5b3fe6406 100644
--- a/ui/hooks/gasFeeInput/useGasFeeInputs.js
+++ b/ui/hooks/gasFeeInput/useGasFeeInputs.js
@@ -111,6 +111,7 @@ export function useGasFeeInputs(
gasFeeEstimates,
isGasEstimatesLoading,
estimatedGasFeeTimeBounds,
+ isNetworkBusy,
} = useGasFeeEstimates();
const userPrefersAdvancedGas = useSelector(getAdvancedInlineGasShown);
@@ -342,6 +343,7 @@ export function useGasFeeInputs(
gasFeeEstimates,
gasEstimateType,
estimatedGasFeeTimeBounds,
+ isNetworkBusy,
onManualChange,
estimatedBaseFee,
// error and warnings
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 236e092d5e79..849d83871810 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -5,6 +5,7 @@ import {
getGasEstimateType,
getGasFeeEstimates,
getIsGasEstimatesLoading,
+ getIsNetworkBusy,
} from '../ducks/metamask/metamask';
import { useSafeGasEstimatePolling } from './useSafeGasEstimatePolling';
@@ -38,6 +39,7 @@ export function useGasFeeEstimates() {
shallowEqual,
);
const isGasEstimatesLoading = useSelector(getIsGasEstimatesLoading);
+ const isNetworkBusy = useSelector(getIsNetworkBusy);
useSafeGasEstimatePolling();
return {
@@ -45,5 +47,6 @@ export function useGasFeeEstimates() {
gasEstimateType,
estimatedGasFeeTimeBounds,
isGasEstimatesLoading,
+ isNetworkBusy,
};
}
diff --git a/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.js b/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.js
index f3eab09ba999..c998daa862b1 100644
--- a/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.js
+++ b/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.js
@@ -22,6 +22,7 @@ const TransactionAlerts = ({
estimateUsed,
hasSimulationError,
supportsEIP1559V2,
+ isNetworkBusy,
} = useGasFeeContext();
const pendingTransactions = useSelector(submittedPendingTransactionsSelector);
const t = useI18nContext();
@@ -107,6 +108,13 @@ const TransactionAlerts = ({
type="warning"
/>
)}
+ {isNetworkBusy ? (
+
}
+ iconFillColor="#f8c000"
+ type="warning"
+ />
+ ) : null}
);
};
diff --git a/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.test.js b/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.test.js
index 555a091a4f05..038e9c3d3a29 100644
--- a/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.test.js
+++ b/ui/pages/confirm-transaction-base/transaction-alerts/transaction-alerts.test.js
@@ -1,172 +1,307 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
-
-import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas';
-import {
- TRANSACTION_ENVELOPE_TYPES,
- TRANSACTION_STATUSES,
-} from '../../../../shared/constants/transaction';
-import { renderWithProvider } from '../../../../test/lib/render-helpers';
-import mockEstimates from '../../../../test/data/mock-estimates.json';
-import mockState from '../../../../test/data/mock-state.json';
-import { GasFeeContextProvider } from '../../../contexts/gasFee';
+import { fireEvent } from '@testing-library/react';
+import { renderWithProvider } from '../../../../test/jest';
+import { submittedPendingTransactionsSelector } from '../../../selectors/transactions';
+import { useGasFeeContext } from '../../../contexts/gasFee';
import configureStore from '../../../store/store';
-
import TransactionAlerts from './transaction-alerts';
-jest.mock('../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
- .fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
-}));
-
-const render = ({ componentProps, transactionProps, state }) => {
- const store = configureStore({
- metamask: {
- ...mockState.metamask,
- accounts: {
- [mockState.metamask.selectedAddress]: {
- address: mockState.metamask.selectedAddress,
- balance: '0x1F4',
- },
- },
- gasFeeEstimates: mockEstimates[GAS_ESTIMATE_TYPES.FEE_MARKET],
- ...state,
- },
- });
+jest.mock('../../../selectors/transactions', () => {
+ return {
+ ...jest.requireActual('../../../selectors/transactions'),
+ submittedPendingTransactionsSelector: jest.fn(),
+ };
+});
- return renderWithProvider(
-
-
- ,
- store,
+jest.mock('../../../contexts/gasFee');
+
+function render({
+ componentProps = {},
+ useGasFeeContextValue = {},
+ submittedPendingTransactionsSelectorValue = null,
+}) {
+ useGasFeeContext.mockReturnValue(useGasFeeContextValue);
+ submittedPendingTransactionsSelector.mockReturnValue(
+ submittedPendingTransactionsSelectorValue,
);
-};
+ const store = configureStore({});
+ return renderWithProvider(
, store);
+}
describe('TransactionAlerts', () => {
- beforeEach(() => {
- process.env.EIP_1559_V2 = true;
- });
+ describe('when supportsEIP1559V2 from useGasFeeContext is truthy', () => {
+ describe('if hasSimulationError from useGasFeeContext is true', () => {
+ it('informs the user that a simulation of the transaction failed', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ hasSimulationError: true,
+ },
+ });
- afterEach(() => {
- process.env.EIP_1559_V2 = false;
- });
+ expect(
+ getByText(
+ 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.',
+ ),
+ ).toBeInTheDocument();
+ });
- it('should returning warning message for low gas estimate', () => {
- render({ transactionProps: { userFeeLevel: 'low' } });
- expect(
- document.getElementsByClassName('actionable-message--warning'),
- ).toHaveLength(1);
- });
+ describe('if the user has not acknowledged the failure', () => {
+ it('offers the user an option to bypass the warning', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ hasSimulationError: true,
+ },
+ });
+ expect(getByText('I want to proceed anyway')).toBeInTheDocument();
+ });
- it('should return null for gas estimate other than low', () => {
- render({ transactionProps: { userFeeLevel: 'high' } });
- expect(
- document.getElementsByClassName('actionable-message--warning'),
- ).toHaveLength(0);
- });
+ it('calls setUserAcknowledgedGasMissing if the user bypasses the warning', () => {
+ const setUserAcknowledgedGasMissing = jest.fn();
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ hasSimulationError: true,
+ },
+ componentProps: { setUserAcknowledgedGasMissing },
+ });
+ fireEvent.click(getByText('I want to proceed anyway'));
+ expect(setUserAcknowledgedGasMissing).toHaveBeenCalled();
+ });
+ });
- it('should not show insufficient balance message if transaction value is less than balance', () => {
- render({
- transactionProps: {
- userFeeLevel: 'high',
- txParams: { value: '0x64' },
- },
+ describe('if the user has already acknowledged the failure', () => {
+ it('does not offer the user an option to bypass the warning', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ hasSimulationError: true,
+ },
+ componentProps: { userAcknowledgedGasMissing: true },
+ });
+ expect(
+ queryByText('I want to proceed anyway'),
+ ).not.toBeInTheDocument();
+ });
+ });
});
- expect(screen.queryByText('Insufficient funds.')).not.toBeInTheDocument();
- });
- it('should show insufficient balance message if transaction value is more than balance', () => {
- render({
- transactionProps: {
- userFeeLevel: 'high',
- txParams: { value: '0x5208' },
- },
+ describe('if hasSimulationError from useGasFeeContext is falsy', () => {
+ it('does not inform the user that a simulation of the transaction failed', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ },
+ });
+ expect(
+ queryByText(
+ 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.',
+ ),
+ ).not.toBeInTheDocument();
+ });
});
- expect(screen.queryByText('Insufficient funds.')).toBeInTheDocument();
- });
- it('should show pending transaction message if there are >= 1 pending transactions', () => {
- render({
- state: {
- currentNetworkTxList: [
- {
- id: 0,
- time: 0,
- txParams: {
- from: mockState.metamask.selectedAddress,
- to: '0xRecipient',
- },
- status: TRANSACTION_STATUSES.SUBMITTED,
+ describe('if the length of pendingTransactions is 1', () => {
+ it('informs the user that they have a pending transaction', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: { supportsEIP1559V2: true },
+ submittedPendingTransactionsSelectorValue: [{ some: 'transaction' }],
+ });
+ expect(
+ getByText('You have (1) pending transaction.'),
+ ).toBeInTheDocument();
+ });
+ });
+
+ describe('if the length of pendingTransactions is more than 1', () => {
+ it('informs the user that they have pending transactions', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: { supportsEIP1559V2: true },
+ submittedPendingTransactionsSelectorValue: [
+ { some: 'transaction' },
+ { some: 'transaction' },
+ ],
+ });
+ expect(
+ getByText('You have (2) pending transactions.'),
+ ).toBeInTheDocument();
+ });
+ });
+
+ describe('if the length of pendingTransactions is 0', () => {
+ it('does not inform the user that they have pending transactions', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: { supportsEIP1559V2: true },
+ submittedPendingTransactionsSelectorValue: [],
+ });
+ expect(
+ queryByText('You have (0) pending transactions.'),
+ ).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if balanceError from useGasFeeContext is true', () => {
+ it('informs the user that they have insufficient funds', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ balanceError: true,
+ },
+ });
+ expect(getByText('Insufficient funds.')).toBeInTheDocument();
+ });
+ });
+
+ describe('if balanceError from useGasFeeContext is falsy', () => {
+ it('does not inform the user that they have insufficient funds', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ balanceError: false,
},
- ],
- },
+ });
+ expect(queryByText('Insufficient funds.')).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if estimateUsed from useGasFeeContext is "low"', () => {
+ it('informs the user that the current transaction is queued', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ estimateUsed: 'low',
+ },
+ });
+ expect(
+ getByText(
+ 'Future transactions will queue after this one. This price was last seen was some time ago.',
+ ),
+ ).toBeInTheDocument();
+ });
+ });
+
+ describe('if estimateUsed from useGasFeeContext is not "low"', () => {
+ it('does not inform the user that the current transaction is queued', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ estimateUsed: 'something_else',
+ },
+ });
+ expect(
+ queryByText(
+ 'Future transactions will queue after this one. This price was last seen was some time ago.',
+ ),
+ ).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if isNetworkBusy from useGasFeeContext is truthy', () => {
+ it('informs the user that the network is busy', () => {
+ const { getByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ isNetworkBusy: true,
+ },
+ });
+ expect(
+ getByText(
+ 'Network is busy. Gas prices are high and estimates are less accurate.',
+ ),
+ ).toBeInTheDocument();
+ });
+ });
+
+ describe('if isNetworkBusy from useGasFeeContext is falsy', () => {
+ it('does not inform the user that the network is busy', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: true,
+ isNetworkBusy: false,
+ },
+ });
+ expect(
+ queryByText(
+ 'Network is busy. Gas prices are high and estimates are less accurate.',
+ ),
+ ).not.toBeInTheDocument();
+ });
});
- expect(
- screen.queryByText('You have (1) pending transaction.'),
- ).toBeInTheDocument();
});
- describe('SimulationError Message', () => {
- it('should show simulation error message along with option to proceed anyway if transaction.simulationFails is true', () => {
- render({ transactionProps: { simulationFails: true } });
- expect(
- screen.queryByText(
- 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.',
- ),
- ).toBeInTheDocument();
- expect(
- screen.queryByText('I want to proceed anyway'),
- ).toBeInTheDocument();
- });
-
- it('should not show options to acknowledge gas-missing warning if component prop userAcknowledgedGasMissing is already true', () => {
- render({
- componentProps: {
- userAcknowledgedGasMissing: true,
- },
- transactionProps: { simulationFails: true },
- });
- expect(
- screen.queryByText(
- 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.',
- ),
- ).toBeInTheDocument();
- expect(
- screen.queryByText('I want to proceed anyway'),
- ).not.toBeInTheDocument();
- });
-
- it('should call prop setUserAcknowledgedGasMissing if option to acknowledge gas-missing warning is clicked', () => {
- const setUserAcknowledgedGasMissing = jest.fn();
- render({
- componentProps: {
- setUserAcknowledgedGasMissing,
- },
- transactionProps: { simulationFails: true },
- });
- fireEvent.click(screen.queryByText('I want to proceed anyway'));
- expect(setUserAcknowledgedGasMissing).toHaveBeenCalledTimes(1);
- });
-
- it('should return null for legacy transactions', () => {
- const { container } = render({
- transactionProps: {
- txParams: {
- type: TRANSACTION_ENVELOPE_TYPES.LEGACY,
+ describe('when supportsEIP1559V2 from useGasFeeContext is falsy', () => {
+ describe('if hasSimulationError from useGasFeeContext is true', () => {
+ it('does not inform the user that a simulation of the transaction failed', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: false,
+ hasSimulationError: true,
+ },
+ });
+
+ expect(
+ queryByText(
+ 'We were not able to estimate gas. There might be an error in the contract and this transaction may fail.',
+ ),
+ ).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if the length of pendingTransactions is at least 1', () => {
+ it('informs the user that they have a pending transaction', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: { supportsEIP1559V2: false },
+ submittedPendingTransactionsSelectorValue: [{ some: 'transaction' }],
+ });
+ expect(
+ queryByText('You have (1) pending transaction.'),
+ ).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if balanceError from useGasFeeContext is true', () => {
+ it('informs the user that they have insufficient funds', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: false,
+ balanceError: true,
+ },
+ });
+ expect(queryByText('Insufficient funds.')).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if estimateUsed from useGasFeeContext is "low"', () => {
+ it('informs the user that the current transaction is queued', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: false,
+ estimateUsed: 'low',
+ },
+ });
+ expect(
+ queryByText(
+ 'Future transactions will queue after this one. This price was last seen was some time ago.',
+ ),
+ ).not.toBeInTheDocument();
+ });
+ });
+
+ describe('if isNetworkBusy from useGasFeeContext is truthy', () => {
+ it('does not inform the user that the network is busy', () => {
+ const { queryByText } = render({
+ useGasFeeContextValue: {
+ supportsEIP1559V2: false,
+ isNetworkBusy: true,
},
- },
+ });
+ expect(
+ queryByText(
+ 'Network is busy. Gas prices are high and estimates are less accurate.',
+ ),
+ ).not.toBeInTheDocument();
});
- expect(container.firstChild).toBeNull();
});
});
});
diff --git a/ui/selectors/transactions.js b/ui/selectors/transactions.js
index 55cb4d67597c..77980087baec 100644
--- a/ui/selectors/transactions.js
+++ b/ui/selectors/transactions.js
@@ -10,8 +10,11 @@ import {
TRANSACTION_TYPES,
} from '../../shared/constants/transaction';
import { transactionMatchesNetwork } from '../../shared/modules/transaction.utils';
-import { getCurrentChainId, deprecatedGetCurrentNetworkId } from './selectors';
-import { getSelectedAddress } from '.';
+import {
+ getCurrentChainId,
+ deprecatedGetCurrentNetworkId,
+ getSelectedAddress,
+} from './selectors';
export const incomingTxListSelector = (state) => {
const { showIncomingTransactions } = state.metamask.featureFlags;