From 556a765cc0afee5cc2a08b4b6a1b27af3411b0d0 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 15 Feb 2024 15:53:58 -0500
Subject: [PATCH 01/74] Added generic polling hook
---
app/scripts/metamask-controller.js | 6 ++
ui/hooks/usePolling.test.js | 84 +++++++++++++++++++
ui/hooks/usePolling.ts | 49 +++++++++++
.../confirm-transaction.component.js | 43 +++-------
.../confirm-transaction.test.js | 12 ++-
.../confirm-transaction.transaction.test.js | 5 +-
ui/store/actions.ts | 25 ++++++
7 files changed, 186 insertions(+), 38 deletions(-)
create mode 100644 ui/hooks/usePolling.test.js
create mode 100644 ui/hooks/usePolling.ts
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index e8f7d9f6887f..97a78cfa969f 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -3301,6 +3301,12 @@ export default class MetamaskController extends EventEmitter {
),
// GasFeeController
+ gasFeeStartPollingByNetworkClientId:
+ gasFeeController.startPollingByNetworkClientId.bind(gasFeeController),
+
+ gasFeeStopPollingByPollingToken:
+ gasFeeController.stopPollingByPollingToken.bind(gasFeeController),
+
getGasFeeEstimatesAndStartPolling:
gasFeeController.getGasFeeEstimatesAndStartPolling.bind(
gasFeeController,
diff --git a/ui/hooks/usePolling.test.js b/ui/hooks/usePolling.test.js
new file mode 100644
index 000000000000..4611d5effee3
--- /dev/null
+++ b/ui/hooks/usePolling.test.js
@@ -0,0 +1,84 @@
+import React from 'react';
+import { renderHook, cleanup } from '@testing-library/react-hooks';
+import { Provider } from 'react-redux';
+import configureStore from '../store/store';
+import usePolling from './usePolling';
+
+describe('usePolling', () => {
+ // eslint-disable-next-line jest/no-done-callback
+ it('calls startPollingByNetworkClientId and callback option args with polling token when component instantiating the hook mounts', (done) => {
+ const mockStart = jest.fn().mockImplementation(() => {
+ return Promise.resolve('pollingToken');
+ });
+ const mockStop = jest.fn();
+ const networkClientId = 'mainnet';
+ const options = {};
+ const mockState = {
+ metamask: {},
+ };
+
+ const wrapper = ({ children }) => (
+ <>
+ {children}
+ >
+ );
+
+ renderHook(
+ () => {
+ usePolling({
+ callback: (pollingToken) => {
+ expect(mockStart).toHaveBeenCalledWith(networkClientId, options);
+ expect(pollingToken).toBeDefined();
+ done();
+ return (_pollingToken) => {
+ // noop
+ };
+ },
+ startPollingByNetworkClientId: mockStart,
+ stopPollingByPollingToken: mockStop,
+ networkClientId,
+ options,
+ });
+ },
+ { wrapper },
+ );
+ });
+ // eslint-disable-next-line jest/no-done-callback
+ it('calls the cleanup function with the correct pollingToken when unmounted', (done) => {
+ const mockStart = jest.fn().mockImplementation(() => {
+ return Promise.resolve('pollingToken');
+ });
+ const mockStop = jest.fn();
+ const networkClientId = 'mainnet';
+ const options = {};
+ const mockState = {
+ metamask: {},
+ };
+
+ const wrapper = ({ children }) => (
+ <>
+ {children}
+ >
+ );
+
+ renderHook(
+ () => {
+ usePolling({
+ callback: () => {
+ return (_pollingToken) => {
+ expect(mockStop).toHaveBeenCalledWith(_pollingToken);
+ expect(_pollingToken).toBeDefined();
+ done();
+ };
+ },
+ startPollingByNetworkClientId: mockStart,
+ stopPollingByPollingToken: mockStop,
+ networkClientId,
+ options,
+ });
+ },
+ { wrapper },
+ );
+ cleanup();
+ });
+});
diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts
new file mode 100644
index 000000000000..42a141547f84
--- /dev/null
+++ b/ui/hooks/usePolling.ts
@@ -0,0 +1,49 @@
+import { useEffect, useRef } from 'react';
+
+type UsePollingOptions = {
+ callback?: (pollingToken: string) => (pollingToken: string) => void;
+ startPollingByNetworkClientId: (
+ networkClientId: string,
+ options: any,
+ ) => Promise;
+ stopPollingByPollingToken: (pollingToken: string) => void;
+ networkClientId: string;
+ options?: any;
+};
+
+const usePolling = (usePollingOptions: UsePollingOptions) => {
+ const pollTokenRef = useRef(null);
+ const cleanupRef = useRef void)>(null);
+ let isMounted = false;
+ useEffect(() => {
+ isMounted = true;
+
+ const cleanup = () => {
+ if (pollTokenRef.current) {
+ usePollingOptions.stopPollingByPollingToken(pollTokenRef.current);
+ cleanupRef.current?.(pollTokenRef.current);
+ }
+ };
+ // Start polling when the component mounts
+ usePollingOptions
+ .startPollingByNetworkClientId(
+ usePollingOptions.networkClientId,
+ usePollingOptions.options,
+ )
+ .then((pollToken) => {
+ pollTokenRef.current = pollToken;
+ cleanupRef.current = usePollingOptions.callback?.(pollToken) || null;
+ if (!isMounted) {
+ cleanup();
+ }
+ });
+
+ // Return a cleanup function to stop polling when the component unmounts
+ return () => {
+ isMounted = false;
+ cleanup();
+ };
+ }, [usePollingOptions.networkClientId, usePollingOptions.options]);
+};
+
+export default usePolling;
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
index f32867639b11..41f31a856301 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js
@@ -37,19 +37,19 @@ import {
unconfirmedTransactionsListSelector,
unconfirmedTransactionsHashSelector,
use4ByteResolutionSelector,
+ getSelectedNetworkClientId,
} from '../../../selectors';
import {
- disconnectGasFeeEstimatePoller,
getContractMethodData,
- getGasFeeEstimatesAndStartPolling,
- addPollingTokenToAppState,
- removePollingTokenFromAppState,
setDefaultHomeActiveTabName,
+ gasFeeStartPollingByNetworkClientId,
+ gasFeeStopPollingByPollingToken,
} from '../../../store/actions';
import ConfirmSignatureRequest from '../confirm-signature-request';
///: BEGIN:ONLY_INCLUDE_IF(conf-redesign)
import Confirm from '../confirm/confirm';
///: END:ONLY_INCLUDE_IF
+import usePolling from '../../../hooks/usePolling';
import ConfirmTokenTransactionSwitch from './confirm-token-transaction-switch';
const ConfirmTransaction = () => {
@@ -57,14 +57,12 @@ const ConfirmTransaction = () => {
const history = useHistory();
const { id: paramsTransactionId } = useParams();
- const [isMounted, setIsMounted] = useState(false);
- const [pollingToken, setPollingToken] = useState();
-
const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage);
const sendTo = useSelector(getSendTo);
const unconfirmedTxsSorted = useSelector(unconfirmedTransactionsListSelector);
const unconfirmedTxs = useSelector(unconfirmedTransactionsHashSelector);
+ const networkClientId = useSelector(getSelectedNetworkClientId);
const totalUnapproved = unconfirmedTxsSorted.length || 0;
const getTransaction = useCallback(() => {
@@ -109,30 +107,13 @@ const ConfirmTransaction = () => {
const prevParamsTransactionId = usePrevious(paramsTransactionId);
const prevTransactionId = usePrevious(transactionId);
- const _beforeUnload = useCallback(() => {
- setIsMounted(false);
-
- if (pollingToken) {
- disconnectGasFeeEstimatePoller(pollingToken);
- removePollingTokenFromAppState(pollingToken);
- }
- }, [pollingToken]);
+ usePolling({
+ startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
+ stopPollingByPollingToken: gasFeeStopPollingByPollingToken,
+ networkClientId: transaction.networkClientId ?? networkClientId,
+ });
useEffect(() => {
- setIsMounted(true);
-
- getGasFeeEstimatesAndStartPolling().then((_pollingToken) => {
- if (isMounted) {
- setPollingToken(_pollingToken);
- addPollingTokenToAppState(_pollingToken);
- } else {
- disconnectGasFeeEstimatePoller(_pollingToken);
- removePollingTokenFromAppState(_pollingToken);
- }
- });
-
- window.addEventListener('beforeunload', _beforeUnload);
-
if (!totalUnapproved && !sendTo) {
history.replace(mostRecentOverviewPage);
} else {
@@ -148,10 +129,6 @@ const ConfirmTransaction = () => {
}
}
- return () => {
- _beforeUnload();
- window.removeEventListener('beforeunload', _beforeUnload);
- };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
index c374316f320a..69d6206aeb09 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js
@@ -135,6 +135,11 @@ jest.mock('../confirm-transaction-switch', () => {
});
describe('Confirmation Transaction Page', () => {
+ beforeEach(() => {
+ jest
+ .spyOn(Actions, 'gasFeeStartPollingByNetworkClientId')
+ .mockResolvedValue(null);
+ });
it('should display the Loading component when the transaction is invalid', () => {
const mockStore = configureMockStore(middleware)({
...mockState,
@@ -216,10 +221,9 @@ describe('Confirmation Transaction Page', () => {
describe('initialization', () => {
it('should poll for gas estimates', () => {
const mockStore = configureMockStore(middleware)(mockState);
- const gasEstimationPollingSpy = jest.spyOn(
- Actions,
- 'getGasFeeEstimatesAndStartPolling',
- );
+ const gasEstimationPollingSpy = jest
+ .spyOn(Actions, 'gasFeeStartPollingByNetworkClientId')
+ .mockResolvedValue(null);
renderWithProvider(, mockStore);
diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.transaction.test.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.transaction.test.js
index 5be82bcb7588..4c3f9f20dc99 100644
--- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.transaction.test.js
+++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.transaction.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-
+import * as Actions from '../../../store/actions';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import { setBackgroundConnection } from '../../../store/background-connection';
import mockState from '../../../../test/data/mock-state.json';
@@ -28,6 +28,9 @@ describe('Confirm Transaction', () => {
mockState.metamask.transactions,
)[0];
it('should render correct information for approve transaction with value', () => {
+ jest
+ .spyOn(Actions, 'gasFeeStartPollingByNetworkClientId')
+ .mockResolvedValue(null);
const store = configureMockStore(middleware)({
...mockState,
confirmTransaction: {
diff --git a/ui/store/actions.ts b/ui/store/actions.ts
index 8be2af71284d..53d3ce7e4dbd 100644
--- a/ui/store/actions.ts
+++ b/ui/store/actions.ts
@@ -4238,6 +4238,31 @@ export async function removePollingTokenFromAppState(pollingToken: string) {
]);
}
+/**
+ * Informs the GasFeeController that the UI requires gas fee polling
+ *
+ * @param networkClientId - unique identifier for the network client
+ * @returns polling token that can be used to stop polling
+ */
+export function gasFeeStartPollingByNetworkClientId(networkClientId: string) {
+ return submitRequestToBackground('gasFeeStartPollingByNetworkClientId', [
+ networkClientId,
+ ]);
+}
+
+/**
+ * Informs the GasFeeController that the UI no longer requires gas fee polling
+ * for the given network client.
+ * If all network clients unsubscribe, the controller stops polling.
+ *
+ * @param pollingToken - Poll token received from calling startPollingByNetworkClientId
+ */
+export function gasFeeStopPollingByPollingToken(pollingToken: string) {
+ return submitRequestToBackground('gasFeeStopPollingByPollingToken', [
+ pollingToken,
+ ]);
+}
+
export function getGasFeeTimeEstimate(
maxPriorityFeePerGas: string,
maxFeePerGas: string,
From 5706baa8a0835025aa4eca52e26af8161f9fd5ef Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 15 Feb 2024 17:05:07 -0500
Subject: [PATCH 02/74] Added fast stable stringify
---
package.json | 1 +
ui/hooks/usePolling.ts | 3 ++-
yarn.lock | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/package.json b/package.json
index eca6edbe72e9..feec542b8245 100644
--- a/package.json
+++ b/package.json
@@ -333,6 +333,7 @@
"ethereumjs-util": "^7.0.10",
"extension-port-stream": "^3.0.0",
"fast-json-patch": "^3.1.1",
+ "fast-json-stable-stringify": "^2.1.0",
"fuse.js": "^3.2.0",
"human-standard-token-abi": "^2.0.0",
"immer": "^9.0.6",
diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts
index 42a141547f84..1d15bbddac77 100644
--- a/ui/hooks/usePolling.ts
+++ b/ui/hooks/usePolling.ts
@@ -1,4 +1,5 @@
import { useEffect, useRef } from 'react';
+import stringify from 'fast-json-stable-stringify';
type UsePollingOptions = {
callback?: (pollingToken: string) => (pollingToken: string) => void;
@@ -43,7 +44,7 @@ const usePolling = (usePollingOptions: UsePollingOptions) => {
isMounted = false;
cleanup();
};
- }, [usePollingOptions.networkClientId, usePollingOptions.options]);
+ }, [usePollingOptions.networkClientId, stringify(usePollingOptions.options)]);
};
export default usePolling;
diff --git a/yarn.lock b/yarn.lock
index 609456cd3893..00c252452be7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -24268,6 +24268,7 @@ __metadata:
fancy-log: "npm:^1.3.3"
fast-glob: "npm:^3.2.2"
fast-json-patch: "npm:^3.1.1"
+ fast-json-stable-stringify: "npm:^2.1.0"
fs-extra: "npm:^8.1.0"
fuse.js: "npm:^3.2.0"
ganache: "npm:^7.9.2"
From a9a23037551b66e206e250f82fce6160e4cd33c5 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Fri, 16 Feb 2024 11:07:26 -0500
Subject: [PATCH 03/74] Removed fast stringify for normal json stringify to not
deal with ESM
---
ui/hooks/usePolling.ts | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts
index 1d15bbddac77..7698cc61e7fb 100644
--- a/ui/hooks/usePolling.ts
+++ b/ui/hooks/usePolling.ts
@@ -1,5 +1,4 @@
import { useEffect, useRef } from 'react';
-import stringify from 'fast-json-stable-stringify';
type UsePollingOptions = {
callback?: (pollingToken: string) => (pollingToken: string) => void;
@@ -44,7 +43,13 @@ const usePolling = (usePollingOptions: UsePollingOptions) => {
isMounted = false;
cleanup();
};
- }, [usePollingOptions.networkClientId, stringify(usePollingOptions.options)]);
+ }, [
+ usePollingOptions.networkClientId,
+ JSON.stringify(
+ usePollingOptions.options,
+ Object.keys(usePollingOptions.options).sort(),
+ ),
+ ]);
};
export default usePolling;
From 591c9342197d2cccc5ffa6519a68a5ab20782b54 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Fri, 16 Feb 2024 11:18:42 -0500
Subject: [PATCH 04/74] Removed fast-json-stable-stringify
---
package.json | 1 -
yarn.lock | 1 -
2 files changed, 2 deletions(-)
diff --git a/package.json b/package.json
index feec542b8245..eca6edbe72e9 100644
--- a/package.json
+++ b/package.json
@@ -333,7 +333,6 @@
"ethereumjs-util": "^7.0.10",
"extension-port-stream": "^3.0.0",
"fast-json-patch": "^3.1.1",
- "fast-json-stable-stringify": "^2.1.0",
"fuse.js": "^3.2.0",
"human-standard-token-abi": "^2.0.0",
"immer": "^9.0.6",
diff --git a/yarn.lock b/yarn.lock
index 00c252452be7..609456cd3893 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -24268,7 +24268,6 @@ __metadata:
fancy-log: "npm:^1.3.3"
fast-glob: "npm:^3.2.2"
fast-json-patch: "npm:^3.1.1"
- fast-json-stable-stringify: "npm:^2.1.0"
fs-extra: "npm:^8.1.0"
fuse.js: "npm:^3.2.0"
ganache: "npm:^7.9.2"
From d8bb41dda8590d23bf0bfc63eb045dd174d81d4d Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Fri, 16 Feb 2024 11:37:53 -0500
Subject: [PATCH 05/74] Fixed issue if usePollingOptions.options is not defined
---
ui/hooks/usePolling.ts | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/ui/hooks/usePolling.ts b/ui/hooks/usePolling.ts
index 7698cc61e7fb..ae64d3c73bb6 100644
--- a/ui/hooks/usePolling.ts
+++ b/ui/hooks/usePolling.ts
@@ -45,10 +45,11 @@ const usePolling = (usePollingOptions: UsePollingOptions) => {
};
}, [
usePollingOptions.networkClientId,
- JSON.stringify(
- usePollingOptions.options,
- Object.keys(usePollingOptions.options).sort(),
- ),
+ usePollingOptions.options &&
+ JSON.stringify(
+ usePollingOptions.options,
+ Object.keys(usePollingOptions.options).sort(),
+ ),
]);
};
From cf501b9d9aa2c4a83e771b41ba504fae55e08a3e Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 09:51:17 -0800
Subject: [PATCH 06/74] Replace useSafeGasEstimatePolling with usePolling
---
.../files-to-convert.json | 1 -
ui/hooks/useGasFeeEstimates.js | 13 +++--
ui/hooks/useSafeGasEstimatePolling.js | 47 -------------------
.../confirmations/hooks/useGasFeeInputs.js | 2 +-
.../hooks/useIncrementedGasFees.js | 2 +-
5 files changed, 12 insertions(+), 53 deletions(-)
delete mode 100644 ui/hooks/useSafeGasEstimatePolling.js
diff --git a/development/ts-migration-dashboard/files-to-convert.json b/development/ts-migration-dashboard/files-to-convert.json
index 0a11ad6fba86..be5e60a6a97f 100644
--- a/development/ts-migration-dashboard/files-to-convert.json
+++ b/development/ts-migration-dashboard/files-to-convert.json
@@ -1130,7 +1130,6 @@
"ui/hooks/useIncrementedGasFees.js",
"ui/hooks/useOriginMetadata.js",
"ui/hooks/usePrevious.js",
- "ui/hooks/useSafeGasEstimatePolling.js",
"ui/hooks/useSegmentContext.js",
"ui/hooks/useShouldAnimateGasEstimations.js",
"ui/hooks/useShouldShowSpeedUp.js",
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 1cd11ccc0727..bf40c832ba71 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -6,7 +6,8 @@ import {
getIsGasEstimatesLoading,
getIsNetworkBusy,
} from '../ducks/metamask/metamask';
-import { useSafeGasEstimatePolling } from './useSafeGasEstimatePolling';
+import usePolling from './usePolling';
+import { gasFeeStartPollingByNetworkClientId, gasFeeStopPollingByPollingToken } from '../store/actions';
/**
* @typedef {object} GasEstimates
@@ -27,12 +28,18 @@ import { useSafeGasEstimatePolling } from './useSafeGasEstimatePolling';
*
* @returns {GasEstimates} GasEstimates object
*/
-export function useGasFeeEstimates() {
+export function useGasFeeEstimates(networkClientId) {
const gasEstimateType = useSelector(getGasEstimateType);
const gasFeeEstimates = useSelector(getGasFeeEstimates, isEqual);
const isGasEstimatesLoading = useSelector(getIsGasEstimatesLoading);
const isNetworkBusy = useSelector(getIsNetworkBusy);
- useSafeGasEstimatePolling();
+ const selectedNetworkClientId = useSelector(getSelectedNetworkClientId);
+
+ usePolling({
+ startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
+ stopPollingByPollingToken: gasFeeStopPollingByPollingToken,
+ networkClientId: networkClientId ?? selectedNetworkClientId,
+ });
return {
gasFeeEstimates,
diff --git a/ui/hooks/useSafeGasEstimatePolling.js b/ui/hooks/useSafeGasEstimatePolling.js
deleted file mode 100644
index 156f805e6737..000000000000
--- a/ui/hooks/useSafeGasEstimatePolling.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { useEffect } from 'react';
-import {
- disconnectGasFeeEstimatePoller,
- getGasFeeEstimatesAndStartPolling,
- addPollingTokenToAppState,
- removePollingTokenFromAppState,
-} from '../store/actions';
-
-/**
- * Provides a reusable hook that can be used for safely updating the polling
- * data in the gas fee controller. It makes a request to get estimates and
- * begin polling, keeping track of the poll token for the lifetime of the hook.
- * It then disconnects polling upon unmount. If the hook is unmounted while waiting
- * for `getGasFeeEstimatesAndStartPolling` to resolve, the `active` flag ensures
- * that a call to disconnect happens after promise resolution.
- */
-export function useSafeGasEstimatePolling() {
- useEffect(() => {
- let active = true;
- let pollToken;
-
- const cleanup = () => {
- active = false;
- if (pollToken) {
- disconnectGasFeeEstimatePoller(pollToken);
- removePollingTokenFromAppState(pollToken);
- }
- };
-
- getGasFeeEstimatesAndStartPolling().then((newPollToken) => {
- if (active) {
- pollToken = newPollToken;
- addPollingTokenToAppState(pollToken);
- } else {
- disconnectGasFeeEstimatePoller(newPollToken);
- removePollingTokenFromAppState(pollToken);
- }
- });
-
- window.addEventListener('beforeunload', cleanup);
-
- return () => {
- cleanup();
- window.removeEventListener('beforeunload', cleanup);
- };
- }, []);
-}
diff --git a/ui/pages/confirmations/hooks/useGasFeeInputs.js b/ui/pages/confirmations/hooks/useGasFeeInputs.js
index 90913f8f86c3..4bbf1ee903c7 100644
--- a/ui/pages/confirmations/hooks/useGasFeeInputs.js
+++ b/ui/pages/confirmations/hooks/useGasFeeInputs.js
@@ -130,7 +130,7 @@ export function useGasFeeInputs(
gasFeeEstimates,
isGasEstimatesLoading,
isNetworkBusy,
- } = useGasFeeEstimates();
+ } = useGasFeeEstimates(transaction.networkClientId);
const userPrefersAdvancedGas = useSelector(getAdvancedInlineGasShown);
diff --git a/ui/pages/confirmations/hooks/useIncrementedGasFees.js b/ui/pages/confirmations/hooks/useIncrementedGasFees.js
index 319312e1b421..b4156e70ca16 100644
--- a/ui/pages/confirmations/hooks/useIncrementedGasFees.js
+++ b/ui/pages/confirmations/hooks/useIncrementedGasFees.js
@@ -39,7 +39,7 @@ function getHighestIncrementedFee(originalFee, currentEstimate) {
* ).CustomGasSettings} Gas settings for cancellations/speed ups
*/
export function useIncrementedGasFees(transaction) {
- const { gasFeeEstimates = {} } = useGasFeeEstimates();
+ const { gasFeeEstimates = {} } = useGasFeeEstimates(transaction.networkClientId);
// We memoize this value so that it can be relied upon in other hooks.
const customGasSettings = useMemo(() => {
From 57a0469415788af035f50e227791569795ef6154 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 10:20:09 -0800
Subject: [PATCH 07/74] update specs
---
ui/hooks/useGasFeeEstimates.js | 1 +
ui/hooks/useGasFeeEstimates.test.js | 37 ++++++++++++++++++++---------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index bf40c832ba71..0dd94b448e01 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -8,6 +8,7 @@ import {
} from '../ducks/metamask/metamask';
import usePolling from './usePolling';
import { gasFeeStartPollingByNetworkClientId, gasFeeStopPollingByPollingToken } from '../store/actions';
+import { getSelectedNetworkClientId } from '../selectors';
/**
* @typedef {object} GasEstimates
diff --git a/ui/hooks/useGasFeeEstimates.test.js b/ui/hooks/useGasFeeEstimates.test.js
index a76633c112a0..21530ab102da 100644
--- a/ui/hooks/useGasFeeEstimates.test.js
+++ b/ui/hooks/useGasFeeEstimates.test.js
@@ -7,19 +7,17 @@ import {
getGasFeeEstimates,
getIsGasEstimatesLoading,
} from '../ducks/metamask/metamask';
-import { checkNetworkAndAccountSupports1559 } from '../selectors';
+import { checkNetworkAndAccountSupports1559, getSelectedNetworkClientId } from '../selectors';
import {
- disconnectGasFeeEstimatePoller,
- getGasFeeEstimatesAndStartPolling,
+ gasFeeStopPollingByPollingToken,
+ gasFeeStartPollingByNetworkClientId,
} from '../store/actions';
import { useGasFeeEstimates } from './useGasFeeEstimates';
jest.mock('../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest.fn(),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ gasFeeStartPollingByNetworkClientId: jest.fn(),
}));
jest.mock('react-redux', () => {
@@ -51,6 +49,9 @@ const generateUseSelectorRouter =
DEFAULT_OPTS.checkNetworkAndAccountSupports1559
);
}
+ if (selector === getSelectedNetworkClientId) {
+ return 'selectedNetworkClientId';
+ }
if (selector === getGasEstimateType) {
return opts.gasEstimateType ?? DEFAULT_OPTS.gasEstimateType;
}
@@ -68,12 +69,12 @@ describe('useGasFeeEstimates', () => {
beforeEach(() => {
jest.clearAllMocks();
tokens = [];
- getGasFeeEstimatesAndStartPolling.mockImplementation(() => {
+ gasFeeStartPollingByNetworkClientId.mockImplementation(() => {
const token = createRandomId();
tokens.push(token);
return Promise.resolve(token);
});
- disconnectGasFeeEstimatePoller.mockImplementation((token) => {
+ gasFeeStopPollingByPollingToken.mockImplementation((token) => {
tokens = tokens.filter((tkn) => tkn !== token);
});
});
@@ -90,11 +91,25 @@ describe('useGasFeeEstimates', () => {
expect(tokens).toHaveLength(1);
const expectedToken = tokens[0];
await cleanup();
- expect(getGasFeeEstimatesAndStartPolling).toHaveBeenCalledTimes(1);
- expect(disconnectGasFeeEstimatePoller).toHaveBeenCalledWith(expectedToken);
+ expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
+ expect(gasFeeStopPollingByPollingToken).toHaveBeenCalledWith(expectedToken);
expect(tokens).toHaveLength(0);
});
+ it('polls the selected networkClientId by default', () => {
+ useSelector.mockImplementation(generateUseSelectorRouter());
+ renderHook(() => useGasFeeEstimates());
+ expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
+ expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledWith('selectedNetworkClientId', undefined)
+ });
+
+ it('polls the passed in networkClientId when provided', () => {
+ useSelector.mockImplementation(generateUseSelectorRouter());
+ renderHook(() => useGasFeeEstimates('networkClientId1'));
+ expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
+ expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledWith('networkClientId1', undefined)
+ });
+
it('works with LEGACY gas prices', () => {
useSelector.mockImplementation(
generateUseSelectorRouter({
From 3d484525bbedeaadc23ac407f8f3140943756741 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 13:47:01 -0800
Subject: [PATCH 08/74] update useGasFeeEstimates to use usePolling hook
---
app/scripts/metamask-controller.js | 4 +
ui/ducks/metamask/metamask.js | 51 ++++-
ui/hooks/useGasFeeEstimates.js | 53 +++--
ui/hooks/useGasFeeEstimates.test.js | 183 +++++++++++-------
.../hooks/useIncrementedGasFees.js | 4 +-
ui/selectors/selectors.js | 5 +-
ui/store/actions.ts | 21 +-
7 files changed, 227 insertions(+), 94 deletions(-)
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index eefb4440d6cf..2244b84bbe51 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -2823,6 +2823,10 @@ export default class MetamaskController extends EventEmitter {
this.networkController.getEIP1559Compatibility.bind(
this.networkController,
),
+ getNetworkConfigurationByNetworkClientId:
+ this.networkController.getNetworkConfigurationByNetworkClientId.bind(
+ this.networkController,
+ ),
// PreferencesController
setSelectedAddress: (address) => {
const account = this.accountsController.getAccountByAddress(address);
diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js
index ed4dd3bb9947..9b35a47c310b 100644
--- a/ui/ducks/metamask/metamask.js
+++ b/ui/ducks/metamask/metamask.js
@@ -331,12 +331,14 @@ export function isNotEIP1559Network(state) {
* Function returns true if network details are fetched and it is found to support EIP-1559
*
* @param state
+ * @param networkClientId
*/
-export function isEIP1559Network(state) {
+export function isEIP1559Network(state, networkClientId) {
const selectedNetworkClientId = getSelectedNetworkClientId(state);
return (
- state.metamask.networksMetadata?.[selectedNetworkClientId].EIPS[1559] ===
- true
+ state.metamask.networksMetadata?.[
+ networkClientId ?? selectedNetworkClientId
+ ].EIPS[1559] === true
);
}
@@ -352,6 +354,19 @@ export function getEstimatedGasFeeTimeBounds(state) {
return state.metamask.estimatedGasFeeTimeBounds;
}
+export function getGasEstimateTypeByChainId(state, chainId) {
+ return state.metamask.gasFeeEstimatesByChainId[chainId]?.gasEstimateType;
+}
+
+export function getGasFeeEstimatesByChainId(state, chainId) {
+ return state.metamask.gasFeeEstimatesByChainId[chainId]?.gasFeeEstimates;
+}
+
+export function getEstimatedGasFeeTimeBoundsByChainId(state, chainId) {
+ return state.metamask.gasFeeEstimatesByChainId[chainId]
+ ?.estimatedGasFeeTimeBounds;
+}
+
export function getIsGasEstimatesLoading(state) {
const networkAndAccountSupports1559 =
checkNetworkAndAccountSupports1559(state);
@@ -372,11 +387,41 @@ export function getIsGasEstimatesLoading(state) {
return isGasEstimatesLoading;
}
+export function getIsGasEstimatesLoadingByChainId(
+ state,
+ { chainId, networkClientId },
+) {
+ const networkAndAccountSupports1559 = checkNetworkAndAccountSupports1559(
+ state,
+ networkClientId,
+ );
+ const gasEstimateType = getGasEstimateTypeByChainId(state, chainId);
+
+ // We consider the gas estimate to be loading if the gasEstimateType is
+ // 'NONE' or if the current gasEstimateType cannot be supported by the current
+ // network
+ const isEIP1559TolerableEstimateType =
+ gasEstimateType === GasEstimateTypes.feeMarket ||
+ gasEstimateType === GasEstimateTypes.ethGasPrice;
+ const isGasEstimatesLoading =
+ gasEstimateType === GasEstimateTypes.none ||
+ (networkAndAccountSupports1559 && !isEIP1559TolerableEstimateType) ||
+ (!networkAndAccountSupports1559 &&
+ gasEstimateType === GasEstimateTypes.feeMarket);
+
+ return isGasEstimatesLoading;
+}
+
export function getIsNetworkBusy(state) {
const gasFeeEstimates = getGasFeeEstimates(state);
return gasFeeEstimates?.networkCongestion >= NetworkCongestionThresholds.busy;
}
+export function getIsNetworkBusyByChainId(state, chainId) {
+ const gasFeeEstimates = getGasFeeEstimatesByChainId(state, chainId);
+ return gasFeeEstimates?.networkCongestion >= NetworkCongestionThresholds.busy;
+}
+
export function getCompletedOnboarding(state) {
return state.metamask.completedOnboarding;
}
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 0dd94b448e01..3f97c8e54529 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -1,14 +1,19 @@
import isEqual from 'lodash/isEqual';
import { useSelector } from 'react-redux';
+import { useEffect, useState } from 'react';
import {
- getGasEstimateType,
- getGasFeeEstimates,
- getIsGasEstimatesLoading,
- getIsNetworkBusy,
+ getGasEstimateTypeByChainId,
+ getGasFeeEstimatesByChainId,
+ getIsGasEstimatesLoadingByChainId,
+ getIsNetworkBusyByChainId,
} from '../ducks/metamask/metamask';
-import usePolling from './usePolling';
-import { gasFeeStartPollingByNetworkClientId, gasFeeStopPollingByPollingToken } from '../store/actions';
+import {
+ gasFeeStartPollingByNetworkClientId,
+ gasFeeStopPollingByPollingToken,
+ getNetworkConfigurationByNetworkClientId,
+} from '../store/actions';
import { getSelectedNetworkClientId } from '../selectors';
+import usePolling from './usePolling';
/**
* @typedef {object} GasEstimates
@@ -27,19 +32,43 @@ import { getSelectedNetworkClientId } from '../selectors';
* GasFeeController that it is done requiring new gas estimates. Also checks
* the returned gas estimate for validity on the current network.
*
+ * @param _networkClientId
* @returns {GasEstimates} GasEstimates object
*/
-export function useGasFeeEstimates(networkClientId) {
- const gasEstimateType = useSelector(getGasEstimateType);
- const gasFeeEstimates = useSelector(getGasFeeEstimates, isEqual);
- const isGasEstimatesLoading = useSelector(getIsGasEstimatesLoading);
- const isNetworkBusy = useSelector(getIsNetworkBusy);
+export function useGasFeeEstimates(_networkClientId) {
const selectedNetworkClientId = useSelector(getSelectedNetworkClientId);
+ const networkClientId = _networkClientId ?? selectedNetworkClientId;
+
+ const [chainId, setChainId] = useState('');
+
+ const gasEstimateType = useSelector((state) =>
+ getGasEstimateTypeByChainId(state, chainId),
+ );
+ const gasFeeEstimates = useSelector(
+ (state) => getGasFeeEstimatesByChainId(state, chainId),
+ isEqual,
+ );
+ const isGasEstimatesLoading = useSelector((state) =>
+ getIsGasEstimatesLoadingByChainId(state, { chainId, networkClientId }),
+ );
+ const isNetworkBusy = useSelector((state) =>
+ getIsNetworkBusyByChainId(state, chainId),
+ );
+
+ useEffect(() => {
+ getNetworkConfigurationByNetworkClientId(networkClientId).then(
+ (networkConfig) => {
+ if (networkConfig) {
+ setChainId(networkConfig.chainId);
+ }
+ },
+ );
+ }, [networkClientId]);
usePolling({
startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
stopPollingByPollingToken: gasFeeStopPollingByPollingToken,
- networkClientId: networkClientId ?? selectedNetworkClientId,
+ networkClientId,
});
return {
diff --git a/ui/hooks/useGasFeeEstimates.test.js b/ui/hooks/useGasFeeEstimates.test.js
index 21530ab102da..0187ac793bbe 100644
--- a/ui/hooks/useGasFeeEstimates.test.js
+++ b/ui/hooks/useGasFeeEstimates.test.js
@@ -1,23 +1,49 @@
-import { cleanup, renderHook } from '@testing-library/react-hooks';
+import { renderHook, act } from '@testing-library/react-hooks';
import { useSelector } from 'react-redux';
import { GasEstimateTypes } from '../../shared/constants/gas';
-import createRandomId from '../../shared/modules/random-id';
import {
- getGasEstimateType,
- getGasFeeEstimates,
- getIsGasEstimatesLoading,
+ getGasEstimateTypeByChainId,
+ getGasFeeEstimatesByChainId,
+ getIsGasEstimatesLoadingByChainId,
+ getIsNetworkBusyByChainId,
} from '../ducks/metamask/metamask';
-import { checkNetworkAndAccountSupports1559, getSelectedNetworkClientId } from '../selectors';
import {
- gasFeeStopPollingByPollingToken,
gasFeeStartPollingByNetworkClientId,
+ gasFeeStopPollingByPollingToken,
+ getNetworkConfigurationByNetworkClientId,
} from '../store/actions';
import { useGasFeeEstimates } from './useGasFeeEstimates';
+import usePolling from './usePolling';
+
+jest.mock('./usePolling', () => jest.fn());
jest.mock('../store/actions', () => ({
- gasFeeStopPollingByPollingToken: jest.fn(),
- gasFeeStartPollingByNetworkClientId: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn(),
+}));
+
+jest.mock('../ducks/metamask/metamask', () => ({
+ getGasEstimateTypeByChainId: jest
+ .fn()
+ .mockReturnValue('getGasEstimateTypeByChainId'),
+ getGasFeeEstimatesByChainId: jest
+ .fn()
+ .mockReturnValue('getGasFeeEstimatesByChainId'),
+ getIsGasEstimatesLoadingByChainId: jest
+ .fn()
+ .mockReturnValue('getIsGasEstimatesLoadingByChainId'),
+ getIsNetworkBusyByChainId: jest
+ .fn()
+ .mockReturnValue('getIsNetworkBusyByChainId'),
+}));
+
+jest.mock('../selectors', () => ({
+ checkNetworkAndAccountSupports1559: jest
+ .fn()
+ .mockReturnValue('checkNetworkAndAccountSupports1559'),
+ getSelectedNetworkClientId: jest
+ .fn()
+ .mockReturnValue('getSelectedNetworkClientId'),
}));
jest.mock('react-redux', () => {
@@ -40,93 +66,105 @@ const DEFAULT_OPTS = {
isGasEstimatesLoading: true,
};
+const MOCK_STATE = {};
+
const generateUseSelectorRouter =
(opts = DEFAULT_OPTS) =>
(selector) => {
- if (selector === checkNetworkAndAccountSupports1559) {
+ const selectorId = selector(MOCK_STATE);
+ if (selectorId === 'checkNetworkAndAccountSupports1559') {
return (
opts.checkNetworkAndAccountSupports1559 ??
DEFAULT_OPTS.checkNetworkAndAccountSupports1559
);
}
- if (selector === getSelectedNetworkClientId) {
+ if (selectorId === 'getSelectedNetworkClientId') {
return 'selectedNetworkClientId';
}
- if (selector === getGasEstimateType) {
+ if (selectorId === 'getGasEstimateTypeByChainId') {
return opts.gasEstimateType ?? DEFAULT_OPTS.gasEstimateType;
}
- if (selector === getGasFeeEstimates) {
+ if (selectorId === 'getGasFeeEstimatesByChainId') {
return opts.gasFeeEstimates ?? DEFAULT_OPTS.gasFeeEstimates;
}
- if (selector === getIsGasEstimatesLoading) {
+ if (selectorId === 'getIsGasEstimatesLoadingByChainId') {
return opts.isGasEstimatesLoading ?? DEFAULT_OPTS.isGasEstimatesLoading;
}
return undefined;
};
describe('useGasFeeEstimates', () => {
- let tokens = [];
beforeEach(() => {
jest.clearAllMocks();
- tokens = [];
- gasFeeStartPollingByNetworkClientId.mockImplementation(() => {
- const token = createRandomId();
- tokens.push(token);
- return Promise.resolve(token);
- });
- gasFeeStopPollingByPollingToken.mockImplementation((token) => {
- tokens = tokens.filter((tkn) => tkn !== token);
- });
- });
+ getNetworkConfigurationByNetworkClientId.mockImplementation(
+ (networkClientId) => {
+ if (!networkClientId) {
+ return Promise.resolve(undefined);
+ }
- it('registers with the controller', () => {
- useSelector.mockImplementation(generateUseSelectorRouter());
- renderHook(() => useGasFeeEstimates());
- expect(tokens).toHaveLength(1);
+ return Promise.resolve({
+ chainId: '0xa',
+ });
+ },
+ );
});
- it('clears token with the controller on unmount', async () => {
+ it('polls the selected networkClientId by default', async () => {
useSelector.mockImplementation(generateUseSelectorRouter());
- renderHook(() => useGasFeeEstimates());
- expect(tokens).toHaveLength(1);
- const expectedToken = tokens[0];
- await cleanup();
- expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
- expect(gasFeeStopPollingByPollingToken).toHaveBeenCalledWith(expectedToken);
- expect(tokens).toHaveLength(0);
+ await act(async () => {
+ renderHook(() => useGasFeeEstimates());
+ });
+ expect(usePolling).toHaveBeenCalledWith({
+ startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
+ stopPollingByPollingToken: gasFeeStopPollingByPollingToken,
+ networkClientId: 'selectedNetworkClientId',
+ });
});
- it('polls the selected networkClientId by default', () => {
+ it('polls the passed in networkClientId when provided', async () => {
useSelector.mockImplementation(generateUseSelectorRouter());
- renderHook(() => useGasFeeEstimates());
- expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
- expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledWith('selectedNetworkClientId', undefined)
+ await act(async () => {
+ renderHook(() => useGasFeeEstimates('networkClientId1'));
+ });
+ expect(usePolling).toHaveBeenCalledWith({
+ startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
+ stopPollingByPollingToken: gasFeeStopPollingByPollingToken,
+ networkClientId: 'networkClientId1',
+ });
});
- it('polls the passed in networkClientId when provided', () => {
+ it('reads state with the right chainId and networkClientId', async () => {
useSelector.mockImplementation(generateUseSelectorRouter());
- renderHook(() => useGasFeeEstimates('networkClientId1'));
- expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledTimes(1);
- expect(gasFeeStartPollingByNetworkClientId).toHaveBeenCalledWith('networkClientId1', undefined)
+
+ await act(async () =>
+ renderHook(() => useGasFeeEstimates('networkClientId1')),
+ );
+ expect(getGasEstimateTypeByChainId).toHaveBeenCalledWith(MOCK_STATE, '0xa');
+ expect(getGasFeeEstimatesByChainId).toHaveBeenCalledWith(MOCK_STATE, '0xa');
+ expect(getIsGasEstimatesLoadingByChainId).toHaveBeenCalledWith(MOCK_STATE, {
+ chainId: '0xa',
+ networkClientId: 'networkClientId1',
+ });
+ expect(getIsNetworkBusyByChainId).toHaveBeenCalledWith(MOCK_STATE, '0xa');
});
- it('works with LEGACY gas prices', () => {
+ it('works with LEGACY gas prices', async () => {
useSelector.mockImplementation(
generateUseSelectorRouter({
isGasEstimatesLoading: false,
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates: DEFAULT_OPTS.gasFeeEstimates,
gasEstimateType: GasEstimateTypes.legacy,
isGasEstimatesLoading: false,
});
});
- it('works with ETH_GASPRICE gas prices', () => {
+ it('works with ETH_GASPRICE gas prices', async () => {
const gasFeeEstimates = { gasPrice: '10' };
useSelector.mockImplementation(
generateUseSelectorRouter({
@@ -136,17 +174,16 @@ describe('useGasFeeEstimates', () => {
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates,
gasEstimateType: GasEstimateTypes.ethGasPrice,
isGasEstimatesLoading: false,
});
});
- it('works with FEE_MARKET gas prices', () => {
+ it('works with FEE_MARKET gas prices', async () => {
const gasFeeEstimates = {
low: {
minWaitTimeEstimate: 180000,
@@ -177,17 +214,16 @@ describe('useGasFeeEstimates', () => {
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates,
gasEstimateType: GasEstimateTypes.feeMarket,
isGasEstimatesLoading: false,
});
});
- it('indicates that gas estimates are loading when gasEstimateType is NONE', () => {
+ it('indicates that gas estimates are loading when gasEstimateType is NONE', async () => {
useSelector.mockImplementation(
generateUseSelectorRouter({
gasEstimateType: GasEstimateTypes.none,
@@ -195,17 +231,16 @@ describe('useGasFeeEstimates', () => {
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates: {},
gasEstimateType: GasEstimateTypes.none,
isGasEstimatesLoading: true,
});
});
- it('indicates that gas estimates are loading when gasEstimateType is not FEE_MARKET or ETH_GASPRICE, but network supports EIP-1559', () => {
+ it('indicates that gas estimates are loading when gasEstimateType is not FEE_MARKET or ETH_GASPRICE, but network supports EIP-1559', async () => {
useSelector.mockImplementation(
generateUseSelectorRouter({
checkNetworkAndAccountSupports1559: true,
@@ -216,17 +251,16 @@ describe('useGasFeeEstimates', () => {
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates: { gasPrice: '10' },
gasEstimateType: GasEstimateTypes.legacy,
isGasEstimatesLoading: true,
});
});
- it('indicates that gas estimates are loading when gasEstimateType is FEE_MARKET but network does not support EIP-1559', () => {
+ it('indicates that gas estimates are loading when gasEstimateType is FEE_MARKET but network does not support EIP-1559', async () => {
const gasFeeEstimates = {
low: {
minWaitTimeEstimate: 180000,
@@ -256,10 +290,9 @@ describe('useGasFeeEstimates', () => {
}),
);
- const {
- result: { current },
- } = renderHook(() => useGasFeeEstimates());
- expect(current).toMatchObject({
+ let hook;
+ await act(async () => (hook = renderHook(() => useGasFeeEstimates())));
+ expect(hook.result.current).toMatchObject({
gasFeeEstimates,
gasEstimateType: GasEstimateTypes.feeMarket,
isGasEstimatesLoading: true,
diff --git a/ui/pages/confirmations/hooks/useIncrementedGasFees.js b/ui/pages/confirmations/hooks/useIncrementedGasFees.js
index b4156e70ca16..68556c216f53 100644
--- a/ui/pages/confirmations/hooks/useIncrementedGasFees.js
+++ b/ui/pages/confirmations/hooks/useIncrementedGasFees.js
@@ -39,7 +39,9 @@ function getHighestIncrementedFee(originalFee, currentEstimate) {
* ).CustomGasSettings} Gas settings for cancellations/speed ups
*/
export function useIncrementedGasFees(transaction) {
- const { gasFeeEstimates = {} } = useGasFeeEstimates(transaction.networkClientId);
+ const { gasFeeEstimates = {} } = useGasFeeEstimates(
+ transaction.networkClientId,
+ );
// We memoize this value so that it can be relied upon in other hooks.
const customGasSettings = useMemo(() => {
diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js
index 50434c17d9e2..d9f24ee4ba8b 100644
--- a/ui/selectors/selectors.js
+++ b/ui/selectors/selectors.js
@@ -182,9 +182,10 @@ export function getCurrentKeyring(state) {
* both of them support EIP-1559.
*
* @param state
+ * @param networkClientId
*/
-export function checkNetworkAndAccountSupports1559(state) {
- const networkSupports1559 = isEIP1559Network(state);
+export function checkNetworkAndAccountSupports1559(state, networkClientId) {
+ const networkSupports1559 = isEIP1559Network(state, networkClientId);
return networkSupports1559;
}
diff --git a/ui/store/actions.ts b/ui/store/actions.ts
index 53d3ce7e4dbd..62c4053d3694 100644
--- a/ui/store/actions.ts
+++ b/ui/store/actions.ts
@@ -31,7 +31,10 @@ import {
TransactionParams,
TransactionType,
} from '@metamask/transaction-controller';
-import { NetworkClientId } from '@metamask/network-controller';
+import {
+ NetworkClientId,
+ NetworkConfiguration,
+} from '@metamask/network-controller';
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
import switchDirection from '../../shared/lib/switch-direction';
import {
@@ -4766,6 +4769,22 @@ export async function getCurrentNetworkEIP1559Compatibility(): Promise<
return networkEIP1559Compatibility;
}
+export async function getNetworkConfigurationByNetworkClientId(
+ networkClientId: NetworkClientId,
+): Promise {
+ let networkConfiguration;
+ try {
+ networkConfiguration =
+ await submitRequestToBackground(
+ 'getNetworkConfigurationByNetworkClientId',
+ [networkClientId],
+ );
+ } catch (error) {
+ console.error(error);
+ }
+ return networkConfiguration;
+}
+
export function updateProposedNames(
request: UpdateProposedNamesRequest,
): ThunkAction<
From cabd6dbf4390a9b536911dd151b497bb215f2578 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 13:53:17 -0800
Subject: [PATCH 09/74] fix undefined dereference estimatedBaseFee
---
ui/pages/confirmations/hooks/useGasEstimates.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/hooks/useGasEstimates.js b/ui/pages/confirmations/hooks/useGasEstimates.js
index a277bdff4d5d..769d1175fb13 100644
--- a/ui/pages/confirmations/hooks/useGasEstimates.js
+++ b/ui/pages/confirmations/hooks/useGasEstimates.js
@@ -76,7 +76,7 @@ export function useGasEstimates({
maxPriorityFeePerGas: decGWEIToHexWEI(
maxPriorityFeePerGas || maxFeePerGas || gasPrice || '0',
),
- baseFeePerGas: decGWEIToHexWEI(gasFeeEstimates.estimatedBaseFee ?? '0'),
+ baseFeePerGas: decGWEIToHexWEI(gasFeeEstimates?.estimatedBaseFee ?? '0'),
};
} else {
gasSettings = {
From 3ec134edf8d3e4a8d57aecad33748be236a4f010 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 15:41:05 -0800
Subject: [PATCH 10/74] Fix base-fee-input
---
.tool-versions | 1 +
test/data/mock-state.json | 32 +++++++
.../base-fee-input/base-fee-input.js | 25 ++---
.../base-fee-input/base-fee-input.test.js | 91 +++++++++++--------
.../confirmations/hooks/useGasEstimates.js | 5 +-
5 files changed, 103 insertions(+), 51 deletions(-)
create mode 100644 .tool-versions
diff --git a/.tool-versions b/.tool-versions
new file mode 100644
index 000000000000..38b76b57c456
--- /dev/null
+++ b/.tool-versions
@@ -0,0 +1 @@
+nodejs 20.8.1
diff --git a/test/data/mock-state.json b/test/data/mock-state.json
index 06ab82c99d9f..32a4fe3ad582 100644
--- a/test/data/mock-state.json
+++ b/test/data/mock-state.json
@@ -43,6 +43,38 @@
"participateInMetaMetrics": false,
"gasEstimateType": "fee-market",
"showBetaHeader": false,
+ "gasFeeEstimatesByChainId": {
+ "0x5": {
+ "gasEstimateType": "fee-market",
+ "gasFeeEstimates": {
+ "low": {
+ "minWaitTimeEstimate": 180000,
+ "maxWaitTimeEstimate": 300000,
+ "suggestedMaxPriorityFeePerGas": "3",
+ "suggestedMaxFeePerGas": "53"
+ },
+ "medium": {
+ "minWaitTimeEstimate": 15000,
+ "maxWaitTimeEstimate": 60000,
+ "suggestedMaxPriorityFeePerGas": "7",
+ "suggestedMaxFeePerGas": "70"
+ },
+ "high": {
+ "minWaitTimeEstimate": 0,
+ "maxWaitTimeEstimate": 15000,
+ "suggestedMaxPriorityFeePerGas": "10",
+ "suggestedMaxFeePerGas": "100"
+ },
+ "estimatedBaseFee": "50",
+ "historicalBaseFeeRange": ["28.533098435", "70.351148354"],
+ "baseFeeTrend": "up",
+ "latestPriorityFeeRange": ["1", "40"],
+ "historicalPriorityFeeRange": ["0.1458417", "700.156384646"],
+ "priorityFeeTrend": "down",
+ "networkCongestion": 0.90625
+ }
+ }
+ },
"gasFeeEstimates": {
"low": {
"minWaitTimeEstimate": 180000,
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js
index 3fc739b0cd1b..30a4e06b606b 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js
@@ -59,23 +59,24 @@ const BaseFeeInput = () => {
} = useAdvancedGasFeePopoverContext();
const { estimatedBaseFee, historicalBaseFeeRange, baseFeeTrend } =
- gasFeeEstimates;
+ gasFeeEstimates ?? {};
+
const [baseFeeError, setBaseFeeError] = useState();
const { currency, numberOfDecimals } = useUserPreferencedCurrency(PRIMARY);
const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues);
- const [baseFee, setBaseFee] = useState(() => {
- if (
- estimateUsed !== PriorityLevels.custom &&
- advancedGasFeeValues?.maxBaseFee &&
- editGasMode !== EditGasModes.swaps
- ) {
- return advancedGasFeeValues.maxBaseFee;
- }
-
- return maxFeePerGas;
- });
+ const defaultBaseFee =
+ estimateUsed !== PriorityLevels.custom &&
+ advancedGasFeeValues?.maxBaseFee &&
+ editGasMode !== EditGasModes.swaps
+ ? advancedGasFeeValues.maxBaseFee
+ : maxFeePerGas;
+
+ const [baseFee, setBaseFee] = useState(defaultBaseFee);
+ useEffect(() => {
+ setBaseFee(defaultBaseFee);
+ }, [defaultBaseFee, setBaseFee]);
const [baseFeeInPrimaryCurrency] = useCurrencyDisplay(
decGWEIToHexWEI(baseFee * gasLimit),
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
index e89cbdf54bb4..ab5fa150579f 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
@@ -1,6 +1,7 @@
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
+import { act } from 'react-dom/test-utils';
import {
EditGasModes,
GasEstimateTypes,
@@ -16,15 +17,16 @@ import AdvancedGasFeeGasLimit from '../../advanced-gas-fee-gas-limit';
import BaseFeeInput from './base-fee-input';
jest.mock('../../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
}));
-const render = (txProps, contextProps) => {
+const render = async (txProps, contextProps) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -34,40 +36,55 @@ const render = (txProps, contextProps) => {
balance: '0x1F4',
},
},
- advancedGasFee: { maxBaseFee: 100 },
+ advancedGasFee: { '0x5': { maxBaseFee: 100 } },
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
-
-
-
-
-
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+
+
+
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('BaseFeeInput', () => {
- it('should renders advancedGasFee.baseFee value if current estimate used is not custom', () => {
- render({
+ it('should renders advancedGasFee.baseFee value if current estimate used is not custom', async () => {
+ await render({
userFeeLevel: 'high',
});
expect(document.getElementsByTagName('input')[0]).toHaveValue(100);
});
- it('should not use advancedGasFee.baseFee value for swaps', () => {
- render(
+ it('should not use advancedGasFee.baseFee value for swaps', async () => {
+ await render(
{
userFeeLevel: 'high',
},
@@ -82,8 +99,8 @@ describe('BaseFeeInput', () => {
);
});
- it('should renders baseFee values from transaction if current estimate used is custom', () => {
- render({
+ it('should renders baseFee values from transaction if current estimate used is custom', async () => {
+ await render({
txParams: {
maxFeePerGas: '0x2E90EDD000',
},
@@ -91,8 +108,8 @@ describe('BaseFeeInput', () => {
expect(document.getElementsByTagName('input')[0]).toHaveValue(200);
});
- it('should show current value of estimatedBaseFee in users primary currency in right side of input box', () => {
- render({
+ it('should show current value of estimatedBaseFee in users primary currency in right side of input box', async () => {
+ await render({
txParams: {
gas: '0x5208',
maxFeePerGas: '0x2E90EDD000',
@@ -101,18 +118,18 @@ describe('BaseFeeInput', () => {
expect(screen.queryByText('≈ 0.0042 ETH')).toBeInTheDocument();
});
- it('should show current value of estimatedBaseFee in subtext', () => {
- render();
+ it('should show current value of estimatedBaseFee in subtext', async () => {
+ await render();
expect(screen.queryByText('50 GWEI')).toBeInTheDocument();
});
- it('should show 12hr range value in subtext', () => {
- render();
+ it('should show 12hr range value in subtext', async () => {
+ await render();
expect(screen.queryByText('50 - 100 GWEI')).toBeInTheDocument();
});
- it('should show error if base fee is less than suggested low value', () => {
- render({
+ it('should show error if base fee is less than suggested low value', async () => {
+ await render({
txParams: {
maxFeePerGas: '0x174876E800',
},
@@ -128,8 +145,8 @@ describe('BaseFeeInput', () => {
});
});
- it('should show error if base if is more than suggested high value', () => {
- render({
+ it('should show error if base if is more than suggested high value', async () => {
+ await render({
txParams: {
maxFeePerGas: '0x174876E800',
},
diff --git a/ui/pages/confirmations/hooks/useGasEstimates.js b/ui/pages/confirmations/hooks/useGasEstimates.js
index 769d1175fb13..083c084689a6 100644
--- a/ui/pages/confirmations/hooks/useGasEstimates.js
+++ b/ui/pages/confirmations/hooks/useGasEstimates.js
@@ -53,8 +53,9 @@ export function useGasEstimates({
transaction,
}) {
const supportsEIP1559 =
- useSelector(checkNetworkAndAccountSupports1559) &&
- !isLegacyTransaction(transaction?.txParams);
+ useSelector((state) =>
+ checkNetworkAndAccountSupports1559(state, transaction?.networkClientId),
+ ) && !isLegacyTransaction(transaction?.txParams);
const {
currency: primaryCurrency,
From 9a641c93cfcb2fb0cab51297b00546b41ad0865b Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 15:54:23 -0800
Subject: [PATCH 11/74] jsdoc
---
ui/ducks/metamask/metamask.js | 2 +-
ui/hooks/useGasFeeEstimates.js | 2 +-
ui/selectors/selectors.js | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js
index 9b35a47c310b..71924dbdd7bc 100644
--- a/ui/ducks/metamask/metamask.js
+++ b/ui/ducks/metamask/metamask.js
@@ -331,7 +331,7 @@ export function isNotEIP1559Network(state) {
* Function returns true if network details are fetched and it is found to support EIP-1559
*
* @param state
- * @param networkClientId
+ * @param networkClientId - The optional network client ID to check for EIP-1559 support. Defaults to the currently selected network.
*/
export function isEIP1559Network(state, networkClientId) {
const selectedNetworkClientId = getSelectedNetworkClientId(state);
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 3f97c8e54529..b58a2654815b 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -32,7 +32,7 @@ import usePolling from './usePolling';
* GasFeeController that it is done requiring new gas estimates. Also checks
* the returned gas estimate for validity on the current network.
*
- * @param _networkClientId
+ * @param _networkClientId - The optional network client ID to get gas fee estimates for. Defaults to the currently selected network.
* @returns {GasEstimates} GasEstimates object
*/
export function useGasFeeEstimates(_networkClientId) {
diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js
index d9f24ee4ba8b..3b8c5115b812 100644
--- a/ui/selectors/selectors.js
+++ b/ui/selectors/selectors.js
@@ -182,7 +182,7 @@ export function getCurrentKeyring(state) {
* both of them support EIP-1559.
*
* @param state
- * @param networkClientId
+ * @param networkClientId - The optional network client ID to check network and account for EIP-1559 support
*/
export function checkNetworkAndAccountSupports1559(state, networkClientId) {
const networkSupports1559 = isEIP1559Network(state, networkClientId);
From cd086c4e9de4169aef2c5f7bf557d7c774479bff Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 16 Feb 2024 15:54:37 -0800
Subject: [PATCH 12/74] remove .tool-versions
---
.tool-versions | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 .tool-versions
diff --git a/.tool-versions b/.tool-versions
deleted file mode 100644
index 38b76b57c456..000000000000
--- a/.tool-versions
+++ /dev/null
@@ -1 +0,0 @@
-nodejs 20.8.1
From 6398d0617391aed52b431cdb0bf58dc6bf913a93 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:00:32 -0800
Subject: [PATCH 13/74] fix advanced-gas-fee-gas-limit.test.js
---
.../advanced-gas-fee-gas-limit.test.js | 52 +++++++++++++------
1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
index 51e0c5ed9c6d..4c3c49f294a7 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
@@ -11,17 +11,21 @@ import configureStore from '../../../../../store/store';
import { AdvancedGasFeePopoverContextProvider } from '../context';
import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit';
+import { act } from 'react-dom/test-utils';
jest.mock('../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
}));
-const render = (contextProps) => {
+
+
+const render = async (contextProps) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -31,14 +35,26 @@ const render = (contextProps) => {
balance: '0x1F4',
},
},
- advancedGasFee: { priorityFee: 100 },
+ advancedGasFee: { '0x5': { priorityFee: 100 } },
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ result = renderWithProvider(
{
,
store,
- );
+ ))
+
+ return result;
};
describe('AdvancedGasFeeGasLimit', () => {
- it('should show GasLimit from transaction', () => {
- render();
+ it('should show GasLimit from transaction', async () => {
+ await render();
expect(screen.getByText('21000')).toBeInTheDocument();
});
- it('should show input when edit link is clicked', () => {
- render();
+ it('should show input when edit link is clicked', async () => {
+ await render();
expect(document.getElementsByTagName('input')).toHaveLength(0);
fireEvent.click(screen.queryByText('Edit'));
expect(document.getElementsByTagName('input')[0]).toHaveValue(21000);
});
- it('should show error if gas limit is not in range', () => {
- render();
+ it('should show error if gas limit is not in range', async () => {
+ await render();
fireEvent.click(screen.queryByText('Edit'));
fireEvent.change(document.getElementsByTagName('input')[0], {
target: { value: 20000 },
@@ -96,8 +114,8 @@ describe('AdvancedGasFeeGasLimit', () => {
).not.toBeInTheDocument();
});
- it('should validate gas limit against minimumGasLimit it is passed to context', () => {
- render({ minimumGasLimit: '0x7530' });
+ it('should validate gas limit against minimumGasLimit it is passed to context', async () => {
+ await render({ minimumGasLimit: '0x7530' });
fireEvent.click(screen.queryByText('Edit'));
fireEvent.change(document.getElementsByTagName('input')[0], {
target: { value: 25000 },
From c99ff3b3f416b86e0e6ecb71fffc9206652c750b Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:13:16 -0800
Subject: [PATCH 14/74] Fix priority fee
---
.../priority-fee-input/priority-fee-input.js | 25 +++++++++++--------
.../priority-fee-input.test.js | 11 ++++----
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
index 70ee1d913b44..8ec87783bf38 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
@@ -57,19 +57,22 @@ const PriorityFeeInput = () => {
latestPriorityFeeRange,
historicalPriorityFeeRange,
priorityFeeTrend,
- } = gasFeeEstimates;
+ } = gasFeeEstimates ?? {};
const [priorityFeeError, setPriorityFeeError] = useState();
- const [priorityFee, setPriorityFee] = useState(() => {
- if (
- estimateUsed !== PriorityLevels.custom &&
- advancedGasFeeValues?.priorityFee &&
- editGasMode !== EditGasModes.swaps
- ) {
- return advancedGasFeeValues.priorityFee;
- }
- return maxPriorityFeePerGas;
- });
+
+ const defaultPriorityFee =
+ estimateUsed !== PriorityLevels.custom &&
+ advancedGasFeeValues?.priorityFee &&
+ editGasMode !== EditGasModes.swaps
+ ? advancedGasFeeValues.priorityFee
+ : maxPriorityFeePerGas;
+
+
+ const [priorityFee, setPriorityFee] = useState(defaultPriorityFee);
+ useEffect(() => {
+ setPriorityFee(defaultPriorityFee);
+ }, [defaultPriorityFee, setPriorityFee]);
const { currency, numberOfDecimals } = useUserPreferencedCurrency(PRIMARY);
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
index 6aa3cac2531e..eafe65b10fc0 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
@@ -17,12 +17,13 @@ import { CHAIN_IDS } from '../../../../../../../shared/constants/network';
import PriorityfeeInput from './priority-fee-input';
jest.mock('../../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
}));
const render = (txProps, contextProps) => {
From db00da5ebf118973aa497d03249b20329267fd67 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:13:26 -0800
Subject: [PATCH 15/74] fix base fee import act
---
.../base-fee-input/base-fee-input.test.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
index ab5fa150579f..67a15399f301 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
@@ -1,7 +1,6 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
-import { act } from 'react-dom/test-utils';
import {
EditGasModes,
GasEstimateTypes,
From 40bf680304408e25e21a4e4c649a9a650ba6268c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:13:45 -0800
Subject: [PATCH 16/74] fix advanced fee
---
.../advanced-gas-fee-defaults.test.js | 59 ++++++++++++-------
1 file changed, 38 insertions(+), 21 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
index 7365d6a81cf4..845e0669335a 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
import {
EditGasModes,
@@ -21,18 +21,19 @@ import AdvancedGasFeeDefaults from './advanced-gas-fee-defaults';
const TEXT_SELECTOR = 'Save these values as my default for the Goerli network.';
jest.mock('../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
setAdvancedGasFee: jest.fn(),
updateEventFragment: jest.fn(),
createTransactionEventFragment: jest.fn(),
}));
-const render = (defaultGasParams, contextParams) => {
+const render = async (defaultGasParams, contextParams) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -46,9 +47,22 @@ const render = (defaultGasParams, contextParams) => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
+
+ let result;
+
+ await act(
+ async () =>
+ result = renderWithProvider(
{
,
store,
- );
+ ))
+
+ return result;
};
+
describe('AdvancedGasFeeDefaults', () => {
- it('should renders correct message when the default is not set', () => {
- render({ advancedGasFee: {} });
+ it('should renders correct message when the default is not set', async () => {
+ await render({ advancedGasFee: {} });
expect(screen.queryByText(TEXT_SELECTOR)).toBeInTheDocument();
});
- it('should renders correct message when the default values are set', () => {
- render({
+ it('should renders correct message when the default values are set', async () => {
+ await render({
advancedGasFee: {
[CHAIN_IDS.GOERLI]: { maxBaseFee: 50, priorityFee: 2 },
},
});
expect(screen.queryByText(TEXT_SELECTOR)).toBeInTheDocument();
});
- it('should renders correct message when the default values are set and the maxBaseFee values are updated', () => {
- render({
+ it('should renders correct message when the default values are set and the maxBaseFee values are updated', async () => {
+ await render({
advancedGasFee: {
[CHAIN_IDS.GOERLI]: { maxBaseFee: 50, priorityFee: 2 },
},
@@ -91,8 +108,8 @@ describe('AdvancedGasFeeDefaults', () => {
expect(screen.queryByText(TEXT_SELECTOR)).toBeInTheDocument();
expect(screen.queryByText(TEXT_SELECTOR)).toBeInTheDocument();
});
- it('should renders correct message when the default values are set and the priorityFee values are updated', () => {
- render({
+ it('should renders correct message when the default values are set and the priorityFee values are updated', async () => {
+ await render({
advancedGasFee: {
[CHAIN_IDS.GOERLI]: { maxBaseFee: 50, priorityFee: 2 },
},
@@ -107,8 +124,8 @@ describe('AdvancedGasFeeDefaults', () => {
expect(screen.queryByText(TEXT_SELECTOR)).toBeInTheDocument();
});
- it('should call action setAdvancedGasFee when checkbox or label text is clicked', () => {
- render({
+ it('should call action setAdvancedGasFee when checkbox or label text is clicked', async () => {
+ await render({
advancedGasFee: {
[CHAIN_IDS.GOERLI]: { maxBaseFee: 50, priorityFee: 2 },
},
@@ -124,8 +141,8 @@ describe('AdvancedGasFeeDefaults', () => {
expect(mock).toHaveBeenCalledTimes(2);
});
- it('should not render option to set default gas options in a swaps transaction', () => {
- render({}, { editGasMode: EditGasModes.swaps });
+ it('should not render option to set default gas options in a swaps transaction', async () => {
+ await render({}, { editGasMode: EditGasModes.swaps });
expect(
document.querySelector('input[type=checkbox]'),
).not.toBeInTheDocument();
From 31733873e4c1ca43c52eac51d8b43e4bf7e637ed Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:17:04 -0800
Subject: [PATCH 17/74] fix priority fee input
---
.../advanced-gas-fee-gas-limit.test.js | 3 +-
.../priority-fee-input.test.js | 54 ++++++++++++-------
2 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
index 4c3c49f294a7..0ead69e8d376 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
import { GasEstimateTypes } from '../../../../../../shared/constants/gas';
import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
@@ -11,7 +11,6 @@ import configureStore from '../../../../../store/store';
import { AdvancedGasFeePopoverContextProvider } from '../context';
import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit';
-import { act } from 'react-dom/test-utils';
jest.mock('../../../../../store/actions', () => ({
gasFeeStartPollingByNetworkClientId: jest
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
index eafe65b10fc0..3ff89c456592 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
import {
EditGasModes,
@@ -26,7 +26,7 @@ jest.mock('../../../../../../store/actions', () => ({
.mockResolvedValue({ chainId: '0x5' }),
}));
-const render = (txProps, contextProps) => {
+const render = async (txProps, contextProps) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -40,10 +40,22 @@ const render = (txProps, contextProps) => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ result = renderWithProvider(
{
,
store,
- );
+ ))
+
+ return result;
};
describe('PriorityfeeInput', () => {
- it('should renders advancedGasFee.priorityfee value if current estimate used is not custom', () => {
- render({
+ it('should renders advancedGasFee.priorityfee value if current estimate used is not custom', async () => {
+ await render({
userFeeLevel: 'high',
});
expect(document.getElementsByTagName('input')[0]).toHaveValue(100);
});
- it('should not use advancedGasFee.priorityfee value for swaps', () => {
- render(
+ it('should not use advancedGasFee.priorityfee value for swaps', async () => {
+ await render(
{
userFeeLevel: 'high',
},
@@ -84,8 +98,8 @@ describe('PriorityfeeInput', () => {
);
});
- it('should renders priorityfee value from transaction if current estimate used is custom', () => {
- render({
+ it('should renders priorityfee value from transaction if current estimate used is custom', async () => {
+ await render({
txParams: {
maxPriorityFeePerGas: '0x77359400',
},
@@ -93,13 +107,13 @@ describe('PriorityfeeInput', () => {
expect(document.getElementsByTagName('input')[0]).toHaveValue(2);
});
- it('should show current priority fee range in subtext', () => {
- render();
+ it('should show current priority fee range in subtext', async () => {
+ await render();
expect(screen.queryByText('1 - 20 GWEI')).toBeInTheDocument();
});
- it('should show current value of priority fee in users primary currency in right side of input box', () => {
- render({
+ it('should show current value of priority fee in users primary currency in right side of input box', async () => {
+ await render({
txParams: {
gas: '0x5208',
maxPriorityFeePerGas: '0x77359400',
@@ -108,13 +122,13 @@ describe('PriorityfeeInput', () => {
expect(screen.queryByText('≈ 0.000042 ETH')).toBeInTheDocument();
});
- it('should show 12hr range value in subtext', () => {
- render();
+ it('should show 12hr range value in subtext', async () => {
+ await render();
expect(screen.queryByText('2 - 125 GWEI')).toBeInTheDocument();
});
- it('should not show error if value entered is 0', () => {
- render({
+ it('should not show error if value entered is 0', async () => {
+ await render({
txParams: {
maxPriorityFeePerGas: '0x174876E800',
},
@@ -130,8 +144,8 @@ describe('PriorityfeeInput', () => {
).not.toBeInTheDocument();
});
- it('should not show the error if priority fee is 0', () => {
- render({
+ it('should not show the error if priority fee is 0', async () => {
+ await render({
txParams: {
maxPriorityFeePerGas: '0x0',
},
From b2d3f31c7b7aefa1b6e2536459fac6375bf4a39c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:18:18 -0800
Subject: [PATCH 18/74] fix gas fee popover
---
.../advanced-gas-fee-popover.test.js | 49 ++++++++++++-------
1 file changed, 32 insertions(+), 17 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
index 09ca4ba261a4..3d9dafb1d144 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
@@ -12,12 +12,13 @@ import configureStore from '../../../../store/store';
import AdvancedGasFeePopover from './advanced-gas-fee-popover';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
createTransactionEventFragment: jest.fn(),
}));
@@ -28,7 +29,7 @@ jest.mock('../../../../contexts/transaction-modal', () => ({
}),
}));
-const render = () => {
+const render = async () => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -41,10 +42,22 @@ const render = () => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ result = renderWithProvider(
{
,
store,
- );
+ ))
+
+ return result;
};
describe('AdvancedGasFeePopover', () => {
- it('should renders save button enabled by default', () => {
- render();
+ it('should renders save button enabled by default', async () => {
+ await render();
expect(screen.queryByRole('button', { name: 'Save' })).not.toBeDisabled();
});
- it('should enable save button if priority fee 0 is entered', () => {
- render();
+ it('should enable save button if priority fee 0 is entered', async () => {
+ await render();
fireEvent.change(document.getElementsByTagName('input')[1], {
target: { value: 0 },
});
expect(screen.queryByRole('button', { name: 'Save' })).toBeEnabled();
});
- it('should disable save button if priority fee entered is greater than base fee', () => {
- render();
+ it('should disable save button if priority fee entered is greater than base fee', async () => {
+ await render();
fireEvent.change(document.getElementsByTagName('input')[1], {
target: { value: 100000 },
});
expect(screen.queryByRole('button', { name: 'Save' })).toBeDisabled();
});
- it('should disable save button if gas limit beyond range is entered', () => {
- render();
+ it('should disable save button if gas limit beyond range is entered', async () => {
+ await render();
fireEvent.click(screen.queryByText('Edit'));
fireEvent.change(document.getElementsByTagName('input')[3], {
target: { value: 0 },
From b3160b819ec873b9ff0fb6247dac1329126748d4 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:19:04 -0800
Subject: [PATCH 19/74] lint
---
.../advanced-gas-fee-defaults.test.js | 43 +++++++++---------
.../advanced-gas-fee-gas-limit.test.js | 43 +++++++++---------
.../priority-fee-input/priority-fee-input.js | 12 +++--
.../priority-fee-input.test.js | 45 ++++++++++---------
.../advanced-gas-fee-popover.test.js | 39 ++++++++--------
5 files changed, 91 insertions(+), 91 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
index 845e0669335a..b5b389829748 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
@@ -47,14 +47,14 @@ const render = async (defaultGasParams, contextParams) => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- gasFeeEstimatesByChainId: {
- ...mockState.metamask.gasFeeEstimatesByChainId,
- '0x5': {
- ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
- gasFeeEstimates:
- mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- },
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
+ },
},
});
@@ -62,20 +62,21 @@ const render = async (defaultGasParams, contextParams) => {
await act(
async () =>
- result = renderWithProvider(
-
-
-
-
-
- ,
- store,
- ))
+ (result = renderWithProvider(
+
+
+
+
+
+ ,
+ store,
+ )),
+ );
return result;
};
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
index 0ead69e8d376..bba6d4c5aba8 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.test.js
@@ -22,8 +22,6 @@ jest.mock('../../../../../store/actions', () => ({
.mockResolvedValue({ chainId: '0x5' }),
}));
-
-
const render = async (contextProps) => {
const store = configureStore({
metamask: {
@@ -39,13 +37,13 @@ const render = async (contextProps) => {
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
gasFeeEstimatesByChainId: {
- ...mockState.metamask.gasFeeEstimatesByChainId,
- '0x5': {
- ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
- gasFeeEstimates:
- mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- },
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
+ },
},
});
@@ -53,20 +51,21 @@ const render = async (contextProps) => {
await act(
async () =>
- result = renderWithProvider(
-
-
-
-
- ,
- store,
- ))
+ (result = renderWithProvider(
+
+
+
+
+ ,
+ store,
+ )),
+ );
return result;
};
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
index 8ec87783bf38..a35f118e0f04 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
@@ -60,14 +60,12 @@ const PriorityFeeInput = () => {
} = gasFeeEstimates ?? {};
const [priorityFeeError, setPriorityFeeError] = useState();
-
const defaultPriorityFee =
- estimateUsed !== PriorityLevels.custom &&
- advancedGasFeeValues?.priorityFee &&
- editGasMode !== EditGasModes.swaps
- ? advancedGasFeeValues.priorityFee
- : maxPriorityFeePerGas;
-
+ estimateUsed !== PriorityLevels.custom &&
+ advancedGasFeeValues?.priorityFee &&
+ editGasMode !== EditGasModes.swaps
+ ? advancedGasFeeValues.priorityFee
+ : maxPriorityFeePerGas;
const [priorityFee, setPriorityFee] = useState(defaultPriorityFee);
useEffect(() => {
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
index 3ff89c456592..7133da22a075 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
@@ -40,14 +40,14 @@ const render = async (txProps, contextProps) => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- gasFeeEstimatesByChainId: {
- ...mockState.metamask.gasFeeEstimatesByChainId,
- '0x5': {
- ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
- gasFeeEstimates:
- mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- },
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
+ },
},
});
@@ -55,21 +55,22 @@ const render = async (txProps, contextProps) => {
await act(
async () =>
- result = renderWithProvider(
-
-
-
-
-
- ,
- store,
- ))
+ (result = renderWithProvider(
+
+
+
+
+
+ ,
+ store,
+ )),
+ );
return result;
};
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
index 3d9dafb1d144..488b044513c3 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-popover.test.js
@@ -42,14 +42,14 @@ const render = async () => {
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- gasFeeEstimatesByChainId: {
- ...mockState.metamask.gasFeeEstimatesByChainId,
- '0x5': {
- ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
- gasFeeEstimates:
- mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
- },
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
+ },
},
});
@@ -57,19 +57,20 @@ const render = async () => {
await act(
async () =>
- result = renderWithProvider(
-
-
- ,
- store,
- ))
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
+ );
- return result;
+ return result;
};
describe('AdvancedGasFeePopover', () => {
From 1dc268834855024d3b2a6f40380709dd16d9395d Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 10:39:23 -0800
Subject: [PATCH 20/74] WIP gas-details-item.test.js
---
.../gas-details-item/gas-details-item.test.js | 89 ++++++++++++-------
1 file changed, 58 insertions(+), 31 deletions(-)
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index 2d3321c8596e..eff620570853 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen, waitFor } from '@testing-library/react';
+import { act, screen, waitFor } from '@testing-library/react';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
@@ -11,15 +11,17 @@ import configureStore from '../../../../store/store';
import GasDetailsItem from './gas-details-item';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
}));
-const render = ({ contextProps } = {}) => {
+const render = async ({ contextProps } = {}) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -33,31 +35,46 @@ const render = ({ contextProps } = {}) => {
useNativeCurrencyAsPrimaryCurrency: true,
},
gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
...contextProps,
},
});
- return renderWithProvider(
-
-
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('GasDetailsItem', () => {
it('should render label', async () => {
- render();
+ await render();
await waitFor(() => {
expect(screen.queryAllByText('Market')[0]).toBeInTheDocument();
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
@@ -66,7 +83,7 @@ describe('GasDetailsItem', () => {
});
it('should show warning icon if estimates are high', async () => {
- render({
+ await render({
contextProps: { transaction: { txParams: {}, userFeeLevel: 'high' } },
});
await waitFor(() => {
@@ -75,13 +92,23 @@ describe('GasDetailsItem', () => {
});
it('should show warning icon if dapp estimates are high', async () => {
- render({
+ await render({
contextProps: {
gasFeeEstimates: {
high: {
suggestedMaxPriorityFeePerGas: '1',
},
},
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ gasFeeEstimates: {
+ high: {
+ suggestedMaxPriorityFeePerGas: '1',
+ },
+ },
+ },
+ },
transaction: {
txParams: {
gas: '0x52081',
@@ -101,7 +128,7 @@ describe('GasDetailsItem', () => {
});
it('should not show warning icon if estimates are not high', async () => {
- render({
+ await render({
contextProps: { transaction: { txParams: {}, userFeeLevel: 'low' } },
});
await waitFor(() => {
@@ -109,8 +136,8 @@ describe('GasDetailsItem', () => {
});
});
- it('should return null if there is simulationError and user has not acknowledged gasMissing warning', () => {
- const { container } = render({
+ it('should return null if there is simulationError and user has not acknowledged gasMissing warning', async () => {
+ const { container } = await render({
contextProps: {
transaction: {
txParams: {},
@@ -123,7 +150,7 @@ describe('GasDetailsItem', () => {
});
it('should not return null even if there is simulationError if user acknowledged gasMissing warning', async () => {
- render();
+ await render();
await waitFor(() => {
expect(screen.queryAllByText('Market')[0]).toBeInTheDocument();
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
@@ -132,7 +159,7 @@ describe('GasDetailsItem', () => {
});
it('should render gas fee details', async () => {
- render();
+ await render();
await waitFor(() => {
expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0);
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
@@ -140,7 +167,7 @@ describe('GasDetailsItem', () => {
});
it('should render gas fee details if maxPriorityFeePerGas is 0', async () => {
- render({
+ await render({
contextProps: {
transaction: {
txParams: {
@@ -160,7 +187,7 @@ describe('GasDetailsItem', () => {
});
it('should render gas fee details if maxPriorityFeePerGas is undefined', async () => {
- render({
+ await render({
contextProps: {
transaction: {
txParams: {
From af58cc94d9e8a4ebbdec62903195b68143af48e1 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 12:29:14 -0800
Subject: [PATCH 21/74] WIP
---
ui/hooks/useGasFeeEstimates.js | 24 +++++++++----------
.../gas-details-item/gas-details-item.test.js | 2 +-
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index b58a2654815b..d15649b7182b 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -42,28 +42,28 @@ export function useGasFeeEstimates(_networkClientId) {
const [chainId, setChainId] = useState('');
const gasEstimateType = useSelector((state) =>
- getGasEstimateTypeByChainId(state, chainId),
+ getGasEstimateTypeByChainId(state, '0x5'),
);
const gasFeeEstimates = useSelector(
(state) => getGasFeeEstimatesByChainId(state, chainId),
isEqual,
);
const isGasEstimatesLoading = useSelector((state) =>
- getIsGasEstimatesLoadingByChainId(state, { chainId, networkClientId }),
+ getIsGasEstimatesLoadingByChainId(state, { chainId: '0x5', networkClientId }),
);
const isNetworkBusy = useSelector((state) =>
- getIsNetworkBusyByChainId(state, chainId),
+ getIsNetworkBusyByChainId(state, '0x5'),
);
- useEffect(() => {
- getNetworkConfigurationByNetworkClientId(networkClientId).then(
- (networkConfig) => {
- if (networkConfig) {
- setChainId(networkConfig.chainId);
- }
- },
- );
- }, [networkClientId]);
+ // useEffect(() => {
+ // getNetworkConfigurationByNetworkClientId(networkClientId).then(
+ // (networkConfig) => {
+ // if (networkConfig) {
+ // setChainId(networkConfig.chainId);
+ // }
+ // },
+ // );
+ // }, [networkClientId]);
usePolling({
startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index eff620570853..e21773792de0 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -158,7 +158,7 @@ describe('GasDetailsItem', () => {
});
});
- it('should render gas fee details', async () => {
+ it.only('should render gas fee details', async () => {
await render();
await waitFor(() => {
expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0);
From 2e7db99322246b7275751af0679b5d4ba6925a27 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 14:51:19 -0800
Subject: [PATCH 22/74] Fix specs
---
.../__snapshots__/confirm-gas-display.test.js.snap | 6 +++---
.../confirm-gas-display/confirm-gas-display.test.js | 2 +-
.../gas-details-item/gas-details-item.test.js | 10 ++++------
.../transaction-detail.component.test.js | 2 +-
4 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm-gas-display/__snapshots__/confirm-gas-display.test.js.snap b/ui/pages/confirmations/components/confirm-gas-display/__snapshots__/confirm-gas-display.test.js.snap
index a798793d2c62..b3f464b168a5 100644
--- a/ui/pages/confirmations/components/confirm-gas-display/__snapshots__/confirm-gas-display.test.js.snap
+++ b/ui/pages/confirmations/components/confirm-gas-display/__snapshots__/confirm-gas-display.test.js.snap
@@ -87,16 +87,16 @@ exports[`ConfirmGasDisplay should match snapshot 1`] = `
- Advanced
+ Unknown processing time
~
- 1 sec
+
diff --git a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
index 296b90d1503c..484c602fcbcd 100644
--- a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
+++ b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
@@ -36,7 +36,7 @@ const render = ({ transactionProp = {}, contextProps = {} } = {}) => {
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
+ gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
});
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index 2d3321c8596e..2d3496b3c164 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -32,7 +32,7 @@ const render = ({ contextProps } = {}) => {
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
+ gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
...contextProps,
},
});
@@ -42,8 +42,6 @@ const render = ({ contextProps } = {}) => {
transaction={{
txParams: {
gas: '0x5208',
- maxFeePerGas: '0x59682f10',
- maxPriorityFeePerGas: '0x59682f00',
},
userFeeLevel: 'medium',
}}
@@ -134,7 +132,7 @@ describe('GasDetailsItem', () => {
it('should render gas fee details', async () => {
render();
await waitFor(() => {
- expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0);
+ expect(screen.queryAllByTitle('0.00147 ETH').length).toBeGreaterThan(0);
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
});
});
@@ -154,7 +152,7 @@ describe('GasDetailsItem', () => {
},
});
await waitFor(() => {
- expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0);
+ expect(screen.queryAllByTitle('0.001113 ETH').length).toBeGreaterThan(0);
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
});
});
@@ -173,7 +171,7 @@ describe('GasDetailsItem', () => {
},
});
await waitFor(() => {
- expect(screen.queryAllByTitle('0.0000315 ETH').length).toBeGreaterThan(0);
+ expect(screen.queryAllByTitle('0.001113 ETH').length).toBeGreaterThan(0);
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
});
});
diff --git a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
index b9434e18a0f6..af94d90d2daa 100644
--- a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
+++ b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
@@ -31,7 +31,7 @@ const render = ({ componentProps, contextProps } = {}) => {
balance: '0x1F4',
},
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
+ gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
});
From be2afe8f924891690b534ced83e0b00e7b8eb0ad Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 14:53:11 -0800
Subject: [PATCH 23/74] lint
---
.../components/confirm-gas-display/confirm-gas-display.test.js | 3 ++-
.../components/gas-details-item/gas-details-item.test.js | 3 ++-
.../transaction-detail/transaction-detail.component.test.js | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
index 484c602fcbcd..deecbf007783 100644
--- a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
+++ b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
@@ -36,7 +36,8 @@ const render = ({ transactionProp = {}, contextProps = {} } = {}) => {
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
});
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index 2d3496b3c164..02071860835e 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -32,7 +32,8 @@ const render = ({ contextProps } = {}) => {
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
...contextProps,
},
});
diff --git a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
index af94d90d2daa..1e1fa3804429 100644
--- a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
+++ b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
@@ -31,7 +31,8 @@ const render = ({ componentProps, contextProps } = {}) => {
balance: '0x1F4',
},
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
});
From a9b0dc699031d44559a57433af2b521705e2e423 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 14:57:16 -0800
Subject: [PATCH 24/74] missed one
---
.../components/edit-gas-fee-button/edit-gas-fee-button.test.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
index 922b1eae7fb0..d0c351809e64 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
@@ -35,7 +35,8 @@ const render = ({ componentProps, contextProps } = {}) => {
balance: '0x1F4',
},
},
- gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
},
});
From aef952038c3ec7451833419d646ea4ca6a0b8933 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 15:12:31 -0800
Subject: [PATCH 25/74] restore useGasFeeEstimates
---
ui/hooks/useGasFeeEstimates.js | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 31ce0c26cb38..92612ff63691 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -42,7 +42,7 @@ export function useGasFeeEstimates(_networkClientId) {
const [chainId, setChainId] = useState('');
const gasEstimateType = useSelector((state) =>
- getGasEstimateTypeByChainId(state, '0x5'),
+ getGasEstimateTypeByChainId(state, chainId),
);
const gasFeeEstimates = useSelector(
(state) => getGasFeeEstimatesByChainId(state, chainId),
@@ -50,23 +50,23 @@ export function useGasFeeEstimates(_networkClientId) {
);
const isGasEstimatesLoading = useSelector((state) =>
getIsGasEstimatesLoadingByChainId(state, {
- chainId: '0x5',
+ chainId,
networkClientId,
}),
);
const isNetworkBusy = useSelector((state) =>
- getIsNetworkBusyByChainId(state, '0x5'),
+ getIsNetworkBusyByChainId(state, chainId),
);
- // useEffect(() => {
- // getNetworkConfigurationByNetworkClientId(networkClientId).then(
- // (networkConfig) => {
- // if (networkConfig) {
- // setChainId(networkConfig.chainId);
- // }
- // },
- // );
- // }, [networkClientId]);
+ useEffect(() => {
+ getNetworkConfigurationByNetworkClientId(networkClientId).then(
+ (networkConfig) => {
+ if (networkConfig) {
+ setChainId(networkConfig.chainId);
+ }
+ },
+ );
+ }, [networkClientId]);
usePolling({
startPollingByNetworkClientId: gasFeeStartPollingByNetworkClientId,
From c0339b81459f2102633a70ea5bdb07631ca1d649 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 20 Feb 2024 15:12:39 -0800
Subject: [PATCH 26/74] fix gas-details-item act
---
.../gas-details-item/gas-details-item.test.js | 31 ++++++++++---------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
index da271eb40950..60f0cba4d7b5 100644
--- a/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
+++ b/ui/pages/confirmations/components/gas-details-item/gas-details-item.test.js
@@ -50,21 +50,22 @@ const render = async ({ contextProps } = {}) => {
let result;
- await act(async () =>
- renderWithProvider(
-
-
- ,
- store,
- ),
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
);
return result;
From ffb7ab40c54661ab104036bd5754046523b14b72 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 09:28:11 -0800
Subject: [PATCH 27/74] Fix useGasItemFeeDetails gasFeeEstimates undefined
reference
---
.../edit-gas-fee-popover/edit-gas-item/useGasItemFeeDetails.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/useGasItemFeeDetails.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/useGasItemFeeDetails.js
index bfe35be4ad04..3e78d5ac05fc 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/useGasItemFeeDetails.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/useGasItemFeeDetails.js
@@ -79,7 +79,7 @@ export const useGasItemFeeDetails = (priorityLevel) => {
maxPriorityFeePerGas,
});
- if (gasFeeEstimates[priorityLevel]) {
+ if (gasFeeEstimates?.[priorityLevel]) {
minWaitTime =
priorityLevel === PriorityLevels.high
? gasFeeEstimates?.high.minWaitTimeEstimate
From c20fb28aa67147b368efbbf0894dd6a90e8696ff Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 09:55:36 -0800
Subject: [PATCH 28/74] Fix base-fee-input.test.js
---
.../base-fee-input/base-fee-input.test.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
index 66efaa22403a..c3413ddc0a0b 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.test.js
@@ -138,8 +138,8 @@ describe('BaseFeeInput', () => {
);
});
- it('should show current value of estimatedBaseFee in users primary currency in right side of input box', () => {
- render({
+ it('should show current value of estimatedBaseFee in users primary currency in right side of input box', async () => {
+ await render({
txParams: {
gas: '0x5208',
maxFeePerGas: '0x2E90EDD000',
@@ -196,8 +196,8 @@ describe('BaseFeeInput', () => {
});
describe('updateBaseFee', () => {
- it('updates base fee correctly', () => {
- const { getByTestId } = render();
+ it('updates base fee correctly', async () => {
+ const { getByTestId } = await render();
const input = getByTestId('base-fee-input');
fireEvent.change(input, { target: { value: '1' } });
@@ -205,8 +205,8 @@ describe('BaseFeeInput', () => {
expect(input.value).toBe('1');
});
- it('handles low numbers', () => {
- const { getByTestId } = render();
+ it('handles low numbers', async () => {
+ const { getByTestId } = await render();
const input = getByTestId('base-fee-input');
fireEvent.change(input, { target: { value: LOW_BASE_FEE } });
From 18e5801fc56a8b21fb4965f243f2af1293a69422 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 10:20:01 -0800
Subject: [PATCH 29/74] fix priority-fee-input.test.js
---
.../priority-fee-input/priority-fee-input.test.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
index 40b6df46d408..1378e89c84b3 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.test.js
@@ -179,8 +179,8 @@ describe('PriorityfeeInput', () => {
});
describe('updatePriorityFee', () => {
- it('updates base fee correctly', () => {
- const { getByTestId } = render();
+ it('updates base fee correctly', async () => {
+ const { getByTestId } = await render();
const input = getByTestId('priority-fee-input');
fireEvent.change(input, { target: { value: '1' } });
@@ -188,8 +188,8 @@ describe('PriorityfeeInput', () => {
expect(input.value).toBe('1');
});
- it('handles low numbers', () => {
- const { getByTestId } = render();
+ it('handles low numbers', async () => {
+ const { getByTestId } = await render();
const input = getByTestId('priority-fee-input');
fireEvent.change(input, { target: { value: LOW_PRIORITY_FEE } });
From 55a76ab474a479cffa36147ef1057344fed0836c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 10:43:20 -0800
Subject: [PATCH 30/74] fix transaction-detail.component.test.js
---
.../transaction-detail.component.test.js | 61 ++++++++++++-------
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
index 1e1fa3804429..5a5d7431c2d0 100644
--- a/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
+++ b/ui/pages/confirmations/components/transaction-detail/transaction-detail.component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import { TransactionEnvelopeType } from '@metamask/transaction-controller';
import { GasEstimateTypes } from '../../../../../shared/constants/gas';
@@ -13,15 +13,17 @@ import configureStore from '../../../../store/store';
import TransactionDetail from './transaction-detail.component';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
createTransactionEventFragment: jest.fn(),
}));
-const render = ({ componentProps, contextProps } = {}) => {
+const render = async ({ componentProps, contextProps } = {}) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -33,33 +35,48 @@ const render = ({ componentProps, contextProps } = {}) => {
},
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
-
- {
- console.log('on edit');
- }}
- rows={[]}
- userAcknowledgedGasMissing
- {...componentProps}
- />
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+ {
+ console.log('on edit');
+ }}
+ rows={[]}
+ userAcknowledgedGasMissing
+ {...componentProps}
+ />
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('TransactionDetail', () => {
- it('should render edit link with text low if low gas estimates are selected', () => {
- render({ contextProps: { transaction: { userFeeLevel: 'low' } } });
+ it('should render edit link with text low if low gas estimates are selected', async () => {
+ await render({ contextProps: { transaction: { userFeeLevel: 'low' } } });
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('Low')).toBeInTheDocument();
});
- it('should render edit link with text edit for legacy transactions', () => {
- render({
+ it('should render edit link with text edit for legacy transactions', async () => {
+ await render({
contextProps: {
transaction: {
userFeeLevel: 'low',
From 35b7f78b3b702f4afb066b10e11ce5fbede1459e Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 10:56:55 -0800
Subject: [PATCH 31/74] Fix ui/pages/swaps test
---
ui/ducks/metamask/metamask.js | 6 +++---
ui/pages/swaps/index.test.js | 13 +++++++++++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/ui/ducks/metamask/metamask.js b/ui/ducks/metamask/metamask.js
index 71924dbdd7bc..26e1883d2bf6 100644
--- a/ui/ducks/metamask/metamask.js
+++ b/ui/ducks/metamask/metamask.js
@@ -355,15 +355,15 @@ export function getEstimatedGasFeeTimeBounds(state) {
}
export function getGasEstimateTypeByChainId(state, chainId) {
- return state.metamask.gasFeeEstimatesByChainId[chainId]?.gasEstimateType;
+ return state.metamask.gasFeeEstimatesByChainId?.[chainId]?.gasEstimateType;
}
export function getGasFeeEstimatesByChainId(state, chainId) {
- return state.metamask.gasFeeEstimatesByChainId[chainId]?.gasFeeEstimates;
+ return state.metamask.gasFeeEstimatesByChainId?.[chainId]?.gasFeeEstimates;
}
export function getEstimatedGasFeeTimeBoundsByChainId(state, chainId) {
- return state.metamask.gasFeeEstimatesByChainId[chainId]
+ return state.metamask.gasFeeEstimatesByChainId?.[chainId]
?.estimatedGasFeeTimeBounds;
}
diff --git a/ui/pages/swaps/index.test.js b/ui/pages/swaps/index.test.js
index 3844631bc892..ddd867bc62d4 100644
--- a/ui/pages/swaps/index.test.js
+++ b/ui/pages/swaps/index.test.js
@@ -21,8 +21,13 @@ setBackgroundConnection({
setSwapsLiveness: jest.fn(() => true),
setSwapsTokens: jest.fn(),
setSwapsTxGasPrice: jest.fn(),
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest.fn(),
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x1' }),
});
describe('Swap', () => {
@@ -49,6 +54,10 @@ describe('Swap', () => {
.get('/networks/1/tokens')
.reply(200, MOCKS.TOKENS_GET_RESPONSE);
+ nock(CONSTANTS.METASWAP_BASE_URL)
+ .get('/networks/1/tokens?includeBlockedTokens=true')
+ .reply(200, MOCKS.TOKENS_GET_RESPONSE);
+
featureFlagsNock = nock(CONSTANTS.METASWAP_BASE_URL)
.get('/featureFlags')
.reply(200, MOCKS.createFeatureFlagsResponse());
From 2293f79f1014069d0e72441fa1b1f0457d5c0924 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 11:18:28 -0800
Subject: [PATCH 32/74] fix transaction-list-item-details.component.test.js
---
...action-list-item-details.component.test.js | 148 ++++++++----------
1 file changed, 64 insertions(+), 84 deletions(-)
diff --git a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js
index 793dec26db85..092464decc55 100644
--- a/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js
+++ b/ui/components/app/transaction-list-item-details/transaction-list-item-details.component.test.js
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-import { waitFor } from '@testing-library/react';
+import { act, waitFor } from '@testing-library/react';
import { TransactionStatus } from '@metamask/transaction-controller';
import { GAS_LIMITS } from '../../../../shared/constants/gas';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
@@ -10,8 +10,13 @@ import TransactionListItemDetails from '.';
jest.mock('../../../store/actions.ts', () => ({
tryReverseResolveAddress: () => jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest.fn().mockResolvedValue(),
- addPollingTokenToAppState: jest.fn(),
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
}));
let mockGetCustodianTransactionDeepLink = jest.fn();
@@ -22,34 +27,34 @@ jest.mock('../../../store/institutional/institution-background', () => ({
}),
}));
-describe('TransactionListItemDetails Component', () => {
- const transaction = {
- history: [],
- id: 1,
- status: TransactionStatus.confirmed,
- txParams: {
- from: '0x1',
- gas: GAS_LIMITS.SIMPLE,
- gasPrice: '0x3b9aca00',
- nonce: '0xa4',
- to: '0x2',
- value: '0x2386f26fc10000',
- },
- metadata: {
- note: 'some note',
- },
- custodyId: '1',
- };
-
- const transactionGroup = {
- transactions: [transaction],
- primaryTransaction: transaction,
- initialTransaction: transaction,
+const transaction = {
+ history: [],
+ id: 1,
+ status: TransactionStatus.confirmed,
+ txParams: {
+ from: '0x1',
+ gas: GAS_LIMITS.SIMPLE,
+ gasPrice: '0x3b9aca00',
nonce: '0xa4',
- hasRetried: false,
- hasCancelled: false,
- };
-
+ to: '0x2',
+ value: '0x2386f26fc10000',
+ },
+ metadata: {
+ note: 'some note',
+ },
+ custodyId: '1',
+};
+
+const transactionGroup = {
+ transactions: [transaction],
+ primaryTransaction: transaction,
+ initialTransaction: transaction,
+ nonce: '0xa4',
+ hasRetried: false,
+ hasCancelled: false,
+};
+
+const render = async (overrideProps) => {
const rpcPrefs = {
blockExplorerUrl: 'https://customblockexplorer.com/',
};
@@ -69,70 +74,52 @@ describe('TransactionListItemDetails Component', () => {
transactionStatus: () => ,
blockExplorerLinkText,
rpcPrefs,
+ ...overrideProps,
};
- it('should render title with title prop', async () => {
- const mockStore = configureMockStore([thunk])(mockState);
+ const mockStore = configureMockStore([thunk])(mockState);
+
+ let result;
- const { queryByText } = renderWithProvider(
- ,
- mockStore,
- );
+ await act(
+ async () =>
+ (result = renderWithProvider(
+ ,
+ mockStore,
+ )),
+ );
+
+ return result;
+};
+
+describe('TransactionListItemDetails Component', () => {
+ it('should render title with title prop', async () => {
+ const { queryByText } = await render();
await waitFor(() => {
- expect(queryByText(props.title)).toBeInTheDocument();
+ expect(queryByText('Test Transaction Details')).toBeInTheDocument();
});
});
describe('Retry button', () => {
- it('should render retry button with showRetry prop', () => {
- const retryProps = {
- ...props,
- showRetry: true,
- };
-
- const mockStore = configureMockStore([thunk])(mockState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
- );
+ it('should render retry button with showRetry prop', async () => {
+ const { queryByTestId } = await render({ showRetry: true });
expect(queryByTestId('rety-button')).toBeInTheDocument();
});
});
describe('Cancel button', () => {
- it('should render cancel button with showCancel prop', () => {
- const retryProps = {
- ...props,
- showCancel: true,
- };
-
- const mockStore = configureMockStore([thunk])(mockState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
- );
+ it('should render cancel button with showCancel prop', async () => {
+ const { queryByTestId } = await render({ showCancel: true });
expect(queryByTestId('cancel-button')).toBeInTheDocument();
});
});
describe('Speedup button', () => {
- it('should render speedup button with showSpeedUp prop', () => {
- const retryProps = {
- ...props,
- showSpeedUp: true,
- };
-
- const mockStore = configureMockStore([thunk])(mockState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
- );
+ it('should render speedup button with showSpeedUp prop', async () => {
+ const { queryByTestId } = await render({ showSpeedUp: true });
expect(queryByTestId('speedup-button')).toBeInTheDocument();
});
@@ -144,9 +131,7 @@ describe('TransactionListItemDetails Component', () => {
.fn()
.mockReturnValue({ url: 'https://url.com' });
- const mockStore = configureMockStore([thunk])(mockState);
-
- renderWithProvider(, mockStore);
+ await render({ showCancel: true });
await waitFor(() => {
const custodianViewButton = document.querySelector(
@@ -173,15 +158,10 @@ describe('TransactionListItemDetails Component', () => {
primaryTransaction: newTransaction,
initialTransaction: newTransaction,
};
- const mockStore = configureMockStore([thunk])(mockState);
- const { queryByText } = renderWithProvider(
- ,
- mockStore,
- );
+ const { queryByText } = await render({
+ transactionGroup: newTransactionGroup,
+ });
await waitFor(() => {
expect(queryByText('some note')).toBeInTheDocument();
From 112397685474c2b1fe49455493c7e98921e8bfd5 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 11:36:46 -0800
Subject: [PATCH 33/74] fix send-content.component.test.js
---
.../send-content.component.test.js | 239 +++++++-----------
1 file changed, 86 insertions(+), 153 deletions(-)
diff --git a/ui/pages/confirmations/send/send-content/send-content.component.test.js b/ui/pages/confirmations/send/send-content/send-content.component.test.js
index 88c6fb270cce..ccfa8769c7f0 100644
--- a/ui/pages/confirmations/send/send-content/send-content.component.test.js
+++ b/ui/pages/confirmations/send/send-content/send-content.component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { waitFor } from '@testing-library/react';
+import { act, waitFor } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
@@ -13,10 +13,13 @@ import { useIsOriginalNativeTokenSymbol } from '../../../../hooks/useIsOriginalN
import SendContent from '.';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest.fn().mockResolvedValue(),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
createTransactionEventFragment: jest.fn(),
getGasFeeTimeEstimate: jest.fn().mockResolvedValue('unknown'),
getTokenSymbol: jest.fn().mockResolvedValue('ETH'),
@@ -28,31 +31,41 @@ jest.mock('../../../../hooks/useIsOriginalNativeTokenSymbol', () => {
};
});
-describe('SendContent Component', () => {
- useIsOriginalNativeTokenSymbol.mockReturnValue(true);
- describe('render', () => {
- const mockStore = configureMockStore()({
- ...mockSendState,
- metamask: {
- ...mockSendState.metamask,
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- type: NETWORK_TYPES.GOERLI,
- },
+const render = async (props, overrideStoreState) => {
+ const mockStore = configureMockStore()({
+ ...mockSendState,
+ metamask: {
+ ...mockSendState.metamask,
+ providerConfig: {
+ chainId: CHAIN_IDS.GOERLI,
+ nickname: GOERLI_DISPLAY_NAME,
+ type: NETWORK_TYPES.GOERLI,
},
- });
+ },
+ ...overrideStoreState,
+ });
+
+ let result;
+ await act(
+ async () =>
+ (result = renderWithProvider(, mockStore)),
+ );
+
+ return result;
+};
+
+describe('SendContent Component', () => {
+ beforeEach(() => {
+ useIsOriginalNativeTokenSymbol.mockReturnValue(true);
+ });
+
+ describe('render', () => {
it('should match snapshot', async () => {
- const props = {
+ const { container } = await render({
gasIsExcessive: false,
showHexData: true,
- };
-
- const { container } = renderWithProvider(
- ,
- mockStore,
- );
+ });
await waitFor(() => {
expect(container).toMatchSnapshot();
@@ -61,78 +74,47 @@ describe('SendContent Component', () => {
});
describe('SendHexDataRow', () => {
- const tokenAssetState = {
- ...mockSendState,
- send: {
- ...mockSendState.send,
- draftTransactions: {
- '1-tx': {
- ...mockSendState.send.draftTransactions['1-tx'],
- asset: {
- balance: '0x3635c9adc5dea00000',
- details: {
- address: '0xAddress',
- decimals: 18,
- symbol: 'TST',
- balance: '1',
- standard: 'ERC20',
- },
- error: null,
- type: 'TOKEN',
- },
- },
- },
- },
- metamask: {
- ...mockSendState.metamask,
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- type: NETWORK_TYPES.GOERLI,
- },
- },
- };
-
it('should not render the SendHexDataRow if props.showHexData is false', async () => {
- const props = {
+ const { queryByText } = await render({
gasIsExcessive: false,
showHexData: false,
- };
-
- const mockStore = configureMockStore()({
- ...mockSendState,
- metamask: {
- ...mockSendState.metamask,
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- type: NETWORK_TYPES.GOERLI,
- },
- },
});
- const { queryByText } = renderWithProvider(
- ,
- mockStore,
- );
-
await waitFor(() => {
expect(queryByText('Hex data:')).not.toBeInTheDocument();
});
});
it('should not render the SendHexDataRow if the asset type is TOKEN (ERC-20)', async () => {
- const props = {
- gasIsExcessive: false,
- showHexData: true,
+ const tokenAssetState = {
+ send: {
+ ...mockSendState.send,
+ draftTransactions: {
+ '1-tx': {
+ ...mockSendState.send.draftTransactions['1-tx'],
+ asset: {
+ balance: '0x3635c9adc5dea00000',
+ details: {
+ address: '0xAddress',
+ decimals: 18,
+ symbol: 'TST',
+ balance: '1',
+ standard: 'ERC20',
+ },
+ error: null,
+ type: 'TOKEN',
+ },
+ },
+ },
+ },
};
- // Use token draft transaction asset
- const mockState = configureMockStore()(tokenAssetState);
-
- const { queryByText } = renderWithProvider(
- ,
- mockState,
+ const { queryByText } = await render(
+ {
+ gasIsExcessive: false,
+ showHexData: true,
+ },
+ tokenAssetState,
);
await waitFor(() => {
@@ -143,28 +125,11 @@ describe('SendContent Component', () => {
describe('Gas Error', () => {
it('should show gas warning when gasIsExcessive prop is true.', async () => {
- const props = {
+ const { queryByTestId } = await render({
gasIsExcessive: true,
showHexData: false,
- };
-
- const mockStore = configureMockStore()({
- ...mockSendState,
- metamask: {
- ...mockSendState.metamask,
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- type: NETWORK_TYPES.GOERLI,
- },
- },
});
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
- );
-
const gasWarning = queryByTestId('gas-warning-message');
await waitFor(() => {
@@ -173,13 +138,7 @@ describe('SendContent Component', () => {
});
it('should show gas warning for none gasEstimateType in state', async () => {
- const props = {
- gasIsExcessive: false,
- showHexData: false,
- };
-
const noGasPriceState = {
- ...mockSendState,
metamask: {
...mockSendState.metamask,
gasEstimateType: 'none',
@@ -191,11 +150,12 @@ describe('SendContent Component', () => {
},
};
- const mockStore = configureMockStore()(noGasPriceState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
+ const { queryByTestId } = await render(
+ {
+ gasIsExcessive: false,
+ showHexData: false,
+ },
+ noGasPriceState,
);
const gasWarning = queryByTestId('gas-warning-message');
@@ -208,13 +168,7 @@ describe('SendContent Component', () => {
describe('Recipient Warning', () => {
it('should show recipient warning with knownAddressRecipient state in draft transaction state', async () => {
- const props = {
- gasIsExcessive: false,
- showHexData: false,
- };
-
const knownRecipientWarningState = {
- ...mockSendState,
send: {
...mockSendState.send,
draftTransactions: {
@@ -238,11 +192,12 @@ describe('SendContent Component', () => {
},
};
- const mockStore = configureMockStore()(knownRecipientWarningState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
+ const { queryByTestId } = await render(
+ {
+ gasIsExcessive: false,
+ showHexData: false,
+ },
+ knownRecipientWarningState,
);
const sendWarning = queryByTestId('send-warning');
@@ -255,13 +210,7 @@ describe('SendContent Component', () => {
describe('Assert Error', () => {
it('should render dialog error with asset error in draft transaction state', async () => {
- const props = {
- gasIsExcessive: false,
- showHexData: false,
- };
-
const assertErrorState = {
- ...mockSendState,
send: {
...mockSendState.send,
draftTransactions: {
@@ -285,11 +234,12 @@ describe('SendContent Component', () => {
},
};
- const mockStore = configureMockStore()(assertErrorState);
-
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
+ const { queryByTestId } = await render(
+ {
+ gasIsExcessive: false,
+ showHexData: false,
+ },
+ assertErrorState,
);
const dialogMessage = queryByTestId('dialog-message');
@@ -302,29 +252,12 @@ describe('SendContent Component', () => {
describe('Warning', () => {
it('should display warning dialog message from warning prop', async () => {
- const props = {
+ const { queryByTestId } = await render({
gasIsExcessive: false,
showHexData: false,
warning: 'warning',
- };
-
- const mockStore = configureMockStore()({
- ...mockSendState,
- metamask: {
- ...mockSendState.metamask,
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- type: NETWORK_TYPES.GOERLI,
- },
- },
});
- const { queryByTestId } = renderWithProvider(
- ,
- mockStore,
- );
-
const dialogMessage = queryByTestId('dialog-message');
await waitFor(() => {
From f565236c4f9f9cfd086a7f385b82def543543ce9 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Wed, 21 Feb 2024 14:48:26 -0500
Subject: [PATCH 34/74] Get confirmation container container tests passing and
remove act warnings
---
.../confirm-page-container-container.test.js | 74 ++++++++++++-------
1 file changed, 49 insertions(+), 25 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm-page-container/confirm-page-container-container.test.js b/ui/pages/confirmations/components/confirm-page-container/confirm-page-container-container.test.js
index 4a515fad6b45..eb38c48a510c 100644
--- a/ui/pages/confirmations/components/confirm-page-container/confirm-page-container-container.test.js
+++ b/ui/pages/confirmations/components/confirm-page-container/confirm-page-container-container.test.js
@@ -163,6 +163,13 @@ jest.mock('../../../../store/actions', () => ({
getGasFeeEstimatesAndStartPolling: jest
.fn()
.mockImplementation(() => Promise.resolve()),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() => {
+ return Promise.resolve({ chainId: '0x5' });
+ }),
+ gasFeeStartPollingByNetworkClientId: jest.fn().mockImplementation(() => {
+ return Promise.resolve('pollingToken');
+ }),
+ gasFeeStopPollingByPollingToken: jest.fn(),
addPollingTokenToAppState: jest.fn(),
}));
@@ -197,9 +204,11 @@ describe('Confirm Page Container Container Test', () => {
});
describe('Render and simulate button clicks', () => {
- beforeEach(() => {
+ beforeEach(async () => {
const store = configureMockStore()(mockedState);
- renderWithProvider(, store);
+ await act(async () => {
+ renderWithProvider(, store);
+ });
});
it('should render a confirm page container component', () => {
@@ -244,7 +253,7 @@ describe('Confirm Page Container Container Test', () => {
});
describe(`when type is '${TransactionType.tokenMethodSetApprovalForAll}'`, () => {
- it('should display warning modal with total token balance', () => {
+ it('should display warning modal with total token balance', async () => {
const mockValue12AsHexString = '0x0c'; // base-10 representation = 12
TokenUtil.fetchTokenBalance.mockImplementation(() => {
@@ -253,16 +262,18 @@ describe('Confirm Page Container Container Test', () => {
setMockedTransactionType(TransactionType.tokenMethodSetApprovalForAll);
const store = configureMockStore()(mockedState);
- renderWithProvider(
- ,
- store,
- );
+ await act(async () => {
+ renderWithProvider(
+ ,
+ store,
+ );
+ });
- act(() => {
+ await act(async () => {
const confirmButton = screen.getByTestId('page-container-footer-next');
fireEvent.click(confirmButton);
});
@@ -281,25 +292,36 @@ describe('Confirm Page Container Container Test', () => {
describe('Rendering NetworkAccountBalanceHeader', () => {
const store = configureMockStore()(mockState);
- it('should render NetworkAccountBalanceHeader if displayAccountBalanceHeader is true', () => {
- const { getByText } = renderWithProvider(
- ,
- store,
- );
+ it('should render NetworkAccountBalanceHeader if displayAccountBalanceHeader is true', async () => {
+ let result;
+ await act(async () => {
+ result = renderWithProvider(
+ ,
+ store,
+ );
+ });
+ const { getByText } = result;
expect(getByText('Balance')).toBeInTheDocument();
});
- it('should not render NetworkAccountBalanceHeader if displayAccountBalanceHeader is false', () => {
- const { queryByText } = renderWithProvider(
- ,
- store,
- );
- expect(queryByText('Balance')).toBeNull();
+ it('should not render NetworkAccountBalanceHeader if displayAccountBalanceHeader is false', async () => {
+ let result;
+ await act(async () => {
+ result = renderWithProvider(
+ ,
+ store,
+ );
+ });
+ const { queryByText } = result;
+ expect(queryByText('Balance')).toBe(null);
});
});
describe('Contact/AddressBook name should appear in recipient header', () => {
- it('should not show add to address dialog if recipient is in contact list and should display contact name', () => {
+ it('should not show add to address dialog if recipient is in contact list and should display contact name', async () => {
const addressBookName = 'test save name';
const addressBook = {
@@ -320,7 +342,9 @@ describe('Confirm Page Container Container Test', () => {
const store = configureMockStore()(mockState);
- renderWithProvider(, store);
+ await act(async () => {
+ renderWithProvider(, store);
+ });
// Does not display new address dialog banner
const newAccountDetectDialog = screen.queryByText(
From 00f30a6d31fd5faf7583791e61d9e8cbdedb704c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 13:22:03 -0800
Subject: [PATCH 35/74] remove snapshot
---
.../send-content.component.test.js.snap | 291 ------------------
1 file changed, 291 deletions(-)
delete mode 100644 ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
deleted file mode 100644
index cb4204841623..000000000000
--- a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
+++ /dev/null
@@ -1,291 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`SendContent Component render should match snapshot 1`] = `
-
-`;
-
-exports[`SendContent Component render should match snapshot 2`] = ``;
From f2c5a9486cc636b90cf711c79983502c2e840aea Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 14:45:33 -0800
Subject: [PATCH 36/74] fix snapshot
---
.../send-content.component.test.js.snap | 291 ++++++++++++++++++
1 file changed, 291 insertions(+)
create mode 100644 ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
new file mode 100644
index 000000000000..cb4204841623
--- /dev/null
+++ b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
@@ -0,0 +1,291 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`SendContent Component render should match snapshot 1`] = `
+
+`;
+
+exports[`SendContent Component render should match snapshot 2`] = ``;
From 1ed23fccb2e453e0ddd7ca9195cb8868fdd3aa15 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 14:53:13 -0800
Subject: [PATCH 37/74] fix snapshot attempt 2
---
.../__snapshots__/send-content.component.test.js.snap | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
index cb4204841623..8b1c6be08bf3 100644
--- a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
+++ b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
@@ -239,7 +239,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
data-testid="gas-timing-time"
>
~
-
+
@@ -287,5 +287,3 @@ exports[`SendContent Component render should match snapshot 1`] = `
`;
-
-exports[`SendContent Component render should match snapshot 2`] = ``;
From 491951223b10b01602e4e822a29c475aef0d21ac Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 15:04:46 -0800
Subject: [PATCH 38/74] fix snapshot attempt 3
---
.../__snapshots__/send-content.component.test.js.snap | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
index 8b1c6be08bf3..55fc897b62f5 100644
--- a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
+++ b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
@@ -239,7 +239,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
data-testid="gas-timing-time"
>
~
-
+
From 4cdaaa363e46b5a806d97f625c68d1d8c8089d1e Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 15:22:17 -0800
Subject: [PATCH 39/74] fix edit-gas-fee-button.test.js
---
.../edit-gas-fee-button.test.js | 73 ++++++++++++-------
.../edit-gas-item/edit-gas-item.test.js | 1 +
2 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
index d0c351809e64..b520f27b5373 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import { TransactionEnvelopeType } from '@metamask/transaction-controller';
import {
@@ -17,15 +17,17 @@ import configureStore from '../../../../store/store';
import EditGasFeeButton from './edit-gas-fee-button';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
createTransactionEventFragment: jest.fn(),
}));
-const render = ({ componentProps, contextProps } = {}) => {
+const render = async ({ componentProps, contextProps } = {}) => {
const store = configureStore({
metamask: {
...mockState.metamask,
@@ -37,45 +39,60 @@ const render = ({ componentProps, contextProps } = {}) => {
},
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
,
store,
- );
+ )),
+ );
+
+ return result;
};
describe('EditGasFeeButton', () => {
- it('should render edit link with text low if low gas estimates are selected', () => {
- render({ contextProps: { transaction: { userFeeLevel: 'low' } } });
+ it('should render edit link with text low if low gas estimates are selected', async () => {
+ await render({ contextProps: { transaction: { userFeeLevel: 'low' } } });
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('Low')).toBeInTheDocument();
});
- it('should render edit link with text market if medium gas estimates are selected', () => {
- render({ contextProps: { transaction: { userFeeLevel: 'medium' } } });
+ it('should render edit link with text market if medium gas estimates are selected', async () => {
+ await render({ contextProps: { transaction: { userFeeLevel: 'medium' } } });
expect(screen.queryByText('🦊')).toBeInTheDocument();
expect(screen.queryByText('Market')).toBeInTheDocument();
});
- it('should render edit link with text aggressive if high gas estimates are selected', () => {
- render({ contextProps: { transaction: { userFeeLevel: 'high' } } });
+ it('should render edit link with text aggressive if high gas estimates are selected', async () => {
+ await render({ contextProps: { transaction: { userFeeLevel: 'high' } } });
expect(screen.queryByText('🦍')).toBeInTheDocument();
expect(screen.queryByText('Aggressive')).toBeInTheDocument();
});
- it('should render edit link with text 10% increase if tenPercentIncreased gas estimates are selected', () => {
- render({
+ it('should render edit link with text 10% increase if tenPercentIncreased gas estimates are selected', async () => {
+ await render({
contextProps: { transaction: { userFeeLevel: 'tenPercentIncreased' } },
});
expect(screen.queryByText('10% increase')).toBeInTheDocument();
});
- it('should render edit link with text Site suggested if site suggested estimated are used', () => {
- render({
+ it('should render edit link with text Site suggested if site suggested estimated are used', async () => {
+ await render({
contextProps: {
transaction: {
userFeeLevel: PriorityLevels.dAppSuggested,
@@ -89,8 +106,8 @@ describe('EditGasFeeButton', () => {
expect(document.getElementsByClassName('info-tooltip')).toHaveLength(1);
});
- it('should render edit link with text swap suggested if high gas estimates are selected for swaps', () => {
- render({
+ it('should render edit link with text swap suggested if high gas estimates are selected for swaps', async () => {
+ await render({
contextProps: {
transaction: { userFeeLevel: 'high' },
editGasMode: EditGasModes.swaps,
@@ -100,8 +117,8 @@ describe('EditGasFeeButton', () => {
expect(screen.queryByText('Swap suggested')).toBeInTheDocument();
});
- it('should render edit link with text advance if custom gas estimates are used', () => {
- render({
+ it('should render edit link with text advance if custom gas estimates are used', async () => {
+ await render({
contextProps: {
defaultEstimateToUse: 'custom',
transaction: {},
@@ -112,8 +129,8 @@ describe('EditGasFeeButton', () => {
expect(screen.queryByText('Edit')).toBeInTheDocument();
});
- it('should not render edit link if transaction has simulation error and prop userAcknowledgedGasMissing is false', () => {
- render({
+ it('should not render edit link if transaction has simulation error and prop userAcknowledgedGasMissing is false', async () => {
+ await render({
contextProps: {
transaction: {
simulationFails: true,
@@ -126,8 +143,8 @@ describe('EditGasFeeButton', () => {
expect(screen.queryByText('Low')).not.toBeInTheDocument();
});
- it('should render edit link if userAcknowledgedGasMissing is true even if transaction has simulation error', () => {
- render({
+ it('should render edit link if userAcknowledgedGasMissing is true even if transaction has simulation error', async () => {
+ await render({
contextProps: {
transaction: {
simulationFails: true,
@@ -140,8 +157,8 @@ describe('EditGasFeeButton', () => {
expect(screen.queryByText('Low')).toBeInTheDocument();
});
- it('should render null for legacy transactions', () => {
- const { container } = render({
+ it('should render null for legacy transactions', async () => {
+ const { container } = await render({
contextProps: {
transaction: {
userFeeLevel: 'low',
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
index 857dd103e2fb..2901d32ca3c9 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
@@ -55,6 +55,7 @@ const ESTIMATE_MOCK = {
maxPriorityFeePerGas: '0x59682f00',
};
+//
const renderComponent = ({
componentProps,
transactionProps,
From f27318efd64121e30c5ad1732d33e06eb515f3cf Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 15:33:46 -0800
Subject: [PATCH 40/74] fix edit-gas-item.test.js
---
.../edit-gas-item/edit-gas-item.test.js | 91 ++++++++++++-------
1 file changed, 57 insertions(+), 34 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
index 2901d32ca3c9..63325aefc6ee 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-item/edit-gas-item.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import {
EditGasModes,
@@ -17,11 +17,13 @@ import {
import EditGasItem from './edit-gas-item';
jest.mock('../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
getGasFeeTimeEstimate: jest
.fn()
.mockImplementation(() => Promise.resolve('unknown')),
@@ -55,8 +57,7 @@ const ESTIMATE_MOCK = {
maxPriorityFeePerGas: '0x59682f00',
};
-//
-const renderComponent = ({
+const render = async ({
componentProps,
transactionProps,
contextProps,
@@ -69,6 +70,15 @@ const renderComponent = ({
nickname: GOERLI_DISPLAY_NAME,
type: NETWORK_TYPES.GOERLI,
},
+ selectedNetworkClientId: 'goerli',
+ networkConfigurations: {
+ goerli: {
+ type: 'rpc',
+ chainId: '0x5',
+ ticker: 'ETH',
+ id: 'goerli',
+ },
+ },
accountsByChainId: {
[CHAIN_IDS.GOERLI]: {
'0xAddress': {
@@ -90,6 +100,12 @@ const renderComponent = ({
featureFlags: { advancedInlineGas: true },
gasEstimateType: 'fee-market',
gasFeeEstimates: MOCK_FEE_ESTIMATE,
+ gasFeeEstimatesByChainId: {
+ [CHAIN_IDS.GOERLI]: {
+ gasFeeEstimates: MOCK_FEE_ESTIMATE,
+ gasEstimateType: 'fee-market',
+ },
+ },
advancedGasFee: {
[CHAIN_IDS.GOERLI]: {
maxBaseFee: '100',
@@ -99,20 +115,27 @@ const renderComponent = ({
},
});
- return renderWithProvider(
-
-
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('EditGasItem', () => {
- it('should renders low gas estimate option for priorityLevel low', () => {
- renderComponent({ componentProps: { priorityLevel: PriorityLevels.low } });
+ it('should renders low gas estimate option for priorityLevel low', async () => {
+ await render({ componentProps: { priorityLevel: PriorityLevels.low } });
expect(screen.queryByRole('button', { name: 'low' })).toBeInTheDocument();
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('Low')).toBeInTheDocument();
@@ -120,8 +143,8 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.001113 ETH')).toBeInTheDocument();
});
- it('should renders market gas estimate option for priorityLevel medium', () => {
- renderComponent({
+ it('should renders market gas estimate option for priorityLevel medium', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.medium },
});
expect(
@@ -133,8 +156,8 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.00147 ETH')).toBeInTheDocument();
});
- it('should renders aggressive gas estimate option for priorityLevel high', () => {
- renderComponent({ componentProps: { priorityLevel: PriorityLevels.high } });
+ it('should renders aggressive gas estimate option for priorityLevel high', async () => {
+ await render({ componentProps: { priorityLevel: PriorityLevels.high } });
expect(screen.queryByRole('button', { name: 'high' })).toBeInTheDocument();
expect(screen.queryByText('🦍')).toBeInTheDocument();
expect(screen.queryByText('Aggressive')).toBeInTheDocument();
@@ -142,8 +165,8 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.0021 ETH')).toBeInTheDocument();
});
- it('should render priorityLevel high as "Swap suggested" for swaps', () => {
- renderComponent({
+ it('should render priorityLevel high as "Swap suggested" for swaps', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.high },
contextProps: { editGasMode: EditGasModes.swaps },
});
@@ -154,8 +177,8 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.0021 ETH')).toBeInTheDocument();
});
- it('should highlight option is priorityLevel is currently selected', () => {
- renderComponent({
+ it('should highlight option is priorityLevel is currently selected', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.high },
transactionProps: { userFeeLevel: 'high' },
});
@@ -164,8 +187,8 @@ describe('EditGasItem', () => {
).toHaveLength(1);
});
- it('should renders site gas estimate option for priorityLevel dappSuggested', () => {
- renderComponent({
+ it('should renders site gas estimate option for priorityLevel dappSuggested', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.dAppSuggested },
transactionProps: { dappSuggestedGasFees: ESTIMATE_MOCK },
});
@@ -177,15 +200,15 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.0000315 ETH')).toBeInTheDocument();
});
- it('should not renders site gas estimate option for priorityLevel dappSuggested if site does not provided gas estimates', () => {
- renderComponent({
+ it('should not renders site gas estimate option for priorityLevel dappSuggested if site does not provided gas estimates', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.dAppSuggested },
transactionProps: {},
});
expect(
screen.queryByRole('button', { name: 'dappSuggested' }),
).not.toBeInTheDocument();
- renderComponent({
+ await render({
componentProps: { priorityLevel: PriorityLevels.dAppSuggested },
transactionProps: { dappSuggestedGasFees: { gas: '0x59682f10' } },
});
@@ -194,8 +217,8 @@ describe('EditGasItem', () => {
).not.toBeInTheDocument();
});
- it('should renders advance gas estimate option for priorityLevel custom', () => {
- renderComponent({
+ it('should renders advance gas estimate option for priorityLevel custom', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.custom },
transactionProps: { userFeeLevel: 'high' },
});
@@ -208,8 +231,8 @@ describe('EditGasItem', () => {
expect(screen.queryByTitle('0.0021 ETH')).toBeInTheDocument();
});
- it('should renders +10% gas estimate option for priorityLevel minimum', () => {
- renderComponent({
+ it('should renders +10% gas estimate option for priorityLevel minimum', async () => {
+ await render({
componentProps: { priorityLevel: PriorityLevels.tenPercentIncreased },
transactionProps: {
userFeeLevel: 'tenPercentIncreased',
From 9f705f56ee68db36d730da1324decf479b305a1c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 15:33:50 -0800
Subject: [PATCH 41/74] lint
---
.../edit-gas-fee-button/edit-gas-fee-button.test.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
index b520f27b5373..4ad0a3d6c0a2 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-button/edit-gas-fee-button.test.js
@@ -55,12 +55,12 @@ const render = async ({ componentProps, contextProps } = {}) => {
await act(
async () =>
(result = renderWithProvider(
-
-
- ,
- store,
- )),
- );
+
+
+ ,
+ store,
+ )),
+ );
return result;
};
From f441ccfdb59e17a48db2cb6a5ba0490898372201 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 15:51:37 -0800
Subject: [PATCH 42/74] fix fee-details-component.test.js
---
.../fee-details-component.test.js | 46 +++++++++++++------
1 file changed, 33 insertions(+), 13 deletions(-)
diff --git a/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js b/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
index f8199f0d90ee..ee3fd6b7a2fa 100644
--- a/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
+++ b/ui/pages/confirmations/components/fee-details-component/fee-details-component.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import mockState from '../../../../../test/data/mock-state.json';
@@ -7,32 +7,44 @@ import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import FeeDetailsComponent from './fee-details-component';
jest.mock('../../../../store/actions', () => ({
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
}));
-const render = (state = {}) => {
+const render = async (state = {}) => {
const store = configureStore()({ ...mockState, ...state });
- return renderWithProvider(, store);
+
+ let result;
+
+ await act(
+ async () => (result = renderWithProvider(, store)),
+ );
+
+ return result;
};
describe('FeeDetailsComponent', () => {
- it('renders "Fee details"', () => {
- render();
+ it('renders "Fee details"', async () => {
+ await render();
expect(screen.queryByText('Fee details')).toBeInTheDocument();
});
- it('should expand when button is clicked', () => {
- render();
+ it('should expand when button is clicked', async () => {
+ await render();
expect(screen.queryByTitle('0 ETH')).not.toBeInTheDocument();
- screen.getByRole('button').click();
+ await act(async () => {
+ screen.getByRole('button').click();
+ });
expect(screen.queryByTitle('0 ETH')).toBeInTheDocument();
});
- it('should be displayed for even legacy network', () => {
- render({
+ it('should be displayed for even legacy network', async () => {
+ await render({
...mockState,
metamask: {
...mockState.metamask,
@@ -41,6 +53,14 @@ describe('FeeDetailsComponent', () => {
1559: false,
},
},
+ networksMetadata: {
+ goerli: {
+ EIPS: {
+ 1559: false,
+ },
+ status: 'available',
+ },
+ },
},
});
expect(screen.queryByText('Fee details')).toBeInTheDocument();
From adf57bf23fc25ac544288e7548c03a95e21124f3 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 16:13:33 -0800
Subject: [PATCH 43/74] Fix routes.component.test.js
---
ui/pages/routes/routes.component.test.js | 79 ++++++++++++++++--------
1 file changed, 52 insertions(+), 27 deletions(-)
diff --git a/ui/pages/routes/routes.component.test.js b/ui/pages/routes/routes.component.test.js
index fa2d5873138c..e684fedc32cb 100644
--- a/ui/pages/routes/routes.component.test.js
+++ b/ui/pages/routes/routes.component.test.js
@@ -1,6 +1,6 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
-import { fireEvent } from '@testing-library/react';
+import { act, fireEvent } from '@testing-library/react';
import { SEND_STAGES } from '../../ducks/send';
import { renderWithProvider } from '../../../test/jest';
@@ -28,10 +28,13 @@ jest.mock('webextension-polyfill', () => ({
jest.mock('../../store/actions', () => ({
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
showNetworkDropdown: () => mockShowNetworkDropdown,
hideNetworkDropdown: () => mockHideNetworkDropdown,
}));
@@ -64,31 +67,49 @@ jest.mock(
'../../components/app/metamask-template-renderer/safe-component-list',
);
+const render = async (route, state) => {
+ const store = configureMockStore()({
+ ...mockSendState,
+ ...state,
+ });
+
+ let result;
+
+ await act(
+ async () => (result = renderWithProvider(, store, route)),
+ );
+
+ return result;
+};
+
describe('Routes Component', () => {
useIsOriginalNativeTokenSymbol.mockImplementation(() => true);
+
afterEach(() => {
mockShowNetworkDropdown.mockClear();
mockHideNetworkDropdown.mockClear();
});
+
describe('render during send flow', () => {
- it('should render with network change disabled while adding recipient for send flow', () => {
- const store = configureMockStore()({
- ...mockSendState,
+ it('should render with network change disabled while adding recipient for send flow', async () => {
+ const state = {
send: {
...mockSendState.send,
stage: SEND_STAGES.ADD_RECIPIENT,
},
- });
+ };
- const { getByTestId } = renderWithProvider(, store, ['/send']);
+ const { getByTestId } = await render(['/send'], state);
const networkDisplay = getByTestId('network-display');
- fireEvent.click(networkDisplay);
+ await act(async () => {
+ fireEvent.click(networkDisplay);
+ });
expect(mockShowNetworkDropdown).not.toHaveBeenCalled();
});
- it('should render with network change disabled while user is in send page', () => {
- const store = configureMockStore()({
- ...mockSendState,
+
+ it('should render with network change disabled while user is in send page', async () => {
+ const state = {
metamask: {
...mockSendState.metamask,
providerConfig: {
@@ -97,16 +118,18 @@ describe('Routes Component', () => {
type: NETWORK_TYPES.GOERLI,
},
},
- });
- const { getByTestId } = renderWithProvider(, store, ['/send']);
+ };
+ const { getByTestId } = await render(['/send'], state);
const networkDisplay = getByTestId('network-display');
- fireEvent.click(networkDisplay);
+ await act(async () => {
+ fireEvent.click(networkDisplay);
+ });
expect(mockShowNetworkDropdown).not.toHaveBeenCalled();
});
- it('should render with network change disabled while editing a send transaction', () => {
- const store = configureMockStore()({
- ...mockSendState,
+
+ it('should render with network change disabled while editing a send transaction', async () => {
+ const state = {
send: {
...mockSendState.send,
stage: SEND_STAGES.EDIT,
@@ -119,16 +142,18 @@ describe('Routes Component', () => {
type: NETWORK_TYPES.GOERLI,
},
},
- });
- const { getByTestId } = renderWithProvider(, store, ['/send']);
+ };
+ const { getByTestId } = await render(['/send'], state);
const networkDisplay = getByTestId('network-display');
- fireEvent.click(networkDisplay);
+ await act(async () => {
+ fireEvent.click(networkDisplay);
+ });
expect(mockShowNetworkDropdown).not.toHaveBeenCalled();
});
- it('should render when send transaction is not active', () => {
- const store = configureMockStore()({
- ...mockSendState,
+
+ it('should render when send transaction is not active', async () => {
+ const state = {
metamask: {
...mockSendState.metamask,
swapsState: {
@@ -151,8 +176,8 @@ describe('Routes Component', () => {
localeMessages: {
currentLocale: 'en',
},
- });
- const { getByTestId } = renderWithProvider(, store);
+ };
+ const { getByTestId } = await render(undefined, state);
expect(getByTestId('account-menu-icon')).not.toBeDisabled();
});
});
From b4d3743980790474a6ab7ce029721cd52750ab2b Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 16:13:45 -0800
Subject: [PATCH 44/74] update mock-send-state to silence required props errors
---
test/data/mock-send-state.json | 38 ++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/test/data/mock-send-state.json b/test/data/mock-send-state.json
index 772d806174f2..f52cc5f93cf6 100644
--- a/test/data/mock-send-state.json
+++ b/test/data/mock-send-state.json
@@ -14,6 +14,7 @@
"importNftsModal": { "open": false },
"gasIsLoading": false,
"isLoading": false,
+ "importTokensModalOpen": false,
"modal": {
"open": false,
"modalState": {
@@ -24,6 +25,9 @@
"name": null
}
},
+ "showIpfsModalOpen": false,
+ "showKeyringRemovalSnapModal": false,
+ "showWhatsNewPopup": false,
"warning": null,
"alertOpen": false
},
@@ -90,6 +94,38 @@
"priorityFeeTrend": "down",
"networkCongestion": 0.90625
},
+ "gasFeeEstimatesByChainId": {
+ "0x5": {
+ "gasEstimateType": "fee-market",
+ "gasFeeEstimates": {
+ "low": {
+ "minWaitTimeEstimate": 180000,
+ "maxWaitTimeEstimate": 300000,
+ "suggestedMaxPriorityFeePerGas": "3",
+ "suggestedMaxFeePerGas": "53"
+ },
+ "medium": {
+ "minWaitTimeEstimate": 15000,
+ "maxWaitTimeEstimate": 60000,
+ "suggestedMaxPriorityFeePerGas": "7",
+ "suggestedMaxFeePerGas": "70"
+ },
+ "high": {
+ "minWaitTimeEstimate": 0,
+ "maxWaitTimeEstimate": 15000,
+ "suggestedMaxPriorityFeePerGas": "10",
+ "suggestedMaxFeePerGas": "100"
+ },
+ "estimatedBaseFee": "50",
+ "historicalBaseFeeRange": ["28.533098435", "70.351148354"],
+ "baseFeeTrend": "up",
+ "latestPriorityFeeRange": ["1", "40"],
+ "historicalPriorityFeeRange": ["0.1458417", "700.156384646"],
+ "priorityFeeTrend": "down",
+ "networkCongestion": 0.90625
+ }
+ }
+ },
"snaps": [{}],
"preferences": {
"hideZeroBalanceTokens": false,
@@ -97,6 +133,7 @@
"showTestNetworks": true,
"useNativeCurrencyAsPrimaryCurrency": true
},
+ "seedPhraseBackedUp": null,
"ensResolutionsByAddress": {},
"isAccountMenuOpen": false,
"isUnlocked": true,
@@ -217,6 +254,7 @@
"address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"id": "cf8dace4-9439-4bd4-b3a8-88c821c8fcb3",
"metadata": {
+ "name": "Test Account",
"keyring": {
"type": "HD Key Tree"
}
From e03e5391598e7c698ff094f916f540bd3732f7c7 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 16:24:54 -0800
Subject: [PATCH 45/74] fix edit-gas-fee-icon.test.js
---
.../edit-gas-fee-icon.test.js | 33 ++++++++++++-------
.../confirmations/hooks/useGasFeeInputs.js | 2 +-
.../send-content.component.test.js.snap | 2 ++
3 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
index 4f86824e09af..97f51d65e605 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { fireEvent, screen } from '@testing-library/react';
+import { act, fireEvent, screen } from '@testing-library/react';
import { renderWithProvider } from '../../../../../test/jest';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
import configureStore from '../../../../store/store';
@@ -7,11 +7,13 @@ import mockState from '../../../../../test/data/mock-state.json';
import EditGasFeeIcon from './edit-gas-fee-icon';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
createTransactionEventFragment: jest.fn(),
}));
@@ -24,27 +26,34 @@ jest.mock('../../../../contexts/transaction-modal', () => ({
}),
}));
-const render = () => {
+const render = async () => {
const store = configureStore({
metamask: {
...mockState.metamask,
},
});
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
,
- store,
- );
+ store,
+ )),
+ );
+
+ return result;
};
describe('EditGasFeeIcon', () => {
- it('should render edit icon', () => {
- render();
+ it('should render edit icon', async () => {
+ await render();
const iconButton = screen.getByTestId('edit-gas-fee-icon');
expect(iconButton).toBeInTheDocument();
- fireEvent.click(iconButton);
+ await act(async () => {fireEvent.click(iconButton); })
expect(mockOpenModalFn).toHaveBeenCalledTimes(1);
});
});
diff --git a/ui/pages/confirmations/hooks/useGasFeeInputs.js b/ui/pages/confirmations/hooks/useGasFeeInputs.js
index 4bbf1ee903c7..27a60ad5f043 100644
--- a/ui/pages/confirmations/hooks/useGasFeeInputs.js
+++ b/ui/pages/confirmations/hooks/useGasFeeInputs.js
@@ -130,7 +130,7 @@ export function useGasFeeInputs(
gasFeeEstimates,
isGasEstimatesLoading,
isNetworkBusy,
- } = useGasFeeEstimates(transaction.networkClientId);
+ } = useGasFeeEstimates(transaction?.networkClientId);
const userPrefersAdvancedGas = useSelector(getAdvancedInlineGasShown);
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
index 55fc897b62f5..cb4204841623 100644
--- a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
+++ b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
@@ -287,3 +287,5 @@ exports[`SendContent Component render should match snapshot 1`] = `
`;
+
+exports[`SendContent Component render should match snapshot 2`] = ``;
From 4c5a52dd21113b0910bc6308ec0c3c9bd39754aa Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 16:27:48 -0800
Subject: [PATCH 46/74] fix edit-gas-tooltip.test.js
---
ui/helpers/utils/gas.js | 2 +-
.../edit-gas-tooltip/edit-gas-tooltip.test.js | 38 ++++++++++++-------
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/ui/helpers/utils/gas.js b/ui/helpers/utils/gas.js
index d5e7633078ca..65103972f3fb 100644
--- a/ui/helpers/utils/gas.js
+++ b/ui/helpers/utils/gas.js
@@ -25,7 +25,7 @@ export const gasEstimateGreaterThanGasUsedPlusTenPercent = (
);
const maxFeePerGasFromEstimate =
- gasFeeEstimates[estimate]?.suggestedMaxFeePerGas;
+ gasFeeEstimates?.[estimate]?.suggestedMaxFeePerGas;
return bnGreaterThan(maxFeePerGasFromEstimate, maxFeePerGasInTransaction);
};
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
index 6be40bea5fd9..79922a8d1d6a 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
@@ -3,13 +3,16 @@ import configureStore from '../../../../../store/store';
import { renderWithProvider } from '../../../../../../test/jest';
import { GasFeeContextProvider } from '../../../../../contexts/gasFee';
import EditGasToolTip from './edit-gas-tooltip';
+import { act } from '@testing-library/react';
jest.mock('../../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
getGasFeeTimeEstimate: jest
.fn()
.mockImplementation(() => Promise.resolve('unknown')),
@@ -30,7 +33,7 @@ const HIGH_GAS_OPTION = {
maxPriorityFeePerGas: '2',
};
-const renderComponent = (componentProps) => {
+const render = async (componentProps) => {
const mockStore = {
metamask: {
providerConfig: {},
@@ -57,17 +60,24 @@ const renderComponent = (componentProps) => {
const store = configureStore(mockStore);
- return renderWithProvider(
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
,
- store,
- );
+ store,
+ )),
+ );
+
+ return result;
};
describe('EditGasToolTip', () => {
- it('should render correct values for priorityLevel low', () => {
- const { queryByText } = renderComponent({
+ it('should render correct values for priorityLevel low', async () => {
+ const { queryByText } = await render({
priorityLevel: 'low',
...LOW_GAS_OPTION,
});
@@ -77,8 +87,8 @@ describe('EditGasToolTip', () => {
expect(queryByText('21000')).toBeInTheDocument();
});
- it('should render correct values for priorityLevel medium', () => {
- const { queryByText } = renderComponent({
+ it('should render correct values for priorityLevel medium', async () => {
+ const { queryByText } = await render({
priorityLevel: 'medium',
...MEDIUM_GAS_OPTION,
});
@@ -87,8 +97,8 @@ describe('EditGasToolTip', () => {
expect(queryByText('21000')).toBeInTheDocument();
});
- it('should render correct values for priorityLevel high', () => {
- const { queryByText } = renderComponent({
+ it('should render correct values for priorityLevel high', async () => {
+ const { queryByText } = await render({
priorityLevel: 'high',
...HIGH_GAS_OPTION,
});
From 5b9f557bab946f5c02ecfc7eeeb18d992201b4ee Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Wed, 21 Feb 2024 16:29:42 -0800
Subject: [PATCH 47/74] lint
---
.../edit-gas-fee-icon/edit-gas-fee-icon.test.js | 16 +++++++++-------
.../edit-gas-tooltip/edit-gas-tooltip.test.js | 14 +++++++-------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
index 97f51d65e605..1781314edbc6 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-icon/edit-gas-fee-icon.test.js
@@ -38,14 +38,14 @@ const render = async () => {
await act(
async () =>
(result = renderWithProvider(
-
-
- ,
+
+
+ ,
store,
- )),
- );
+ )),
+ );
- return result;
+ return result;
};
describe('EditGasFeeIcon', () => {
@@ -53,7 +53,9 @@ describe('EditGasFeeIcon', () => {
await render();
const iconButton = screen.getByTestId('edit-gas-fee-icon');
expect(iconButton).toBeInTheDocument();
- await act(async () => {fireEvent.click(iconButton); })
+ await act(async () => {
+ fireEvent.click(iconButton);
+ });
expect(mockOpenModalFn).toHaveBeenCalledTimes(1);
});
});
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
index 79922a8d1d6a..d0963f87269c 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-tooltip/edit-gas-tooltip.test.js
@@ -1,9 +1,9 @@
import React from 'react';
+import { act } from '@testing-library/react';
import configureStore from '../../../../../store/store';
import { renderWithProvider } from '../../../../../../test/jest';
import { GasFeeContextProvider } from '../../../../../contexts/gasFee';
import EditGasToolTip from './edit-gas-tooltip';
-import { act } from '@testing-library/react';
jest.mock('../../../../../store/actions', () => ({
gasFeeStartPollingByNetworkClientId: jest
@@ -65,14 +65,14 @@ const render = async (componentProps) => {
await act(
async () =>
(result = renderWithProvider(
-
-
- ,
+
+
+ ,
store,
- )),
- );
+ )),
+ );
- return result;
+ return result;
};
describe('EditGasToolTip', () => {
From aa0580d5acc10dce23a2a59eb8c1d3661e792a3b Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 10:24:08 -0500
Subject: [PATCH 48/74] Fixed token allowance tests
---
.../__snapshots__/blockaid-banner-alert.test.js.snap | 12 ++++++------
.../token-allowance/token-allowance.test.js | 9 +++++++++
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap b/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
index 04b2a4843aab..ab0c4a9a1c89 100644
--- a/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
+++ b/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
@@ -51,7 +51,7 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertRespo
Something doesn't look right?
@@ -144,7 +144,7 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
Something doesn't look right?
@@ -237,7 +237,7 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
Something doesn't look right?
@@ -331,7 +331,7 @@ exports[`Blockaid Banner Alert should render details section even when features
Something doesn't look right?
@@ -438,7 +438,7 @@ exports[`Blockaid Banner Alert should render details when provided 1`] = `
Something doesn't look right?
@@ -533,7 +533,7 @@ exports[`Blockaid Banner Alert should render link to report url 1`] = `
Something doesn't look right?
diff --git a/ui/pages/confirmations/token-allowance/token-allowance.test.js b/ui/pages/confirmations/token-allowance/token-allowance.test.js
index 6a8db32b1a7a..7b1eadb5274a 100644
--- a/ui/pages/confirmations/token-allowance/token-allowance.test.js
+++ b/ui/pages/confirmations/token-allowance/token-allowance.test.js
@@ -108,11 +108,20 @@ const mockedState = jest.mocked(state);
jest.mock('../../../store/actions', () => ({
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest
.fn()
.mockImplementation(() => Promise.resolve()),
addPollingTokenToAppState: jest.fn(),
removePollingTokenFromAppState: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
updateTransactionGasFees: () => ({ type: 'UPDATE_TRANSACTION_PARAMS' }),
updatePreviousGasParams: () => ({ type: 'UPDATE_TRANSACTION_PARAMS' }),
createTransactionEventFragment: jest.fn(),
From eb38f68e502d88b5bd63c7701725ef7ad1fd2ee0 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 11:38:15 -0500
Subject: [PATCH 49/74] Fixed action mocks
---
.../edit-gas-fee-popover.test.js | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
index 481234e8ce03..dda3eeb5f13a 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
@@ -18,6 +18,18 @@ import {
import EditGasFeePopover from './edit-gas-fee-popover';
jest.mock('../../../../store/actions', () => ({
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getGasFeeEstimatesAndStartPolling: jest
+ .fn()
+ .mockImplementation(() => Promise.resolve()),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest
.fn()
From b66fc18785a6012928c5ad1d7c0442474fb7d2f3 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Thu, 22 Feb 2024 10:29:38 -0800
Subject: [PATCH 50/74] fix confirm-gas-display.test
---
.../confirm-gas-display.test.js | 53 ++++++++++++-------
1 file changed, 35 insertions(+), 18 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
index deecbf007783..cad2e6264257 100644
--- a/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
+++ b/ui/pages/confirmations/components/confirm-gas-display/confirm-gas-display.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import { NetworkType } from '@metamask/controller-utils';
import { NetworkStatus } from '@metamask/network-controller';
@@ -13,15 +13,17 @@ import { GasFeeContextProvider } from '../../../../contexts/gasFee';
import ConfirmGasDisplay from './confirm-gas-display';
jest.mock('../../../../store/actions', () => ({
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
}));
-const render = ({ transactionProp = {}, contextProps = {} } = {}) => {
+const render = async ({ transactionProp = {}, contextProps = {} } = {}) => {
const store = configureStore({
...mockState,
...contextProps,
@@ -38,24 +40,39 @@ const render = ({ transactionProp = {}, contextProps = {} } = {}) => {
},
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
- return renderWithProvider(
-
-
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('ConfirmGasDisplay', () => {
it('should match snapshot', async () => {
- const { container } = render();
+ const { container } = await render();
expect(container).toMatchSnapshot();
});
- it('should render gas display labels for EIP1559 transcations', () => {
- render({
+ it('should render gas display labels for EIP1559 transcations', async () => {
+ await render({
transactionProp: {
txParams: {
gas: '0x5208',
@@ -69,13 +86,13 @@ describe('ConfirmGasDisplay', () => {
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
});
- it('should render gas display labels for legacy transcations', () => {
- render({
+ it('should render gas display labels for legacy transcations', async () => {
+ await render({
contextProps: {
metamask: {
- selectedNetworkClientId: NetworkType.mainnet,
+ selectedNetworkClientId: NetworkType.goerli,
networksMetadata: {
- [NetworkType.mainnet]: {
+ [NetworkType.goerli]: {
EIPS: {
1559: false,
},
From a2ac2ff4d8608a756f6dfe28eaa979182d72e701 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Thu, 22 Feb 2024 12:59:11 -0800
Subject: [PATCH 51/74] fix send.test.js
---
.../multichain/pages/send/send.test.js | 294 ++++++++++--------
1 file changed, 160 insertions(+), 134 deletions(-)
diff --git a/ui/components/multichain/pages/send/send.test.js b/ui/components/multichain/pages/send/send.test.js
index d6c1330206fc..b1aafd03436f 100644
--- a/ui/components/multichain/pages/send/send.test.js
+++ b/ui/components/multichain/pages/send/send.test.js
@@ -3,6 +3,7 @@ import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import { NetworkType } from '@metamask/controller-utils';
import { EthAccountType, EthMethod } from '@metamask/keyring-api';
+import { act } from '@testing-library/react';
import mockState from '../../../../../test/data/mock-state.json';
import {
renderWithProvider,
@@ -45,12 +46,13 @@ jest.mock('../../../../store/actions.ts', () => {
const originalModule = jest.requireActual('../../../../store/actions.ts');
return {
...originalModule,
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
+ gasFeeStartPollingByNetworkClientId: jest
.fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
- removePollingTokenFromAppState: jest.fn(),
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue({ chainId: '0x5' }),
getTokenSymbol: jest.fn().mockResolvedValue('ETH'),
getGasFeeTimeEstimate: jest
.fn()
@@ -75,122 +77,150 @@ jest.mock('../../../../ducks/send/send', () => {
};
});
-describe('SendPage', () => {
- describe('render and initialization', () => {
- const middleware = [thunk];
-
- const baseStore = {
- send: INITIAL_SEND_STATE_FOR_EXISTING_DRAFT,
- DNS: domainInitialState,
- gas: {
- customData: { limit: null, price: null },
+const baseStore = {
+ send: INITIAL_SEND_STATE_FOR_EXISTING_DRAFT,
+ DNS: domainInitialState,
+ gas: {
+ customData: { limit: null, price: null },
+ },
+ history: { mostRecentOverviewPage: 'activity' },
+ confirmTransaction: {
+ txData: {
+ id: 1,
+ txParams: {
+ value: 'oldTxValue',
},
- history: { mostRecentOverviewPage: 'activity' },
- metamask: {
- transactions: [
- {
- id: 1,
- txParams: {
- value: 'oldTxValue',
- },
- },
- ],
- currencyRates: {
- ETH: {
- conversionDate: 1620710825.03,
- conversionRate: 3910.28,
- usdConversionRate: 3910.28,
- },
+ },
+ },
+ metamask: {
+ transactions: [
+ {
+ id: 1,
+ txParams: {
+ value: 'oldTxValue',
},
- gasEstimateType: GasEstimateTypes.legacy,
+ },
+ ],
+
+ currencyRates: {
+ ETH: {
+ conversionDate: 1620710825.03,
+ conversionRate: 3910.28,
+ usdConversionRate: 3910.28,
+ },
+ },
+ gasEstimateType: GasEstimateTypes.legacy,
+ gasFeeEstimates: {
+ low: '0',
+ medium: '1',
+ fast: '2',
+ },
+ gasFeeEstimatesByChainId: {
+ '0x5': {
gasFeeEstimates: {
low: '0',
medium: '1',
fast: '2',
},
- selectedAddress: '0x0',
- internalAccounts: {
- accounts: {
- 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3': {
- address: '0x0',
- id: 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3',
- metadata: {
- name: 'Test Account',
- keyring: {
- type: 'HD Key Tree',
- },
- },
- options: {},
- methods: [...Object.values(EthMethod)],
- type: EthAccountType.Eoa,
+ gasEstimateType: GasEstimateTypes.legacy,
+ },
+ },
+ selectedAddress: '0x0',
+ internalAccounts: {
+ accounts: {
+ 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3': {
+ address: '0x0',
+ id: 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3',
+ metadata: {
+ name: 'Test Account',
+ keyring: {
+ type: 'HD Key Tree',
},
},
- selectedAccount: 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3',
- },
- keyrings: [
- {
- type: KeyringType.hdKeyTree,
- accounts: ['0x0'],
- },
- ],
- selectedNetworkClientId: NetworkType.mainnet,
- networksMetadata: {
- [NetworkType.mainnet]: {
- EIPS: {},
- status: 'available',
- },
- },
- tokens: [],
- preferences: {
- useNativeCurrencyAsPrimaryCurrency: false,
- },
- currentCurrency: 'USD',
- providerConfig: {
- chainId: CHAIN_IDS.GOERLI,
- nickname: GOERLI_DISPLAY_NAME,
- },
- nativeCurrency: 'ETH',
- featureFlags: {
- sendHexData: false,
- },
- addressBook: {
- [CHAIN_IDS.GOERLI]: [],
- },
- cachedBalances: {
- [CHAIN_IDS.GOERLI]: {},
- },
- accounts: {
- '0x0': { balance: '0x0', address: '0x0', name: 'Account 1' },
- },
- identities: { '0x0': { address: '0x0' } },
- tokenAddress: '0x32e6c34cd57087abbd59b5a4aecc4cb495924356',
- tokenList: {
- '0x32e6c34cd57087abbd59b5a4aecc4cb495924356': {
- name: 'BitBase',
- symbol: 'BTBS',
- decimals: 18,
- address: '0x32E6C34Cd57087aBBD59B5A4AECC4cB495924356',
- iconUrl: 'BTBS.svg',
- occurrences: null,
- },
- '0x3fa400483487a489ec9b1db29c4129063eec4654': {
- name: 'Cryptokek.com',
- symbol: 'KEK',
- decimals: 18,
- address: '0x3fa400483487A489EC9b1dB29C4129063EEC4654',
- iconUrl: 'cryptokek.svg',
- occurrences: null,
- },
+ options: {},
+ methods: [...Object.values(EthMethod)],
+ type: EthAccountType.Eoa,
},
},
- appState: {
- sendInputCurrencySwitched: false,
+ selectedAccount: 'cf8dace4-9439-4bd4-b3a8-88c821c8fcb3',
+ },
+ keyrings: [
+ {
+ type: KeyringType.hdKeyTree,
+ accounts: ['0x0'],
},
- };
+ ],
+ selectedNetworkClientId: NetworkType.goerli,
+ networksMetadata: {
+ [NetworkType.goerli]: {
+ EIPS: {},
+ status: 'available',
+ },
+ },
+ tokens: [],
+ preferences: {
+ useNativeCurrencyAsPrimaryCurrency: false,
+ },
+ currentCurrency: 'USD',
+ providerConfig: {
+ chainId: CHAIN_IDS.GOERLI,
+ nickname: GOERLI_DISPLAY_NAME,
+ },
+ nativeCurrency: 'ETH',
+ featureFlags: {
+ sendHexData: false,
+ },
+ addressBook: {
+ [CHAIN_IDS.GOERLI]: [],
+ },
+ cachedBalances: {
+ [CHAIN_IDS.GOERLI]: {},
+ },
+ accounts: {
+ '0x0': { balance: '0x0', address: '0x0', name: 'Account 1' },
+ },
+ identities: { '0x0': { address: '0x0' } },
+ tokenAddress: '0x32e6c34cd57087abbd59b5a4aecc4cb495924356',
+ tokenList: {
+ '0x32e6c34cd57087abbd59b5a4aecc4cb495924356': {
+ name: 'BitBase',
+ symbol: 'BTBS',
+ decimals: 18,
+ address: '0x32E6C34Cd57087aBBD59B5A4AECC4cB495924356',
+ iconUrl: 'BTBS.svg',
+ occurrences: null,
+ },
+ '0x3fa400483487a489ec9b1db29c4129063eec4654': {
+ name: 'Cryptokek.com',
+ symbol: 'KEK',
+ decimals: 18,
+ address: '0x3fa400483487A489EC9b1dB29C4129063EEC4654',
+ iconUrl: 'cryptokek.svg',
+ occurrences: null,
+ },
+ },
+ },
+ appState: {
+ sendInputCurrencySwitched: false,
+ },
+};
+
+const render = async (state) => {
+ const middleware = [thunk];
+
+ const store = configureMockStore(middleware)(state);
- it('should initialize the ENS slice on render', () => {
- const store = configureMockStore(middleware)(baseStore);
- renderWithProvider(, store);
+ let result;
+
+ await act(async () => (result = renderWithProvider(, store)));
+
+ return { store, result };
+};
+
+describe('SendPage', () => {
+ describe('render and initialization', () => {
+ it('should initialize the ENS slice on render', async () => {
+ const { store } = await render(baseStore);
const actions = store.getActions();
expect(actions).toStrictEqual(
expect.arrayContaining([
@@ -201,17 +231,17 @@ describe('SendPage', () => {
);
});
- it('should render correctly even when a draftTransaction does not exist', () => {
- const modifiedStore = {
+ it('should render correctly even when a draftTransaction does not exist', async () => {
+ const modifiedState = {
...baseStore,
send: {
...baseStore.send,
currentTransactionUUID: null,
},
};
- const store = configureMockStore(middleware)(modifiedStore);
- const { container, getByTestId, getByPlaceholderText } =
- renderWithProvider(, store);
+ const {
+ result: { container, getByTestId, getByPlaceholderText },
+ } = await render(modifiedState);
// Ensure that the send flow renders on the add recipient screen when
// there is no draft transaction.
@@ -229,20 +259,22 @@ describe('SendPage', () => {
});
describe('footer buttons', () => {
- const mockStore = configureMockStore([thunk])(mockState);
-
describe('onCancel', () => {
- it('should call reset send state and route to recent page without cancelling tx', () => {
- const { queryByText } = renderWithProvider(, mockStore);
+ it('should call reset send state and route to recent page without cancelling tx', async () => {
+ const {
+ result: { queryByText },
+ } = await render(mockState);
const cancelText = queryByText('Cancel');
- fireEvent.click(cancelText);
+ await act(async () => {
+ fireEvent.click(cancelText);
+ });
expect(mockResetSendState).toHaveBeenCalled();
expect(mockCancelTx).not.toHaveBeenCalled();
});
- it('should reject/cancel tx when coming from tx editing and route to index', () => {
+ it('should reject/cancel tx when coming from tx editing and route to index', async () => {
const sendDataState = {
...mockState,
send: {
@@ -264,15 +296,14 @@ describe('SendPage', () => {
},
};
- const sendStateStore = configureMockStore([thunk])(sendDataState);
-
- const { queryByText } = renderWithProvider(
- ,
- sendStateStore,
- );
+ const {
+ result: { queryByText },
+ } = await render(sendDataState);
const rejectText = queryByText('Reject');
- fireEvent.click(rejectText);
+ await act(async () => {
+ fireEvent.click(rejectText);
+ });
expect(mockResetSendState).toHaveBeenCalled();
expect(mockCancelTx).toHaveBeenCalled();
@@ -310,14 +341,9 @@ describe('SendPage', () => {
},
};
- const sendStateStore = configureMockStore([thunk])(
- knownRecipientWarningState,
- );
-
- const { queryByTestId } = renderWithProvider(
- ,
- sendStateStore,
- );
+ const {
+ result: { queryByTestId },
+ } = await render(knownRecipientWarningState);
const sendWarning = queryByTestId('send-warning');
await waitFor(() => {
From 13d8effa7ba8c29e6ef2a36623ae56b29f749be1 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 16:10:45 -0500
Subject: [PATCH 52/74] Updated snapshot for confirm-send-ether.test.js
---
.../confirm-send-ether.test.js.snap | 17 -----------------
.../confirm-send-ether.test.js | 9 +++++++++
2 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap b/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
index 5a93d6e98cf0..36086d620ab8 100644
--- a/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
+++ b/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
@@ -316,23 +316,6 @@ exports[`ConfirmSendEther should render correct information for for confirm send
-
-
-
-
- Network is busy. Gas prices are high and estimates are less accurate.
-
-
-
diff --git a/ui/pages/confirmations/confirm-send-ether/confirm-send-ether.test.js b/ui/pages/confirmations/confirm-send-ether/confirm-send-ether.test.js
index b9baedf2d4b4..a73e19aaffd8 100644
--- a/ui/pages/confirmations/confirm-send-ether/confirm-send-ether.test.js
+++ b/ui/pages/confirmations/confirm-send-ether/confirm-send-ether.test.js
@@ -7,6 +7,15 @@ import configureStore from '../../../store/store';
import ConfirmSendEther from './confirm-send-ether';
setBackgroundConnection({
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
getGasFeeTimeEstimate: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest.fn(),
promisifiedBackground: jest.fn(),
From 9892d45290670bef575ab5f6e223e24ad80f9d42 Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 16:41:05 -0500
Subject: [PATCH 53/74] Fixed action mocks for confirm-transaction-base.test.js
---
.../confirm-transaction-base.test.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
index 04ee225a6d79..ef31ce395d9a 100644
--- a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
+++ b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
@@ -32,6 +32,15 @@ import ConfirmTransactionBase from './confirm-transaction-base.container';
const middleware = [thunk];
setBackgroundConnection({
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
getGasFeeTimeEstimate: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest.fn(),
promisifiedBackground: jest.fn(),
From cde5e7ad02a745fd0d9a4e270299ce5c83ca4d5d Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 16:43:53 -0500
Subject: [PATCH 54/74] Fixed action mocks for
advanced-gas-fee-input-subtext.test.js
---
.../advanced-gas-fee-input-subtext.test.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
index 80e4d08f5ec8..8eab525cf4a8 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
@@ -4,6 +4,15 @@ import configureStore from '../../../../../store/store';
import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext';
jest.mock('../../../../../store/actions', () => ({
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest.fn().mockResolvedValue(null),
addPollingTokenToAppState: jest.fn(),
From ad7e7563e67201c702c2680f538043de0f5bddcf Mon Sep 17 00:00:00 2001
From: Shane Jonas
Date: Thu, 22 Feb 2024 16:46:13 -0500
Subject: [PATCH 55/74] Fixed action mocks for cancel-speedup-popover.test.js
---
.../cancel-speedup-popover.test.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
index 1512b8992a09..54de42f40283 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
@@ -48,6 +48,15 @@ const MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_HEX_WEI =
MOCK_SUGGESTED_MEDIUM_MAXFEEPERGAS_BN_WEI.toString(16);
jest.mock('../../../store/actions', () => ({
+ gasFeeStartPollingByNetworkClientId: jest
+ .fn()
+ .mockResolvedValue('pollingToken'),
+ gasFeeStopPollingByPollingToken: jest.fn(),
+ getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
+ Promise.resolve({
+ chainId: '0x5',
+ }),
+ ),
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
getGasFeeEstimatesAndStartPolling: jest
From 013eebb2aaa77940dd171919458391d33b6bdcc6 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Thu, 22 Feb 2024 14:51:48 -0800
Subject: [PATCH 56/74] fix confirm-transaction-base.test.js
---
.../confirm-transaction-base.test.js | 408 ++++++++++--------
1 file changed, 226 insertions(+), 182 deletions(-)
diff --git a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
index ef31ce395d9a..a0695e200e08 100644
--- a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
+++ b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.test.js
@@ -209,43 +209,87 @@ const baseStore = {
},
};
-const mockedStore = jest.mocked(baseStore);
-
-const mockedStoreWithConfirmTxParams = (_mockTxParams = mockTxParams) => {
- mockedStore.metamask.transactions[0].txParams = { ..._mockTxParams };
- mockedStore.confirmTransaction.txData.txParams = { ..._mockTxParams };
+const mockedStoreWithConfirmTxParams = (
+ store,
+ _mockTxParams = mockTxParams,
+) => {
+ const [firstTx, ...restTxs] = store.metamask.transactions;
+
+ return {
+ ...store,
+ metamask: {
+ ...store.metamask,
+ transactions: [
+ {
+ ...firstTx,
+ txParams: {
+ ..._mockTxParams,
+ },
+ },
+ ...restTxs,
+ ],
+ },
+ confirmTransaction: {
+ ...store.confirmTransaction,
+ txData: {
+ ...store.confirmTransaction.txData,
+ txParams: {
+ ..._mockTxParams,
+ },
+ },
+ },
+ };
};
const sendToRecipientSelector =
'.sender-to-recipient__party--recipient .sender-to-recipient__name';
+const render = async ({ props, state } = {}) => {
+ const store = configureMockStore(middleware)({
+ ...baseStore,
+ ...state,
+ });
+
+ const componentProps = {
+ actionKey: 'confirm',
+ ...props,
+ };
+
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+ ,
+ store,
+ )),
+ );
+
+ return result;
+};
+
describe('Confirm Transaction Base', () => {
- it('should match snapshot', () => {
- const store = configureMockStore(middleware)(baseStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ it('should match snapshot', async () => {
+ const { container } = await render();
expect(container).toMatchSnapshot();
});
- it('should not contain L1 L2 fee details for chains that are not optimism', () => {
- const store = configureMockStore(middleware)(baseStore);
- const { queryByText } = renderWithProvider(
- ,
- store,
- );
+ it('should not contain L1 L2 fee details for chains that are not optimism', async () => {
+ const { queryByText } = await render();
+
expect(queryByText('Layer 1 fees')).not.toBeInTheDocument();
expect(queryByText('Layer 2 gas fee')).not.toBeInTheDocument();
});
- it('should render only total fee details if simulation fails', () => {
- mockedStore.send.hasSimulationError = true;
- const store = configureMockStore(middleware)(mockedStore);
- const { queryByText } = renderWithProvider(
- ,
- store,
- );
+ it('should render only total fee details if simulation fails', async () => {
+ const state = {
+ send: {
+ ...baseStore.send,
+ hasSimulationError: true,
+ },
+ };
+
+ const { queryByText } = await render({ state });
expect(queryByText('Total')).toBeInTheDocument();
expect(queryByText('Amount + gas fee')).toBeInTheDocument();
@@ -253,19 +297,18 @@ describe('Confirm Transaction Base', () => {
expect(queryByText('Estimated fee')).not.toBeInTheDocument();
});
- it('renders blockaid security alert if recipient is a malicious address', () => {
- const newMockedStore = {
- ...mockedStore,
+ it('renders blockaid security alert if recipient is a malicious address', async () => {
+ const state = {
send: {
- ...mockedStore.send,
+ ...baseStore.send,
hasSimulationError: false,
},
confirmTransaction: {
- ...mockedStore.confirmTransaction,
+ ...baseStore.confirmTransaction,
txData: {
- ...mockedStore.confirmTransaction.txData,
+ ...baseStore.confirmTransaction.txData,
txParams: {
- ...mockedStore.confirmTransaction.txData.txParams,
+ ...baseStore.confirmTransaction.txData.txParams,
to: mockMaliciousToAddress,
},
securityAlertResponse: {
@@ -277,12 +320,7 @@ describe('Confirm Transaction Base', () => {
},
};
- const store = configureMockStore(middleware)(newMockedStore);
-
- const { getByTestId } = renderWithProvider(
- ,
- store,
- );
+ const { getByTestId } = await render({ state });
const securityProviderBanner = getByTestId(
'security-provider-banner-alert',
@@ -290,63 +328,74 @@ describe('Confirm Transaction Base', () => {
expect(securityProviderBanner).toBeInTheDocument();
});
- it('should contain L1 L2 fee details for optimism', () => {
- mockedStore.metamask.providerConfig.chainId = CHAIN_IDS.OPTIMISM;
- mockedStore.confirmTransaction.txData.chainId = CHAIN_IDS.OPTIMISM;
- const store = configureMockStore(middleware)(mockedStore);
- const { queryByText } = renderWithProvider(
- ,
- store,
- );
+ it('should contain L1 L2 fee details for optimism', async () => {
+ const state = {
+ metamask: {
+ ...baseStore.metamask,
+ providerConfig: {
+ ...baseStore.metamask.providerConfig,
+ chainId: CHAIN_IDS.OPTIMISM,
+ },
+ },
+ confirmTransaction: {
+ ...baseStore.confirmTransaction,
+ txData: {
+ ...baseStore.confirmTransaction.txData,
+ chainId: CHAIN_IDS.OPTIMISM,
+ },
+ },
+ };
+
+ const { queryByText } = await render({ state });
+
expect(queryByText('Layer 1 fees')).toBeInTheDocument();
expect(queryByText('Layer 2 gas fee')).toBeInTheDocument();
});
- it('should render NoteToTrader when isNoteToTraderSupported is true', () => {
- mockedStore.metamask.custodyAccountDetails = {
- [mockTxParamsFromAddress]: {
- address: mockTxParamsFromAddress,
- details: 'details',
- custodyType: 'testCustody - Saturn',
- custodianName: 'saturn-dev',
- },
- };
-
- mockedStore.metamask.mmiConfiguration = {
- custodians: [
- {
- envName: 'saturn-dev',
- displayName: 'Saturn Custody',
- isNoteToTraderSupported: true,
+ it('should render NoteToTrader when isNoteToTraderSupported is true', async () => {
+ const state = {
+ metamask: {
+ ...baseStore.metamask,
+ custodyAccountDetails: {
+ [mockTxParamsFromAddress]: {
+ address: mockTxParamsFromAddress,
+ details: 'details',
+ custodyType: 'testCustody - Saturn',
+ custodianName: 'saturn-dev',
+ },
},
- ],
+ mmiConfiguration: {
+ custodians: [
+ {
+ envName: 'saturn-dev',
+ displayName: 'Saturn Custody',
+ isNoteToTraderSupported: true,
+ },
+ ],
+ },
+ },
};
- const store = configureMockStore(middleware)(mockedStore);
- const { getByTestId } = renderWithProvider(
- ,
- store,
- );
+ const { getByTestId } = await render({ state });
expect(getByTestId('note-tab')).toBeInTheDocument();
});
it('handleMMISubmit calls sendTransaction correctly when isNoteToTraderSupported is false', async () => {
- const newMockedStore = {
- ...mockedStore,
+ const state = {
appState: {
- ...mockedStore.appState,
+ ...baseStore.appState,
gasLoadingAnimationIsShowing: false,
},
confirmTransaction: {
- ...mockedStore.confirmTransaction,
+ ...baseStore.confirmTransaction,
txData: {
- ...mockedStore.confirmTransaction.txData,
+ ...baseStore.confirmTransaction.txData,
custodyStatus: true,
},
},
metamask: {
- ...mockedStore.metamask,
+ ...baseStore.metamask,
accounts: {
[mockTxParamsFromAddress]: {
balance: '0x1000000000000000000',
@@ -356,7 +405,7 @@ describe('Confirm Transaction Base', () => {
gasEstimateType: GasEstimateTypes.feeMarket,
selectedNetworkClientId: NetworkType.mainnet,
networksMetadata: {
- ...mockedStore.metamask.networksMetadata,
+ ...baseStore.metamask.networksMetadata,
[NetworkType.mainnet]: {
EIPS: {
1559: true,
@@ -394,9 +443,9 @@ describe('Confirm Transaction Base', () => {
},
},
send: {
- ...mockedStore.send,
+ ...baseStore.send,
gas: {
- ...mockedStore.send.gas,
+ ...baseStore.send.gas,
gasEstimateType: GasEstimateTypes.legacy,
gasFeeEstimates: {
low: '0',
@@ -413,27 +462,24 @@ describe('Confirm Transaction Base', () => {
},
};
- const store = configureMockStore(middleware)(newMockedStore);
const sendTransaction = jest
.fn()
- .mockResolvedValue(newMockedStore.confirmTransaction.txData);
+ .mockResolvedValue(state.confirmTransaction.txData);
const updateTransaction = jest.fn().mockResolvedValue();
const showCustodianDeepLink = jest.fn();
const setWaitForConfirmDeepLinkDialog = jest.fn();
- const { getByTestId } = renderWithProvider(
- ,
- store,
- );
+ const props = {
+ sendTransaction,
+ updateTransaction,
+ showCustodianDeepLink,
+ setWaitForConfirmDeepLinkDialog,
+ toAddress: mockPropsToAddress,
+ toAccounts: [{ address: mockPropsToAddress }],
+ isMainBetaFlask: false,
+ };
+
+ const { getByTestId } = await render({ props, state });
const confirmButton = getByTestId('page-container-footer-next');
@@ -445,14 +491,13 @@ describe('Confirm Transaction Base', () => {
});
it('handleMainSubmit calls sendTransaction correctly', async () => {
- const newMockedStore = {
- ...mockedStore,
+ const state = {
appState: {
- ...mockedStore.appState,
+ ...baseStore.appState,
gasLoadingAnimationIsShowing: false,
},
metamask: {
- ...mockedStore.metamask,
+ ...baseStore.metamask,
accounts: {
[mockTxParamsFromAddress]: {
balance: '0x1000000000000000000',
@@ -462,7 +507,7 @@ describe('Confirm Transaction Base', () => {
gasEstimateType: GasEstimateTypes.feeMarket,
selectedNetworkClientId: NetworkType.mainnet,
networksMetadata: {
- ...mockedStore.metamask.networksMetadata,
+ ...baseStore.metamask.networksMetadata,
[NetworkType.mainnet]: {
EIPS: { 1559: true },
status: NetworkStatus.Available,
@@ -475,9 +520,9 @@ describe('Confirm Transaction Base', () => {
noGasPrice: false,
},
send: {
- ...mockedStore.send,
+ ...baseStore.send,
gas: {
- ...mockedStore.send.gas,
+ ...baseStore.send.gas,
gasEstimateType: GasEstimateTypes.legacy,
gasFeeEstimates: {
low: '0',
@@ -494,39 +539,38 @@ describe('Confirm Transaction Base', () => {
},
};
- const store = configureMockStore(middleware)(newMockedStore);
const sendTransaction = jest.fn().mockResolvedValue();
- const { getByTestId } = renderWithProvider(
- ,
- store,
- );
+ const props = {
+ sendTransaction,
+ toAddress: mockPropsToAddress,
+ toAccounts: [{ address: mockPropsToAddress }],
+ };
+
+ const { getByTestId } = await render({ props, state });
+
const confirmButton = getByTestId('page-container-footer-next');
- fireEvent.click(confirmButton);
+ await act(async () => {
+ fireEvent.click(confirmButton);
+ });
expect(sendTransaction).toHaveBeenCalled();
});
it('handleMMISubmit calls sendTransaction correctly and then showCustodianDeepLink', async () => {
- const newMockedStore = {
- ...mockedStore,
+ const state = {
appState: {
- ...mockedStore.appState,
+ ...baseStore.appState,
gasLoadingAnimationIsShowing: false,
},
confirmTransaction: {
- ...mockedStore.confirmTransaction,
+ ...baseStore.confirmTransaction,
txData: {
- ...mockedStore.confirmTransaction.txData,
+ ...baseStore.confirmTransaction.txData,
custodyStatus: true,
},
},
metamask: {
- ...mockedStore.metamask,
+ ...baseStore.metamask,
accounts: {
[mockTxParamsFromAddress]: {
balance: '0x1000000000000000000',
@@ -536,7 +580,7 @@ describe('Confirm Transaction Base', () => {
gasEstimateType: GasEstimateTypes.feeMarket,
selectedNetworkClientId: NetworkType.mainnet,
networksMetadata: {
- ...mockedStore.metamask.networksMetadata,
+ ...baseStore.metamask.networksMetadata,
[NetworkType.mainnet]: {
EIPS: {
1559: true,
@@ -551,9 +595,9 @@ describe('Confirm Transaction Base', () => {
noGasPrice: false,
},
send: {
- ...mockedStore.send,
+ ...baseStore.send,
gas: {
- ...mockedStore.send.gas,
+ ...baseStore.send.gas,
gasEstimateType: GasEstimateTypes.legacy,
gasFeeEstimates: {
low: '0',
@@ -570,27 +614,27 @@ describe('Confirm Transaction Base', () => {
},
};
- const store = configureMockStore(middleware)(newMockedStore);
const sendTransaction = jest
.fn()
- .mockResolvedValue(newMockedStore.confirmTransaction.txData);
+ .mockResolvedValue(state.confirmTransaction.txData);
const showCustodianDeepLink = jest.fn();
const setWaitForConfirmDeepLinkDialog = jest.fn();
- const { getByTestId } = renderWithProvider(
- ,
- store,
- );
+ const props = {
+ sendTransaction,
+ showCustodianDeepLink,
+ setWaitForConfirmDeepLinkDialog,
+ toAddress: mockPropsToAddress,
+ toAccounts: [{ address: mockPropsToAddress }],
+ isMainBetaFlask: false,
+ };
+
+ const { getByTestId } = await render({ props, state });
+
const confirmButton = getByTestId('page-container-footer-next');
- fireEvent.click(confirmButton);
+ await act(async () => {
+ fireEvent.click(confirmButton);
+ });
expect(setWaitForConfirmDeepLinkDialog).toHaveBeenCalled();
await expect(sendTransaction).toHaveBeenCalled();
expect(showCustodianDeepLink).toHaveBeenCalled();
@@ -598,27 +642,19 @@ describe('Confirm Transaction Base', () => {
describe('when rendering the recipient value', () => {
describe(`when the transaction is a ${TransactionType.simpleSend} type`, () => {
- it(`should use txParams.to address`, () => {
- const store = configureMockStore(middleware)(mockedStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ it(`should use txParams.to address`, async () => {
+ const { container } = await render();
const recipientElem = container.querySelector(sendToRecipientSelector);
expect(recipientElem).toHaveTextContent(mockTxParamsToAddressConcat);
});
- it(`should use txParams.to address even if there is no amount sent`, () => {
- mockedStoreWithConfirmTxParams({
+ it(`should use txParams.to address even if there is no amount sent`, async () => {
+ const state = mockedStoreWithConfirmTxParams(baseStore, {
...mockTxParams,
value: '0x0',
});
- const store = configureMockStore(middleware)(mockedStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ const { container } = await render({ state });
const recipientElem = container.querySelector(sendToRecipientSelector);
expect(recipientElem).toHaveTextContent(mockTxParamsToAddressConcat);
@@ -626,21 +662,22 @@ describe('Confirm Transaction Base', () => {
});
describe(`when the transaction is NOT a ${TransactionType.simpleSend} type`, () => {
beforeEach(() => {
- mockedStore.confirmTransaction.txData.type =
+ baseStore.confirmTransaction.txData.type =
TransactionType.contractInteraction;
});
describe('when there is an amount being sent (it should be treated as a general contract intereaction rather than custom one)', () => {
- it('should use txParams.to address (contract address)', () => {
- mockedStoreWithConfirmTxParams({
+ it('should use txParams.to address (contract address)', async () => {
+ const state = mockedStoreWithConfirmTxParams(baseStore, {
...mockTxParams,
value: '0x45666',
});
- const store = configureMockStore(middleware)(mockedStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ state.confirmTransaction.txData = {
+ ...state.confirmTransaction.txData,
+ type: TransactionType.contractInteraction,
+ };
+
+ const { container } = await render({ state });
const recipientElem = container.querySelector(
sendToRecipientSelector,
@@ -650,23 +687,24 @@ describe('Confirm Transaction Base', () => {
});
describe(`when there is no amount being sent`, () => {
- it('should use propToAddress (toAddress passed as prop)', () => {
- mockedStoreWithConfirmTxParams({
+ it('should use propToAddress (toAddress passed as prop)', async () => {
+ const state = mockedStoreWithConfirmTxParams(baseStore, {
...mockTxParams,
value: '0x0',
});
- const store = configureMockStore(middleware)(mockedStore);
-
- const { container } = renderWithProvider(
- ,
- store,
- );
+ state.confirmTransaction.txData = {
+ ...state.confirmTransaction.txData,
+ type: TransactionType.contractInteraction,
+ };
+
+ const props = {
+ // we want to test toAddress provided by ownProps in mapStateToProps, but this
+ // currently overrides toAddress this should pan out fine when we refactor the
+ // component into a functional component and remove the container.js file
+ toAddress: mockPropsToAddress,
+ };
+
+ const { container } = await render({ props, state });
const recipientElem = container.querySelector(
sendToRecipientSelector,
@@ -674,16 +712,19 @@ describe('Confirm Transaction Base', () => {
expect(recipientElem).toHaveTextContent(mockPropsToAddressConcat);
});
- it('should use address parsed from transaction data if propToAddress is not provided', () => {
- mockedStoreWithConfirmTxParams({
+ it('should use address parsed from transaction data if propToAddress is not provided', async () => {
+ const state = mockedStoreWithConfirmTxParams(baseStore, {
...mockTxParams,
value: '0x0',
});
- const store = configureMockStore(middleware)(mockedStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ state.confirmTransaction.txData = {
+ ...state.confirmTransaction.txData,
+ type: TransactionType.contractInteraction,
+ };
+
+ const props = {};
+
+ const { container } = await render({ props, state });
const recipientElem = container.querySelector(
sendToRecipientSelector,
@@ -691,17 +732,20 @@ describe('Confirm Transaction Base', () => {
expect(recipientElem).toHaveTextContent(mockParsedTxDataToAddress);
});
- it('should use txParams.to if neither propToAddress is not provided nor the transaction data to address were provided', () => {
- mockedStoreWithConfirmTxParams({
+ it('should use txParams.to if neither propToAddress is not provided nor the transaction data to address were provided', async () => {
+ const state = mockedStoreWithConfirmTxParams(baseStore, {
...mockTxParams,
data: '0x',
value: '0x0',
});
- const store = configureMockStore(middleware)(mockedStore);
- const { container } = renderWithProvider(
- ,
- store,
- );
+ state.confirmTransaction.txData = {
+ ...state.confirmTransaction.txData,
+ type: TransactionType.contractInteraction,
+ };
+
+ const props = {};
+
+ const { container } = await render({ props, state });
const recipientElem = container.querySelector(
sendToRecipientSelector,
From d97ddd90ac6e4f1a4de434f18f7260fc314ae3e1 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Thu, 22 Feb 2024 14:56:38 -0800
Subject: [PATCH 57/74] fix advanced-gas-fee-input-subtext.test.js
---
.../advanced-gas-fee-input-subtext.test.js | 60 +++++++++++--------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
index 8eab525cf4a8..32c5ed716e1f 100644
--- a/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
+++ b/ui/pages/confirmations/components/advanced-gas-fee-popover/advanced-gas-fee-input-subtext/advanced-gas-fee-input-subtext.test.js
@@ -1,4 +1,5 @@
import React from 'react';
+import { act } from '@testing-library/react';
import { renderWithProvider, screen } from '../../../../../../test/jest';
import configureStore from '../../../../../store/store';
import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext';
@@ -19,15 +20,26 @@ jest.mock('../../../../../store/actions', () => ({
removePollingTokenFromAppState: jest.fn(),
}));
-const renderComponent = ({ props = {}, state = {} } = {}) => {
+const renderComponent = async ({ props = {}, state = {} } = {}) => {
const store = configureStore(state);
- return renderWithProvider(, store);
+
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+ ,
+ store,
+ )),
+ );
+
+ return result;
};
describe('AdvancedGasFeeInputSubtext', () => {
describe('when "latest" is non-nullish', () => {
- it('should render the latest fee if given a fee', () => {
- renderComponent({
+ it('should render the latest fee if given a fee', async () => {
+ await renderComponent({
props: {
latest: '123.12345',
},
@@ -36,8 +48,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByText('123.12 GWEI')).toBeInTheDocument();
});
- it('should render the latest fee range if given a fee range', () => {
- renderComponent({
+ it('should render the latest fee range if given a fee range', async () => {
+ await renderComponent({
props: {
latest: ['123.456', '456.789'],
},
@@ -46,8 +58,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByText('123.46 - 456.79 GWEI')).toBeInTheDocument();
});
- it('should render a fee trend arrow image if given "up" as the trend', () => {
- renderComponent({
+ it('should render a fee trend arrow image if given "up" as the trend', async () => {
+ await renderComponent({
props: {
latest: '123.12345',
trend: 'up',
@@ -57,8 +69,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByTitle('up arrow')).toBeInTheDocument();
});
- it('should render a fee trend arrow image if given "down" as the trend', () => {
- renderComponent({
+ it('should render a fee trend arrow image if given "down" as the trend', async () => {
+ await renderComponent({
props: {
latest: '123.12345',
trend: 'down',
@@ -68,8 +80,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByTitle('down arrow')).toBeInTheDocument();
});
- it('should render a fee trend arrow image if given "level" as the trend', () => {
- renderComponent({
+ it('should render a fee trend arrow image if given "level" as the trend', async () => {
+ await renderComponent({
props: {
latest: '123.12345',
trend: 'level',
@@ -79,11 +91,11 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByTitle('level arrow')).toBeInTheDocument();
});
- it('should not render a fee trend arrow image if given an invalid trend', () => {
+ it('should not render a fee trend arrow image if given an invalid trend', async () => {
// Suppress warning from PropTypes, which we expect
jest.spyOn(console, 'error').mockImplementation();
- renderComponent({
+ await renderComponent({
props: {
latest: '123.12345',
trend: 'whatever',
@@ -93,8 +105,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.queryByTestId('fee-arrow')).not.toBeInTheDocument();
});
- it('should not render a fee trend arrow image if given a nullish trend', () => {
- renderComponent({
+ it('should not render a fee trend arrow image if given a nullish trend', async () => {
+ await renderComponent({
props: {
latest: '123.12345',
trend: null,
@@ -106,8 +118,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
});
describe('when "latest" is nullish', () => {
- it('should not render the container for the latest fee', () => {
- renderComponent({
+ it('should not render the container for the latest fee', async () => {
+ await renderComponent({
props: {
latest: null,
},
@@ -118,8 +130,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
});
describe('when "historical" is not nullish', () => {
- it('should render the historical fee if given a fee', () => {
- renderComponent({
+ it('should render the historical fee if given a fee', async () => {
+ await renderComponent({
props: {
historical: '123.12345',
},
@@ -128,8 +140,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
expect(screen.getByText('123.12 GWEI')).toBeInTheDocument();
});
- it('should render the historical fee range if given a fee range', () => {
- renderComponent({
+ it('should render the historical fee range if given a fee range', async () => {
+ await renderComponent({
props: {
historical: ['123.456', '456.789'],
},
@@ -140,8 +152,8 @@ describe('AdvancedGasFeeInputSubtext', () => {
});
describe('when "historical" is nullish', () => {
- it('should not render the container for the historical fee', () => {
- renderComponent({
+ it('should not render the container for the historical fee', async () => {
+ await renderComponent({
props: {
historical: null,
},
From 5ed263678e7cd3e272f568dc107209f72781de6d Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 09:13:19 -0800
Subject: [PATCH 58/74] fix edit-gas-fee-popover.test.js
---
.../edit-gas-fee-popover.test.js | 103 ++++++++++--------
1 file changed, 59 insertions(+), 44 deletions(-)
diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
index dda3eeb5f13a..0a7ce24c57d5 100644
--- a/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
+++ b/ui/pages/confirmations/components/edit-gas-fee-popover/edit-gas-fee-popover.test.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { screen } from '@testing-library/react';
+import { act, screen } from '@testing-library/react';
import {
TransactionStatus,
@@ -22,19 +22,11 @@ jest.mock('../../../../store/actions', () => ({
.fn()
.mockResolvedValue('pollingToken'),
gasFeeStopPollingByPollingToken: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
- .fn()
- .mockImplementation(() => Promise.resolve()),
getNetworkConfigurationByNetworkClientId: jest.fn().mockImplementation(() =>
Promise.resolve({
chainId: '0x5',
}),
),
- disconnectGasFeeEstimatePoller: jest.fn(),
- getGasFeeEstimatesAndStartPolling: jest
- .fn()
- .mockImplementation(() => Promise.resolve()),
- addPollingTokenToAppState: jest.fn(),
createTransactionEventFragment: jest.fn(),
}));
@@ -69,7 +61,7 @@ const MOCK_FEE_ESTIMATE = {
networkCongestion: 0.7,
};
-const render = ({ txProps, contextProps } = {}) => {
+const render = async ({ txProps, contextProps } = {}) => {
const store = configureStore({
metamask: {
currencyRates: {},
@@ -78,6 +70,15 @@ const render = ({ txProps, contextProps } = {}) => {
nickname: GOERLI_DISPLAY_NAME,
type: NETWORK_TYPES.GOERLI,
},
+ selectedNetworkClientId: 'goerli',
+ networksMetadata: {
+ goerli: {
+ EIPS: {
+ 1559: true,
+ },
+ status: 'available',
+ },
+ },
accountsByChainId: {
[CHAIN_IDS.GOERLI]: {
'0xAddress': { address: '0xAddress', balance: '0x1F4' },
@@ -95,24 +96,38 @@ const render = ({ txProps, contextProps } = {}) => {
selectedAddress: '0xAddress',
featureFlags: { advancedInlineGas: true },
gasFeeEstimates: MOCK_FEE_ESTIMATE,
+ gasFeeEstimatesByChainId: {
+ [CHAIN_IDS.GOERLI]: {
+ gasFeeEstimates: MOCK_FEE_ESTIMATE,
+ },
+ },
advancedGasFee: {},
},
});
- return renderWithProvider(
-
-
- ,
- store,
+ let result;
+
+ await act(
+ async () =>
+ (result = renderWithProvider(
+
+
+ ,
+ store,
+ )),
);
+
+ return result;
};
describe('EditGasFeePopover', () => {
- it('should renders low / medium / high options', () => {
- render({ txProps: { dappSuggestedGasFees: { maxFeePerGas: '0x5208' } } });
+ it('should renders low / medium / high options', async () => {
+ await render({
+ txProps: { dappSuggestedGasFees: { maxFeePerGas: '0x5208' } },
+ });
expect(screen.queryByText('🐢')).toBeInTheDocument();
expect(screen.queryByText('🦊')).toBeInTheDocument();
@@ -126,21 +141,21 @@ describe('EditGasFeePopover', () => {
expect(screen.queryByText('Advanced')).toBeInTheDocument();
});
- it('should show time estimates', () => {
- render();
+ it('should show time estimates', async () => {
+ await render();
expect(screen.queryAllByText('5 min')).toHaveLength(2);
expect(screen.queryByText('15 sec')).toBeInTheDocument();
});
- it('should show gas fee estimates', () => {
- render();
+ it('should show gas fee estimates', async () => {
+ await render();
expect(screen.queryByTitle('0.001113 ETH')).toBeInTheDocument();
expect(screen.queryByTitle('0.00147 ETH')).toBeInTheDocument();
expect(screen.queryByTitle('0.0021 ETH')).toBeInTheDocument();
});
- it('should not show insufficient balance message if transaction value is less than balance', () => {
- render({
+ it('should not show insufficient balance message if transaction value is less than balance', async () => {
+ await render({
txProps: {
status: TransactionStatus.unapproved,
type: TransactionType.simpleSend,
@@ -151,8 +166,8 @@ describe('EditGasFeePopover', () => {
expect(screen.queryByText('Insufficient funds.')).not.toBeInTheDocument();
});
- it('should show insufficient balance message if transaction value is more than balance', () => {
- render({
+ it('should show insufficient balance message if transaction value is more than balance', async () => {
+ await render({
txProps: {
status: TransactionStatus.unapproved,
type: TransactionType.simpleSend,
@@ -163,8 +178,8 @@ describe('EditGasFeePopover', () => {
expect(screen.queryByText('Insufficient funds.')).toBeInTheDocument();
});
- it('should not show low, aggressive and dapp-suggested options for swap', () => {
- render({
+ it('should not show low, aggressive and dapp-suggested options for swap', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.swaps },
});
expect(screen.queryByText('🐢')).not.toBeInTheDocument();
@@ -181,52 +196,52 @@ describe('EditGasFeePopover', () => {
expect(screen.queryByText('Advanced')).toBeInTheDocument();
});
- it('should not show time estimates for swaps', () => {
- render({
+ it('should not show time estimates for swaps', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.swaps },
});
expect(screen.queryByText('Time')).not.toBeInTheDocument();
expect(screen.queryByText('Max fee')).toBeInTheDocument();
});
- it('should show correct header for edit gas mode', () => {
- render({
+ it('should show correct header for edit gas mode', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.swaps },
});
expect(screen.queryByText('Edit gas fee')).toBeInTheDocument();
- render({
+ await render({
contextProps: { editGasMode: EditGasModes.cancel },
});
expect(screen.queryByText('Edit cancellation gas fee')).toBeInTheDocument();
- render({
+ await render({
contextProps: { editGasMode: EditGasModes.speedUp },
});
expect(screen.queryByText('Edit speed up gas fee')).toBeInTheDocument();
});
- it('should not show low option for cancel mode', () => {
- render({
+ it('should not show low option for cancel mode', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.cancel },
});
expect(screen.queryByText('Low')).not.toBeInTheDocument();
});
- it('should not show low option for speedup mode', () => {
- render({
+ it('should not show low option for speedup mode', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.speedUp },
});
expect(screen.queryByText('Low')).not.toBeInTheDocument();
});
- it('should show tenPercentIncreased option for cancel gas mode', () => {
- render({
+ it('should show tenPercentIncreased option for cancel gas mode', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.cancel },
});
expect(screen.queryByText('10% increase')).toBeInTheDocument();
});
- it('should show tenPercentIncreased option for speedup gas mode', () => {
- render({
+ it('should show tenPercentIncreased option for speedup gas mode', async () => {
+ await render({
contextProps: { editGasMode: EditGasModes.speedUp },
});
expect(screen.queryByText('10% increase')).toBeInTheDocument();
From 86bf912039f03300ff48d089a7c20236cded35b9 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 09:40:55 -0800
Subject: [PATCH 59/74] fix useGasFeeInputs.test.js via test-utils selectors
---
ui/pages/confirmations/hooks/test-utils.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ui/pages/confirmations/hooks/test-utils.js b/ui/pages/confirmations/hooks/test-utils.js
index a0805096dbf6..5805c56c8f93 100644
--- a/ui/pages/confirmations/hooks/test-utils.js
+++ b/ui/pages/confirmations/hooks/test-utils.js
@@ -6,7 +6,6 @@ import {
getNativeCurrency,
} from '../../../ducks/metamask/metamask';
import {
- checkNetworkAndAccountSupports1559,
getCurrentCurrency,
getShouldShowFiat,
getPreferences,
@@ -132,7 +131,7 @@ export const generateUseSelectorRouter =
if (selector === getCustomMaxPriorityFeePerGas) {
return '0x5208';
}
- if (selector === checkNetworkAndAccountSupports1559) {
+ if (selector.toString().includes('checkNetworkAndAccountSupports1559')) {
return checkNetworkAndAccountSupports1559Response;
}
if (selector === getCurrentKeyring) {
From 2e710c915ca28724574ad8e44987a14a723b6fe5 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 11:22:31 -0800
Subject: [PATCH 60/74] add mock state by chain id to speedup test
---
.../cancel-speedup-popover/cancel-speedup-popover.test.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
index 54de42f40283..2ef329652cf3 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
@@ -94,6 +94,14 @@ const render = (
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ gasFeeEstimatesByChainId: {
+ ...mockState.metamask.gasFeeEstimatesByChainId,
+ '0x5': {
+ ...mockState.metamask.gasFeeEstimatesByChainId['0x5'],
+ gasFeeEstimates:
+ mockEstimates[GasEstimateTypes.feeMarket].gasFeeEstimates,
+ },
+ },
},
});
From 9422acb4c4d3e94897735f6094e5e84595734138 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 11:32:02 -0800
Subject: [PATCH 61/74] wip
---
.../app/cancel-speedup-popover/cancel-speedup-popover.js | 2 ++
.../app/cancel-speedup-popover/cancel-speedup-popover.test.js | 2 +-
ui/contexts/gasFee.js | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
index ceb1aaef00f5..937d1d68e6d1 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
@@ -47,6 +47,7 @@ const CancelSpeedupPopover = () => {
appIsLoading ||
currentModal !== 'cancelSpeedUpTransaction'
) {
+ console.log('exit early')
return;
}
// If gas used previously + 10% is less than medium estimated gas
@@ -58,6 +59,7 @@ const CancelSpeedupPopover = () => {
gasFeeEstimates,
PriorityLevels.medium,
);
+ console.log({gasUsedLessThanMedium})
if (gasUsedLessThanMedium) {
updateTransactionUsingEstimate(PriorityLevels.medium);
return;
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
index 2ef329652cf3..ce1c25e3acb2 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
@@ -171,7 +171,7 @@ describe('CancelSpeedupPopover', () => {
).toBeGreaterThan(0);
});
- it('should show correct gas values, set to the estimated medium, when initial initial gas value is below estimated medium', async () => {
+ it.only('should show correct gas values, set to the estimated medium, when initial initial gas value is below estimated medium', async () => {
await act(async () =>
render(
{
diff --git a/ui/contexts/gasFee.js b/ui/contexts/gasFee.js
index 5f7bf003c448..5b9a78b4f256 100644
--- a/ui/contexts/gasFee.js
+++ b/ui/contexts/gasFee.js
@@ -17,6 +17,7 @@ export const GasFeeContextProvider = ({
minimumGasLimit,
editGasMode,
);
+ console.log('gasFee context', gasFeeDetails.gasFeeEstimates)
return (
{children}
From 170fee4ae31649d4f535e45c54eee986831f47e2 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 13:16:17 -0800
Subject: [PATCH 62/74] exit early updateTransactionToTenPercentIncreasedGasFee
---
ui/pages/confirmations/hooks/useTransactionFunctions.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ui/pages/confirmations/hooks/useTransactionFunctions.js b/ui/pages/confirmations/hooks/useTransactionFunctions.js
index db947e08f337..57c525576329 100644
--- a/ui/pages/confirmations/hooks/useTransactionFunctions.js
+++ b/ui/pages/confirmations/hooks/useTransactionFunctions.js
@@ -183,6 +183,9 @@ export const useTransactionFunctions = ({
? CUSTOM_GAS_ESTIMATE
: PriorityLevels.tenPercentIncreased;
+ if (!gasFeeEstimates?.[estimateUsed]) {
+ return;
+ }
updateTransaction({
estimateSuggested: initTransaction
? defaultEstimateToUse
From 2142d98c85913e380be387ce3f7eaa4e62e00491 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 13:17:22 -0800
Subject: [PATCH 63/74] Revert "wip"
This reverts commit 9422acb4c4d3e94897735f6094e5e84595734138.
---
.../app/cancel-speedup-popover/cancel-speedup-popover.js | 2 --
.../app/cancel-speedup-popover/cancel-speedup-popover.test.js | 2 +-
ui/contexts/gasFee.js | 1 -
3 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
index 937d1d68e6d1..ceb1aaef00f5 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.js
@@ -47,7 +47,6 @@ const CancelSpeedupPopover = () => {
appIsLoading ||
currentModal !== 'cancelSpeedUpTransaction'
) {
- console.log('exit early')
return;
}
// If gas used previously + 10% is less than medium estimated gas
@@ -59,7 +58,6 @@ const CancelSpeedupPopover = () => {
gasFeeEstimates,
PriorityLevels.medium,
);
- console.log({gasUsedLessThanMedium})
if (gasUsedLessThanMedium) {
updateTransactionUsingEstimate(PriorityLevels.medium);
return;
diff --git a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
index ce1c25e3acb2..2ef329652cf3 100644
--- a/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
+++ b/ui/components/app/cancel-speedup-popover/cancel-speedup-popover.test.js
@@ -171,7 +171,7 @@ describe('CancelSpeedupPopover', () => {
).toBeGreaterThan(0);
});
- it.only('should show correct gas values, set to the estimated medium, when initial initial gas value is below estimated medium', async () => {
+ it('should show correct gas values, set to the estimated medium, when initial initial gas value is below estimated medium', async () => {
await act(async () =>
render(
{
diff --git a/ui/contexts/gasFee.js b/ui/contexts/gasFee.js
index 5b9a78b4f256..5f7bf003c448 100644
--- a/ui/contexts/gasFee.js
+++ b/ui/contexts/gasFee.js
@@ -17,7 +17,6 @@ export const GasFeeContextProvider = ({
minimumGasLimit,
editGasMode,
);
- console.log('gasFee context', gasFeeDetails.gasFeeEstimates)
return (
{children}
From 54519ae69f418e79aa2be9df8b107d77bec2e754 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 13:41:56 -0800
Subject: [PATCH 64/74] update updateTransactionToTenPercentIncreasedGasFee
guard
---
ui/pages/confirmations/hooks/useTransactionFunctions.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/hooks/useTransactionFunctions.js b/ui/pages/confirmations/hooks/useTransactionFunctions.js
index 57c525576329..17b5165da94e 100644
--- a/ui/pages/confirmations/hooks/useTransactionFunctions.js
+++ b/ui/pages/confirmations/hooks/useTransactionFunctions.js
@@ -183,7 +183,7 @@ export const useTransactionFunctions = ({
? CUSTOM_GAS_ESTIMATE
: PriorityLevels.tenPercentIncreased;
- if (!gasFeeEstimates?.[estimateUsed]) {
+ if (!gasFeeEstimates) {
return;
}
updateTransaction({
From 47b8b1f9f8601cc26aec31cc3834cd1e80976dae Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 14:09:58 -0800
Subject: [PATCH 65/74] lint
---
ui/components/multichain/pages/send/send.test.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/components/multichain/pages/send/send.test.js b/ui/components/multichain/pages/send/send.test.js
index f6ebfc83f36d..714b0a801fcc 100644
--- a/ui/components/multichain/pages/send/send.test.js
+++ b/ui/components/multichain/pages/send/send.test.js
@@ -22,8 +22,8 @@ import {
} from '../../../../../shared/constants/network';
import mockSendState from '../../../../../test/data/mock-send-state.json';
import { useIsOriginalNativeTokenSymbol } from '../../../../hooks/useIsOriginalNativeTokenSymbol';
-import { SendPage } from '.';
import { KeyringType } from '../../../../../shared/constants/keyring';
+import { SendPage } from '.';
jest.mock('@ethersproject/providers', () => {
const originalModule = jest.requireActual('@ethersproject/providers');
From 98d3230af57a74a3071fca26ac61a390902164a6 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 14:10:11 -0800
Subject: [PATCH 66/74] update blockaid-banner-alert snapshot?..
---
.../__snapshots__/blockaid-banner-alert.test.js.snap | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap b/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
index ab0c4a9a1c89..04b2a4843aab 100644
--- a/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
+++ b/ui/pages/confirmations/components/security-provider-banner-alert/blockaid-banner-alert/__snapshots__/blockaid-banner-alert.test.js.snap
@@ -51,7 +51,7 @@ exports[`Blockaid Banner Alert should render 'danger' UI when securityAlertRespo
Something doesn't look right?
@@ -144,7 +144,7 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
Something doesn't look right?
@@ -237,7 +237,7 @@ exports[`Blockaid Banner Alert should render 'warning' UI when securityAlertResp
Something doesn't look right?
@@ -331,7 +331,7 @@ exports[`Blockaid Banner Alert should render details section even when features
Something doesn't look right?
@@ -438,7 +438,7 @@ exports[`Blockaid Banner Alert should render details when provided 1`] = `
Something doesn't look right?
@@ -533,7 +533,7 @@ exports[`Blockaid Banner Alert should render link to report url 1`] = `
Something doesn't look right?
From 8ec1e7c1ec636be388d38e1b8afa1c4dff571e9c Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Fri, 23 Feb 2024 14:18:49 -0800
Subject: [PATCH 67/74] fix send-content.component.test.js snapshot
---
.../__snapshots__/send-content.component.test.js.snap | 2 --
1 file changed, 2 deletions(-)
diff --git a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
index cb4204841623..55fc897b62f5 100644
--- a/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
+++ b/ui/pages/confirmations/send/send-content/__snapshots__/send-content.component.test.js.snap
@@ -287,5 +287,3 @@ exports[`SendContent Component render should match snapshot 1`] = `
`;
-
-exports[`SendContent Component render should match snapshot 2`] = ``;
From a0ba91f1ff48972564c19ad8a23fb924dbdeec8b Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Mon, 26 Feb 2024 10:24:41 -0800
Subject: [PATCH 68/74] wait for confirm to be enabled before continuing to tx
insights in test-snap-tx-insights-v2.spec.js
---
test/e2e/snaps/test-snap-txinsights-v2.spec.js | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/test/e2e/snaps/test-snap-txinsights-v2.spec.js b/test/e2e/snaps/test-snap-txinsights-v2.spec.js
index 34617cd2a9f1..de8b9a148e1c 100644
--- a/test/e2e/snaps/test-snap-txinsights-v2.spec.js
+++ b/test/e2e/snaps/test-snap-txinsights-v2.spec.js
@@ -99,6 +99,12 @@ describe('Test Snap TxInsights-v2', function () {
WINDOW_TITLES.Dialog,
windowHandles,
);
+
+ await driver.findClickableElement({
+ text: 'Confirm',
+ tag: 'button',
+ });
+
await driver.waitForSelector({
text: 'Insights Example Snap',
tag: 'button',
From d0d702f3f21b4be3ea6fa596205495eca65d1f05 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Mon, 4 Mar 2024 10:02:35 -0800
Subject: [PATCH 69/74] Add isMounted guard to useGasFeeEstimates
---
ui/hooks/useGasFeeEstimates.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js
index 92612ff63691..5ad37925054b 100644
--- a/ui/hooks/useGasFeeEstimates.js
+++ b/ui/hooks/useGasFeeEstimates.js
@@ -59,13 +59,18 @@ export function useGasFeeEstimates(_networkClientId) {
);
useEffect(() => {
+ let isMounted = true;
getNetworkConfigurationByNetworkClientId(networkClientId).then(
(networkConfig) => {
- if (networkConfig) {
+ if (networkConfig && isMounted) {
setChainId(networkConfig.chainId);
}
},
);
+
+ return () => {
+ isMounted = false;
+ };
}, [networkClientId]);
usePolling({
From 75c91c174c031195a197dc53cf65d2acb6cf481c Mon Sep 17 00:00:00 2001
From: Alex
Date: Tue, 5 Mar 2024 10:05:43 -0600
Subject: [PATCH 70/74] fix test
---
ui/components/multichain/pages/send/send.test.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ui/components/multichain/pages/send/send.test.js b/ui/components/multichain/pages/send/send.test.js
index 72b33368ef0d..14f43c04d760 100644
--- a/ui/components/multichain/pages/send/send.test.js
+++ b/ui/components/multichain/pages/send/send.test.js
@@ -207,6 +207,9 @@ const baseStore = {
},
},
},
+ activeTab: {
+ origin: 'https://uniswap.org/',
+ },
appState: {
sendInputCurrencySwitched: false,
},
From 1080c91aa5f0077229bf270b5b2916b61899d305 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 5 Mar 2024 09:29:34 -0800
Subject: [PATCH 71/74] add isMounted guard to gas-timing-component effect
---
.../components/gas-timing/gas-timing.component.js | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/ui/pages/confirmations/components/gas-timing/gas-timing.component.js b/ui/pages/confirmations/components/gas-timing/gas-timing.component.js
index 0b63f76a74a2..50a29591c391 100644
--- a/ui/pages/confirmations/components/gas-timing/gas-timing.component.js
+++ b/ui/pages/confirmations/components/gas-timing/gas-timing.component.js
@@ -65,6 +65,7 @@ export default function GasTiming({
const previousIsUnknownLow = usePrevious(isUnknownLow);
useEffect(() => {
+ let isMounted = true;
const priority = maxPriorityFeePerGas;
const fee = maxFeePerGas;
@@ -78,7 +79,11 @@ export default function GasTiming({
new BigNumber(priority, 10).toString(10),
new BigNumber(fee, 10).toString(10),
).then((result) => {
- if (maxFeePerGas === fee && maxPriorityFeePerGas === priority) {
+ if (
+ maxFeePerGas === fee &&
+ maxPriorityFeePerGas === priority &&
+ isMounted
+ ) {
setCustomEstimatedTime(result);
}
});
@@ -87,6 +92,10 @@ export default function GasTiming({
if (isUnknownLow !== false && previousIsUnknownLow === true) {
setCustomEstimatedTime(null);
}
+
+ return () => {
+ isMounted = false;
+ };
}, [
maxPriorityFeePerGas,
maxFeePerGas,
From 7cf4cc15264b7bb04343de45319facf32036e387 Mon Sep 17 00:00:00 2001
From: Jiexi Luan
Date: Tue, 5 Mar 2024 14:00:29 -0800
Subject: [PATCH 72/74] update confirm-send-ether.test.js snapshot
---
.../__snapshots__/confirm-send-ether.test.js.snap | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap b/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
index 36086d620ab8..dcbd37a4676f 100644
--- a/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
+++ b/ui/pages/confirmations/confirm-send-ether/__snapshots__/confirm-send-ether.test.js.snap
@@ -381,12 +381,12 @@ exports[`ConfirmSendEther should render correct information for for confirm send
- 0.00021
+ 0.000021
@@ -399,12 +399,12 @@ exports[`ConfirmSendEther should render correct information for for confirm send
>
- 0.00021
+ 0.000021
Date: Wed, 6 Mar 2024 09:47:16 -0600
Subject: [PATCH 73/74] use renderHookWithProvider
---
ui/hooks/usePolling.test.js | 62 +++++++++++++------------------------
1 file changed, 22 insertions(+), 40 deletions(-)
diff --git a/ui/hooks/usePolling.test.js b/ui/hooks/usePolling.test.js
index 4611d5effee3..9250257d3cbc 100644
--- a/ui/hooks/usePolling.test.js
+++ b/ui/hooks/usePolling.test.js
@@ -1,7 +1,5 @@
-import React from 'react';
-import { renderHook, cleanup } from '@testing-library/react-hooks';
-import { Provider } from 'react-redux';
-import configureStore from '../store/store';
+import { cleanup } from '@testing-library/react-hooks';
+import { renderHookWithProvider } from '../../test/lib/render-helpers';
import usePolling from './usePolling';
describe('usePolling', () => {
@@ -17,31 +15,22 @@ describe('usePolling', () => {
metamask: {},
};
- const wrapper = ({ children }) => (
- <>
- {children}
- >
- );
-
- renderHook(
- () => {
- usePolling({
- callback: (pollingToken) => {
- expect(mockStart).toHaveBeenCalledWith(networkClientId, options);
- expect(pollingToken).toBeDefined();
- done();
- return (_pollingToken) => {
- // noop
- };
- },
- startPollingByNetworkClientId: mockStart,
- stopPollingByPollingToken: mockStop,
- networkClientId,
- options,
- });
- },
- { wrapper },
- );
+ renderHookWithProvider(() => {
+ usePolling({
+ callback: (pollingToken) => {
+ expect(mockStart).toHaveBeenCalledWith(networkClientId, options);
+ expect(pollingToken).toBeDefined();
+ done();
+ return (_pollingToken) => {
+ // noop
+ };
+ },
+ startPollingByNetworkClientId: mockStart,
+ stopPollingByPollingToken: mockStop,
+ networkClientId,
+ options,
+ });
+ }, mockState);
});
// eslint-disable-next-line jest/no-done-callback
it('calls the cleanup function with the correct pollingToken when unmounted', (done) => {
@@ -55,14 +44,8 @@ describe('usePolling', () => {
metamask: {},
};
- const wrapper = ({ children }) => (
- <>
- {children}
- >
- );
-
- renderHook(
- () => {
+ renderHookWithProvider(
+ () =>
usePolling({
callback: () => {
return (_pollingToken) => {
@@ -75,9 +58,8 @@ describe('usePolling', () => {
stopPollingByPollingToken: mockStop,
networkClientId,
options,
- });
- },
- { wrapper },
+ }),
+ mockState,
);
cleanup();
});
From 37ef9ac0338cb299728ba0eb34dfe5f05ac48ba1 Mon Sep 17 00:00:00 2001
From: Alex
Date: Wed, 6 Mar 2024 10:48:26 -0600
Subject: [PATCH 74/74] fix broken swaps flow
---
ui/pages/swaps/prepare-swap-page/review-quote.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/pages/swaps/prepare-swap-page/review-quote.js b/ui/pages/swaps/prepare-swap-page/review-quote.js
index 080aae54dd87..4c3d2c4a51af 100644
--- a/ui/pages/swaps/prepare-swap-page/review-quote.js
+++ b/ui/pages/swaps/prepare-swap-page/review-quote.js
@@ -316,7 +316,7 @@ export default function ReviewQuote({ setReceiveToAmount }) {
const {
maxFeePerGas: suggestedMaxFeePerGas,
maxPriorityFeePerGas: suggestedMaxPriorityFeePerGas,
- gasFeeEstimates: { estimatedBaseFee = '0' },
+ gasFeeEstimates: { estimatedBaseFee = '0' } = {},
} = gasFeeInputs;
maxFeePerGas = customMaxFeePerGas || decGWEIToHexWEI(suggestedMaxFeePerGas);
maxPriorityFeePerGas =