diff --git a/.storybook/preview.js b/.storybook/preview.js index 8c6c1985c7f4..cedb0e9cfd54 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -12,8 +12,7 @@ import localeList from '../app/_locales/index.json'; import * as allLocales from './locales'; import { I18nProvider, LegacyI18nProvider } from './i18n'; import testData from './test-data.js'; -import { MemoryRouter } from 'react-router-dom'; -import { CompatRouter, Routes, Route } from 'react-router-dom-v5-compat'; +import { MemoryRouter, Routes, Route } from 'react-router-dom'; import { setBackgroundConnection } from '../ui/store/background-connection'; import { metamaskStorybookTheme } from './metamask-storybook-theme'; import { DocsContainer } from '@storybook/addon-docs'; @@ -154,27 +153,25 @@ const metamaskDecorator = (story, context) => { return ( - - undefined, - trackAlertRender: () => undefined, - trackInlineAlertClicked: () => undefined, - }} + undefined, + trackAlertRender: () => undefined, + trackInlineAlertClicked: () => undefined, + }} + > + - - - - } /> - - - - - + + + } /> + + + + ); diff --git a/development/build/index.js b/development/build/index.js index 86fbcc721e50..e20f2f79b893 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -107,6 +107,7 @@ async function defineAndRunBuildTasks() { 'HTMLElement', 'HTMLFormElement', 'Element', + 'history', // needed by react-router-dom v6 HashRouter 'pageXOffset', 'pageYOffset', 'visualViewport', diff --git a/development/ts-migration-dashboard/files-to-convert.json b/development/ts-migration-dashboard/files-to-convert.json index 0084132a3720..026d5a3a2faa 100644 --- a/development/ts-migration-dashboard/files-to-convert.json +++ b/development/ts-migration-dashboard/files-to-convert.json @@ -1317,8 +1317,6 @@ "ui/pages/permissions-connect/flask/snap-update/index.js", "ui/pages/permissions-connect/flask/snap-update/snap-update.js", "ui/pages/permissions-connect/index.js", - "ui/pages/permissions-connect/permissions-connect.component.js", - "ui/pages/permissions-connect/permissions-connect.container.js", "ui/pages/permissions-connect/permissions-connect.stories.js", "ui/pages/permissions-connect/redirect/index.js", "ui/pages/permissions-connect/redirect/permissions-redirect.component.js", diff --git a/development/webpack/utils/plugins/LavamoatPlugin/index.ts b/development/webpack/utils/plugins/LavamoatPlugin/index.ts index 4ec7ec03584a..1efa61f0f54d 100644 --- a/development/webpack/utils/plugins/LavamoatPlugin/index.ts +++ b/development/webpack/utils/plugins/LavamoatPlugin/index.ts @@ -84,6 +84,7 @@ export const lavamoatPlugin = (args: Args) => 'HTMLElement', 'HTMLFormElement', 'Element', + 'history', // needed by react-router-dom v6 HashRouter 'pageXOffset', 'pageYOffset', 'visualViewport', diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 3197c1023401..5c6b67eaac61 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -2582,7 +2582,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -2593,7 +2593,8 @@ "URL": true, "URLSearchParams": true, "console": true, - "document.defaultView": true + "document.defaultView": true, + "history": true } }, "@rive-app/react-canvas>@rive-app/canvas": { @@ -3622,7 +3623,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -4117,27 +4118,7 @@ }, "history": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true - } - }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true + "history": true } }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { @@ -4346,13 +4327,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -4370,7 +4351,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4650,11 +4631,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -4990,11 +4966,6 @@ "console": true } }, - "react-router-dom>react-router>react-is": { - "globals": { - "console": true - } - }, "react-markdown": { "globals": { "console.warn": true @@ -5058,16 +5029,6 @@ } }, "react-router-dom": { - "packages": { - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -5077,7 +5038,7 @@ "confirm": true, "define": true, "document": true, - "history.scrollRestoration": true, + "history": true, "location.href": true, "removeEventListener": true, "scrollTo": true, @@ -5087,33 +5048,20 @@ "setTimeout": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { "console.error": true, + "console.warn": true, "define": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, @@ -5666,7 +5614,7 @@ "process": true } }, - "react-router-dom>tiny-warning": { + "@material-ui/core>@material-ui/styles>jss>tiny-warning": { "globals": { "console": true } diff --git a/lavamoat/browserify/experimental/policy.json b/lavamoat/browserify/experimental/policy.json index 3197c1023401..5c6b67eaac61 100644 --- a/lavamoat/browserify/experimental/policy.json +++ b/lavamoat/browserify/experimental/policy.json @@ -2582,7 +2582,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -2593,7 +2593,8 @@ "URL": true, "URLSearchParams": true, "console": true, - "document.defaultView": true + "document.defaultView": true, + "history": true } }, "@rive-app/react-canvas>@rive-app/canvas": { @@ -3622,7 +3623,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -4117,27 +4118,7 @@ }, "history": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true - } - }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true + "history": true } }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { @@ -4346,13 +4327,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -4370,7 +4351,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4650,11 +4631,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -4990,11 +4966,6 @@ "console": true } }, - "react-router-dom>react-router>react-is": { - "globals": { - "console": true - } - }, "react-markdown": { "globals": { "console.warn": true @@ -5058,16 +5029,6 @@ } }, "react-router-dom": { - "packages": { - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -5077,7 +5038,7 @@ "confirm": true, "define": true, "document": true, - "history.scrollRestoration": true, + "history": true, "location.href": true, "removeEventListener": true, "scrollTo": true, @@ -5087,33 +5048,20 @@ "setTimeout": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { "console.error": true, + "console.warn": true, "define": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, @@ -5666,7 +5614,7 @@ "process": true } }, - "react-router-dom>tiny-warning": { + "@material-ui/core>@material-ui/styles>jss>tiny-warning": { "globals": { "console": true } diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 3197c1023401..5c6b67eaac61 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -2582,7 +2582,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -2593,7 +2593,8 @@ "URL": true, "URLSearchParams": true, "console": true, - "document.defaultView": true + "document.defaultView": true, + "history": true } }, "@rive-app/react-canvas>@rive-app/canvas": { @@ -3622,7 +3623,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -4117,27 +4118,7 @@ }, "history": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true - } - }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true + "history": true } }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { @@ -4346,13 +4327,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -4370,7 +4351,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4650,11 +4631,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -4990,11 +4966,6 @@ "console": true } }, - "react-router-dom>react-router>react-is": { - "globals": { - "console": true - } - }, "react-markdown": { "globals": { "console.warn": true @@ -5058,16 +5029,6 @@ } }, "react-router-dom": { - "packages": { - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -5077,7 +5038,7 @@ "confirm": true, "define": true, "document": true, - "history.scrollRestoration": true, + "history": true, "location.href": true, "removeEventListener": true, "scrollTo": true, @@ -5087,33 +5048,20 @@ "setTimeout": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { "console.error": true, + "console.warn": true, "define": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, @@ -5666,7 +5614,7 @@ "process": true } }, - "react-router-dom>tiny-warning": { + "@material-ui/core>@material-ui/styles>jss>tiny-warning": { "globals": { "console": true } diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 3197c1023401..5c6b67eaac61 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -2582,7 +2582,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -2593,7 +2593,8 @@ "URL": true, "URLSearchParams": true, "console": true, - "document.defaultView": true + "document.defaultView": true, + "history": true } }, "@rive-app/react-canvas>@rive-app/canvas": { @@ -3622,7 +3623,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -4117,27 +4118,7 @@ }, "history": { "globals": { - "console": true, - "define": true, - "document.defaultView": true, - "document.querySelector": true - } - }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true + "history": true } }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { @@ -4346,13 +4327,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -4370,7 +4351,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4650,11 +4631,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -4990,11 +4966,6 @@ "console": true } }, - "react-router-dom>react-router>react-is": { - "globals": { - "console": true - } - }, "react-markdown": { "globals": { "console.warn": true @@ -5058,16 +5029,6 @@ } }, "react-router-dom": { - "packages": { - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -5077,7 +5038,7 @@ "confirm": true, "define": true, "document": true, - "history.scrollRestoration": true, + "history": true, "location.href": true, "removeEventListener": true, "scrollTo": true, @@ -5087,33 +5048,20 @@ "setTimeout": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { "console.error": true, + "console.warn": true, "define": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, @@ -5666,7 +5614,7 @@ "process": true } }, - "react-router-dom>tiny-warning": { + "@material-ui/core>@material-ui/styles>jss>tiny-warning": { "globals": { "console": true } diff --git a/lavamoat/browserify/policy-override.json b/lavamoat/browserify/policy-override.json index 60065c8ad1a8..2fc5d28d988f 100644 --- a/lavamoat/browserify/policy-override.json +++ b/lavamoat/browserify/policy-override.json @@ -1,5 +1,20 @@ { "resources": { + "history": { + "globals": { + "history": true + } + }, + "react-router-dom": { + "globals": { + "history": true + } + }, + "react-router-dom>@remix-run/router": { + "globals": { + "history": true + } + }, "@metamask/snaps-execution-environments": { "packages": { "@metamask/post-message-stream": true, diff --git a/lavamoat/webpack/mv2/policy-override.json b/lavamoat/webpack/mv2/policy-override.json index 54ff1a23051d..a6431462ae16 100644 --- a/lavamoat/webpack/mv2/policy-override.json +++ b/lavamoat/webpack/mv2/policy-override.json @@ -167,9 +167,14 @@ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "react-router-dom-v5-compat": { - "packages": { - "react-router-dom>react-router": true + "react-router-dom": { + "globals": { + "history": true + } + }, + "react-router-dom>@remix-run/router": { + "globals": { + "history": true } }, "@metamask/multichain-network-controller": { diff --git a/lavamoat/webpack/mv2/policy.json b/lavamoat/webpack/mv2/policy.json index 7d22f550b0d7..3d6625071384 100644 --- a/lavamoat/webpack/mv2/policy.json +++ b/lavamoat/webpack/mv2/policy.json @@ -2429,7 +2429,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -3714,7 +3714,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -4224,24 +4224,6 @@ "define": true } }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "@babel/runtime": true, - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true - } - }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { "packages": { "ethers>@ethersproject/sha2>hash.js": true, @@ -4461,13 +4443,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -4485,7 +4467,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -4763,11 +4745,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -5157,17 +5134,6 @@ } }, "react-router-dom": { - "packages": { - "@babel/runtime": true, - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -5187,39 +5153,23 @@ }, "meta": { "webpack-optimization": [ - "Dependency 'react-router-dom' reexports from 'react-router-dom>react-router' and webpack collapsed that to a direct import.", - "Dependency 'react-router-dom-v5-compat>react-router' reexports from 'react-router-dom-v5-compat>@remix-run/router' and webpack collapsed that to a direct import." + "Dependency 'react-router-dom>react-router' reexports from 'react-router-dom>@remix-run/router' and webpack collapsed that to a direct import." ] }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom>react-router": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "@babel/runtime": true, - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { - "console.error": true + "console.error": true, + "console.warn": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, diff --git a/lavamoat/webpack/mv3/policy-override.json b/lavamoat/webpack/mv3/policy-override.json index 54ff1a23051d..a6431462ae16 100644 --- a/lavamoat/webpack/mv3/policy-override.json +++ b/lavamoat/webpack/mv3/policy-override.json @@ -167,9 +167,14 @@ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true } }, - "react-router-dom-v5-compat": { - "packages": { - "react-router-dom>react-router": true + "react-router-dom": { + "globals": { + "history": true + } + }, + "react-router-dom>@remix-run/router": { + "globals": { + "history": true } }, "@metamask/multichain-network-controller": { diff --git a/lavamoat/webpack/mv3/policy.json b/lavamoat/webpack/mv3/policy.json index d6217eb8ffba..d74856401252 100644 --- a/lavamoat/webpack/mv3/policy.json +++ b/lavamoat/webpack/mv3/policy.json @@ -1300,7 +1300,7 @@ "@reduxjs/toolkit>reselect": true } }, - "react-router-dom-v5-compat>@remix-run/router": { + "react-router-dom>@remix-run/router": { "globals": { "AbortController": true, "DOMException": true, @@ -2285,7 +2285,7 @@ "pageYOffset": true }, "packages": { - "react-router-dom>tiny-invariant": true + "react-beautiful-dnd>css-box-model>tiny-invariant": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer>css-vendor": { @@ -2694,24 +2694,6 @@ "define": true } }, - "react-router-dom>history": { - "globals": { - "addEventListener": true, - "confirm": true, - "document": true, - "history": true, - "location": true, - "navigator.userAgent": true, - "removeEventListener": true - }, - "packages": { - "@babel/runtime": true, - "react-router-dom>history>resolve-pathname": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true, - "react-router-dom>history>value-equal": true - } - }, "@toruslabs/eccrypto>elliptic>hmac-drbg": { "packages": { "ethers>@ethersproject/sha2>hash.js": true, @@ -2884,13 +2866,13 @@ "@material-ui/core>@material-ui/styles>jss-plugin-nested": { "packages": { "@babel/runtime": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-rule-value-function": { "packages": { "@material-ui/core>@material-ui/styles>jss": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "@material-ui/core>@material-ui/styles>jss-plugin-vendor-prefixer": { @@ -2908,7 +2890,7 @@ "packages": { "@babel/runtime": true, "@material-ui/core>@material-ui/styles>jss>is-in-browser": true, - "react-router-dom>tiny-warning": true + "@material-ui/core>@material-ui/styles>jss>tiny-warning": true } }, "ethereumjs-util>ethereum-cryptography>keccak": { @@ -3148,11 +3130,6 @@ "process": true } }, - "serve-handler>path-to-regexp": { - "packages": { - "serve-handler>path-to-regexp>isarray": true - } - }, "crypto-browserify>pbkdf2": { "globals": { "crypto": true, @@ -3537,17 +3514,6 @@ } }, "react-router-dom": { - "packages": { - "@babel/runtime": true, - "react-router-dom>history": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat": { "globals": { "FormData": true, "URL": true, @@ -3567,39 +3533,23 @@ }, "meta": { "webpack-optimization": [ - "Dependency 'react-router-dom' reexports from 'react-router-dom>react-router' and webpack collapsed that to a direct import.", - "Dependency 'react-router-dom-v5-compat>react-router' reexports from 'react-router-dom-v5-compat>@remix-run/router' and webpack collapsed that to a direct import." + "Dependency 'react-router-dom>react-router' reexports from 'react-router-dom>@remix-run/router' and webpack collapsed that to a direct import." ] }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, - "history": true, + "react-router-dom>@remix-run/router": true, "react": true, "react-dom": true, - "react-router-dom": true, - "react-router-dom>react-router": true, - "react-router-dom-v5-compat>react-router": true + "react-router-dom>react-router": true } }, "react-router-dom>react-router": { - "packages": { - "@babel/runtime": true, - "react-router-dom>history": true, - "react-redux>hoist-non-react-statics": true, - "serve-handler>path-to-regexp": true, - "prop-types": true, - "react": true, - "react-router-dom>react-router>react-is": true, - "react-router-dom>tiny-invariant": true, - "react-router-dom>tiny-warning": true - } - }, - "react-router-dom-v5-compat>react-router": { "globals": { - "console.error": true + "console.error": true, + "console.warn": true }, "packages": { - "react-router-dom-v5-compat>@remix-run/router": true, + "react-router-dom>@remix-run/router": true, "react": true } }, diff --git a/package.json b/package.json index c924e3229024..a98c0701bdac 100644 --- a/package.json +++ b/package.json @@ -443,8 +443,7 @@ "react-popper": "^2.2.3", "react-redux": "^7.2.9", "react-responsive-carousel": "^3.2.21", - "react-router-dom": "^5.3.4", - "react-router-dom-v5-compat": "^6.26.2", + "react-router-dom": "^6.28.0", "react-simple-file-input": "^2.0.0", "react-tippy": "^1.2.2", "react-toggle-button": "^2.2.0", diff --git a/test/jest/index.js b/test/jest/index.js index f63a6ab3fdec..0a75a12c2d4f 100644 --- a/test/jest/index.js +++ b/test/jest/index.js @@ -3,6 +3,5 @@ export { createSwapsMockStore, createGetSmartTransactionFeesApiResponse, } from './mock-store'; -export { renderWithProvider, renderWithProviderAndHistory } from './rendering'; export * as MOCKS from './mocks'; export * as CONSTANTS from './constants'; diff --git a/test/jest/rendering.js b/test/jest/rendering.js deleted file mode 100644 index 8eb89a7e5165..000000000000 --- a/test/jest/rendering.js +++ /dev/null @@ -1,124 +0,0 @@ -import React, { useMemo } from 'react'; -import { Provider } from 'react-redux'; -import { render } from '@testing-library/react'; -import { MemoryRouter, Router } from 'react-router-dom'; -import { CompatRouter } from 'react-router-dom-v5-compat'; -import PropTypes from 'prop-types'; - -import { I18nContext, LegacyI18nProvider } from '../../ui/contexts/i18n'; -import { getMessage } from '../../ui/helpers/utils/i18n-helper'; -import * as en from '../../app/_locales/en/messages.json'; -import { - LegacyMetaMetricsProvider, - MetaMetricsContext, -} from '../../ui/contexts/metametrics'; - -// Mock MetaMetrics context for tests -const createMockTrackEvent = () => { - const mockTrackEvent = jest.fn().mockResolvedValue(); - Object.assign(mockTrackEvent, { - bufferedTrace: jest.fn().mockResolvedValue(), - bufferedEndTrace: jest.fn().mockResolvedValue(), - onboardingParentContext: { current: null }, - }); - return mockTrackEvent; -}; - -export const I18nProvider = (props) => { - const { currentLocale, current, en: eng } = props; - - const t = useMemo(() => { - return (key, ...args) => - getMessage(currentLocale, current, key, ...args) || - getMessage(currentLocale, eng, key, ...args); - }, [currentLocale, current, eng]); - - return ( - {props.children} - ); -}; - -I18nProvider.propTypes = { - currentLocale: PropTypes.string, - current: PropTypes.object, - en: PropTypes.object, - children: PropTypes.node, -}; - -I18nProvider.defaultProps = { - children: undefined, -}; - -export function renderWithProvider(component, store, initialEntries) { - const mockTrackEvent = createMockTrackEvent(); - - const Wrapper = ({ children }) => { - const WithoutStore = () => ( - - - - - {children} - - - - - ); - return store ? ( - - - - ) : ( - - ); - }; - - Wrapper.propTypes = { - children: PropTypes.node, - }; - - return render(component, { wrapper: Wrapper }); -} - -export function renderWithProviderAndHistory( - component, - store, - history, - renderer = render, -) { - const mockTrackEvent = createMockTrackEvent(); - - const Wrapper = ({ children }) => { - const WithoutStore = () => ( - - - - - - - {children} - - - - - - - ); - return store ? ( - - - - ) : ( - - ); - }; - - Wrapper.propTypes = { - children: PropTypes.node, - }; - - return { - ...renderer(component, { wrapper: Wrapper }), - history, - }; -} diff --git a/test/lib/render-helpers-navigate.js b/test/lib/render-helpers-navigate.js index dab0203f7c9a..7b59547f4a8d 100644 --- a/test/lib/render-helpers-navigate.js +++ b/test/lib/render-helpers-navigate.js @@ -5,16 +5,32 @@ import { render } from '@testing-library/react'; import { renderHook } from '@testing-library/react-hooks'; import { userEvent } from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; -import { CompatRouter } from 'react-router-dom-v5-compat'; import PropTypes from 'prop-types'; import configureStore from '../../ui/store/store'; import { I18nContext, LegacyI18nProvider } from '../../ui/contexts/i18n'; -import { LegacyMetaMetricsProvider } from '../../ui/contexts/metametrics'; +import { + MetaMetricsContext, + LegacyMetaMetricsProvider, +} from '../../ui/contexts/metametrics'; import { getMessage } from '../../ui/helpers/utils/i18n-helper'; import * as en from '../../app/_locales/en/messages.json'; import { setupInitialStore } from '../../ui'; +import { setBackgroundConnection } from '../../ui/store/background-connection'; import Root from '../../ui/pages'; +// Mock MetaMetrics context for tests +const createMockTrackEvent = ( + getMockTrackEvent = () => () => Promise.resolve(), +) => { + const mockTrackEvent = getMockTrackEvent(); + Object.assign(mockTrackEvent, { + bufferedTrace: () => Promise.resolve(), + bufferedEndTrace: () => Promise.resolve(), + onboardingParentContext: { current: null }, + }); + return mockTrackEvent; +}; + export const I18nProvider = (props) => { const { currentLocale, current, en: eng } = props; @@ -40,17 +56,23 @@ I18nProvider.defaultProps = { children: undefined, }; -function createProviderWrapper(store, pathname = '/') { +function createProviderWrapper( + store, + pathname = '/', + getMockTrackEvent = () => () => Promise.resolve(), +) { + const mockTrackEvent = createMockTrackEvent(getMockTrackEvent); + const Wrapper = ({ children }) => { const container = ( - - - + + + {children} - - - + + + ); @@ -74,10 +96,20 @@ export function renderWithProvider( return renderer(component, { wrapper }); } -export function renderHookWithProvider(hook, state, pathname = '/', Container) { +export function renderHookWithProvider( + hook, + state, + pathname = '/', + Container, + getMockTrackEvent = () => () => Promise.resolve(), +) { const store = state ? configureStore(state) : undefined; - const ProviderWrapper = createProviderWrapper(store, pathname); + const ProviderWrapper = createProviderWrapper( + store, + pathname, + getMockTrackEvent, + ); const wrapper = Container ? ({ children }) => ( @@ -107,6 +139,7 @@ export function renderHookWithProvider(hook, state, pathname = '/', Container) { * @param [state] - The initial state for the store. * @param [pathname] - The initial pathname for the history. * @param [Container] - An optional container component. + * @param {() => () => Promise} [getMockTrackEvent] - A placeholder function for tracking a MetaMetrics event. * @returns {RenderHookResult & { history: History }} The result of the rendered hook and the history object. */ export const renderHookWithProviderTyped = ( @@ -114,7 +147,9 @@ export const renderHookWithProviderTyped = ( state, pathname = '/', Container, -) => renderHookWithProvider(hook, state, pathname, Container); + getMockTrackEvent = () => () => Promise.resolve(), +) => + renderHookWithProvider(hook, state, pathname, Container, getMockTrackEvent); export function renderWithLocalization(component) { const Wrapper = ({ children }) => ( @@ -177,9 +212,12 @@ export async function integrationTestRender(extendedRenderOptions) { ...renderOptions } = extendedRenderOptions; - const store = await setupInitialStore(preloadedState, backgroundConnection, { - activeTab, - }); + // Set up background connection if provided + if (backgroundConnection) { + await setBackgroundConnection(backgroundConnection); + } + + const store = await setupInitialStore(preloadedState, activeTab); return { ...render(, { ...renderOptions }), diff --git a/ui/components/app/account-list-item/account-list-item-component.test.js b/ui/components/app/account-list-item/account-list-item-component.test.js index 7abf73703ea0..22d76c4833cf 100644 --- a/ui/components/app/account-list-item/account-list-item-component.test.js +++ b/ui/components/app/account-list-item/account-list-item-component.test.js @@ -2,7 +2,7 @@ import React from 'react'; import configureStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { EthAccountType } from '@metamask/keyring-api'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods'; import AccountListItem from './account-list-item'; diff --git a/ui/components/app/alert-system/alert-modal/alert-modal.test.tsx b/ui/components/app/alert-system/alert-modal/alert-modal.test.tsx index a63aed9c4101..b0f1f54d73eb 100644 --- a/ui/components/app/alert-system/alert-modal/alert-modal.test.tsx +++ b/ui/components/app/alert-system/alert-modal/alert-modal.test.tsx @@ -7,7 +7,7 @@ import { } from '../../../../../shared/constants/security-provider'; import mockState from '../../../../../test/data/mock-state.json'; import { tEn } from '../../../../../test/lib/i18n-helpers'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts'; import { Severity } from '../../../../helpers/constants/design-system'; import * as useAlertsModule from '../../../../hooks/useAlerts'; diff --git a/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.test.tsx b/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.test.tsx index 2a04855b824e..4589dfe3a744 100644 --- a/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.test.tsx +++ b/ui/components/app/alert-system/confirm-alert-modal/confirm-alert-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { Severity } from '../../../../helpers/constants/design-system'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { ConfirmAlertModalProps, ConfirmAlertModal, diff --git a/ui/components/app/alert-system/contexts/alertActionHandler.test.ts b/ui/components/app/alert-system/contexts/alertActionHandler.test.ts index 85f818fa1ada..ec6b85db356b 100644 --- a/ui/components/app/alert-system/contexts/alertActionHandler.test.ts +++ b/ui/components/app/alert-system/contexts/alertActionHandler.test.ts @@ -1,5 +1,5 @@ import React from 'react'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHook } from '@testing-library/react-hooks'; import { useAlertActionHandler } from './alertActionHandler'; jest.mock('react', () => ({ @@ -9,7 +9,7 @@ jest.mock('react', () => ({ describe('alertActionHandler', () => { it('throws an error if used outside of AlertActionHandlerProvider', () => { - const { result } = renderHookWithProvider(() => useAlertActionHandler()); + const { result } = renderHook(() => useAlertActionHandler()); expect(result.error).toEqual( new Error( 'useAlertActionHandler must be used within an AlertActionHandlerProvider', @@ -23,9 +23,7 @@ describe('alertActionHandler', () => { processAction: mockProcessAction, }); - const { result } = renderHookWithProvider(() => useAlertActionHandler(), { - processAction: mockProcessAction, - }); + const { result } = renderHook(() => useAlertActionHandler()); expect(result.current.processAction).toBe(mockProcessAction); }); diff --git a/ui/components/app/alert-system/contexts/alertMetricsContext.test.tsx b/ui/components/app/alert-system/contexts/alertMetricsContext.test.tsx index 9c7315d12caf..28b04ac487ad 100644 --- a/ui/components/app/alert-system/contexts/alertMetricsContext.test.tsx +++ b/ui/components/app/alert-system/contexts/alertMetricsContext.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHook } from '@testing-library/react-hooks'; import { useAlertMetrics } from './alertMetricsContext'; jest.mock('react', () => ({ @@ -19,7 +19,7 @@ describe('useAlertMetrics', () => { trackInlineAlertClicked: jest.fn(), }); const ALERT_KEY_MOCK = 'testKey'; - const { result } = renderHookWithProvider(useAlertMetrics); + const { result } = renderHook(() => useAlertMetrics()); expect(result.current).toBeDefined(); expect(typeof result.current.trackAlertActionClicked).toBe('function'); @@ -36,7 +36,7 @@ describe('useAlertMetrics', () => { }); it('throws an error if used outside of AlertMetricsProvider', () => { - const { result } = renderHookWithProvider(() => useAlertMetrics()); + const { result } = renderHook(() => useAlertMetrics()); expect(result.error).toEqual( new Error('useAlertMetrics must be used within an AlertMetricsProvider'), ); diff --git a/ui/components/app/alert-system/general-alert/general-alert.test.tsx b/ui/components/app/alert-system/general-alert/general-alert.test.tsx index b76a847752f1..d26d6931d7a7 100644 --- a/ui/components/app/alert-system/general-alert/general-alert.test.tsx +++ b/ui/components/app/alert-system/general-alert/general-alert.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Severity } from '../../../../helpers/constants/design-system'; import { SecurityProvider } from '../../../../../shared/constants/security-provider'; import { Text } from '../../../component-library'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import GeneralAlert, { GeneralAlertProps } from './general-alert'; describe('GeneralAlert', () => { @@ -29,7 +29,7 @@ describe('GeneralAlert', () => { details={details} />, ); - expect(getByText('[seeDetails]')).toBeInTheDocument(); + expect(getByText('See details')).toBeInTheDocument(); }); it('renders the security provider information when provided', () => { @@ -42,6 +42,7 @@ describe('GeneralAlert', () => { />, ); - expect(getByText('[securityProviderPoweredBy]')).toBeInTheDocument(); + expect(getByText('Security Alert')).toBeInTheDocument(); + expect(getByText('Powered by')).toBeInTheDocument(); }); }); diff --git a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx index 2809bc3d59f5..b5dfdc4265e5 100644 --- a/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx +++ b/ui/components/app/alert-system/multiple-alert-modal/multiple-alert-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { Severity } from '../../../../helpers/constants/design-system'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import * as useAlertsModule from '../../../../hooks/useAlerts'; import { diff --git a/ui/components/app/alerts/alerts.js b/ui/components/app/alerts/alerts.js index ebd0cd9f4f83..b2c3de1786aa 100644 --- a/ui/components/app/alerts/alerts.js +++ b/ui/components/app/alerts/alerts.js @@ -1,11 +1,12 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import PropTypes from 'prop-types'; +import { useNavigate } from 'react-router-dom'; import { alertIsOpen as invalidCustomNetworkAlertIsOpen } from '../../../ducks/alerts/invalid-custom-network'; import InvalidCustomNetworkAlert from './invalid-custom-network-alert'; -const Alerts = ({ navigate }) => { +const Alerts = () => { + const navigate = useNavigate(); const _invalidCustomNetworkAlertIsOpen = useSelector( invalidCustomNetworkAlertIsOpen, ); @@ -17,8 +18,4 @@ const Alerts = ({ navigate }) => { return null; }; -Alerts.propTypes = { - navigate: PropTypes.func.isRequired, -}; - export default Alerts; diff --git a/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js b/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js index ccff979f57cd..d829a524d6a4 100644 --- a/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js +++ b/ui/components/app/alerts/unconnected-account-alert/unconnected-account-alert.test.js @@ -7,7 +7,7 @@ import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import { tick } from '../../../../../test/lib/timer-helpers'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../../store/actions'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; diff --git a/ui/components/app/app-loading-spinner/app-loading-spinner.test.js b/ui/components/app/app-loading-spinner/app-loading-spinner.test.js index f56d8b8be655..a91355608130 100644 --- a/ui/components/app/app-loading-spinner/app-loading-spinner.test.js +++ b/ui/components/app/app-loading-spinner/app-loading-spinner.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import AppLoadingSpinner from './app-loading-spinner'; diff --git a/ui/components/app/assets/account-group-balance-change/account-group-balance-change.test.tsx b/ui/components/app/assets/account-group-balance-change/account-group-balance-change.test.tsx index 8e703681d33d..536bbb54db61 100644 --- a/ui/components/app/assets/account-group-balance-change/account-group-balance-change.test.tsx +++ b/ui/components/app/assets/account-group-balance-change/account-group-balance-change.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { TextColor } from '../../../../helpers/constants/design-system'; import { getIsMultichainAccountsState2Enabled } from '../../../../selectors'; import { AccountGroupBalanceChange } from './account-group-balance-change'; diff --git a/ui/components/app/assets/account-group-balance/account-group-balance.test.tsx b/ui/components/app/assets/account-group-balance/account-group-balance.test.tsx index d0720912dc7f..dd9e372f4fc7 100644 --- a/ui/components/app/assets/account-group-balance/account-group-balance.test.tsx +++ b/ui/components/app/assets/account-group-balance/account-group-balance.test.tsx @@ -3,7 +3,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { CaipChainId, Hex } from '@metamask/utils'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { getIntlLocale } from '../../../../ducks/locale/locale'; import { getCurrentCurrency } from '../../../../ducks/metamask/metamask'; import { diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.test.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.test.tsx index 799cc670458c..d52374cacc91 100644 --- a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.test.tsx +++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.test.tsx @@ -12,9 +12,9 @@ import { createMockInternalAccount } from '../../../../../../test/jest/mocks'; import AssetListControlBar from './asset-list-control-bar'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx index e024e2896f1f..7e633e282a2c 100644 --- a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx +++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx @@ -7,7 +7,7 @@ import React, { useCallback, } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Hex, isStrictHexString, diff --git a/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx b/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx index beffbd966fb5..6731a726eb64 100644 --- a/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx +++ b/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { screen, fireEvent } from '@testing-library/react'; import { useSelector } from 'react-redux'; import { setTokenSortConfig } from '../../../../../store/actions'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { getPreferences } from '../../../../../selectors'; import { getCurrentCurrency } from '../../../../../ducks/metamask/metamask'; diff --git a/ui/components/app/assets/defi-list/defi-list.test.tsx b/ui/components/app/assets/defi-list/defi-list.test.tsx index 1270a00ff1a3..d6d192daabc5 100644 --- a/ui/components/app/assets/defi-list/defi-list.test.tsx +++ b/ui/components/app/assets/defi-list/defi-list.test.tsx @@ -4,7 +4,7 @@ import thunk from 'redux-thunk'; import { screen, act, waitFor } from '@testing-library/react'; import { DeFiPositionsControllerState } from '@metamask/assets-controllers'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import DeFiList from './defi-list'; const lidoPosition: DeFiPositionsControllerState['allDeFiPositions'] = { diff --git a/ui/components/app/assets/nfts/nft-default-image/nft-default-image.test.js b/ui/components/app/assets/nfts/nft-default-image/nft-default-image.test.js index 1f4d11ee2c2f..02c95444c300 100644 --- a/ui/components/app/assets/nfts/nft-default-image/nft-default-image.test.js +++ b/ui/components/app/assets/nfts/nft-default-image/nft-default-image.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../../test/data/mock-state.json'; import NftDefaultImage from '.'; diff --git a/ui/components/app/assets/nfts/nft-details/nft-details.test.js b/ui/components/app/assets/nfts/nft-details/nft-details.test.js index 76fa6868d1d4..6649e7559433 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-details.test.js +++ b/ui/components/app/assets/nfts/nft-details/nft-details.test.js @@ -30,9 +30,9 @@ jest.mock('../../../../../helpers/utils/util', () => ({ jest.mock('copy-to-clipboard'); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/app/assets/nfts/nft-details/nft-details.tsx b/ui/components/app/assets/nfts/nft-details/nft-details.tsx index 954b85247ae5..3c11f09bc9e9 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-details.tsx +++ b/ui/components/app/assets/nfts/nft-details/nft-details.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { isEqual } from 'lodash'; import { getTokenTrackerLink, getAccountLink } from '@metamask/etherscan-link'; import { Nft } from '@metamask/assets-controllers'; diff --git a/ui/components/app/assets/nfts/nft-details/nft-full-image.test.js b/ui/components/app/assets/nfts/nft-details/nft-full-image.test.js index 0ef9aa3a111d..e11f2bcb15db 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-full-image.test.js +++ b/ui/components/app/assets/nfts/nft-details/nft-full-image.test.js @@ -23,11 +23,13 @@ const mockAsset = nfts[0].address; const mockId = nfts[0].tokenId; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +const mockUseParams = jest.fn(); +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useNavigationType: () => 'PUSH', + useParams: () => mockUseParams(), }; }); @@ -65,13 +67,11 @@ describe('NFT full image', () => { beforeEach(() => { jest.clearAllMocks(); + mockUseParams.mockReturnValue(mockParams); }); it('should match snapshot', async () => { - const { container } = renderWithProvider( - , - mockStore, - ); + const { container } = renderWithProvider(, mockStore); await waitFor(() => { expect(container).toMatchSnapshot(); @@ -91,10 +91,7 @@ describe('NFT full image', () => { nfts[0].image = images; - const { findByTestId } = renderWithProvider( - , - mockStore, - ); + const { findByTestId } = renderWithProvider(, mockStore); const imageElem = await findByTestId('nft-image'); expect(imageElem).toHaveAttribute('src', mockImageUrl); diff --git a/ui/components/app/assets/nfts/nft-details/nft-full-image.tsx b/ui/components/app/assets/nfts/nft-details/nft-full-image.tsx index 2baf730e9c51..b1e707e1d956 100644 --- a/ui/components/app/assets/nfts/nft-details/nft-full-image.tsx +++ b/ui/components/app/assets/nfts/nft-details/nft-full-image.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate, useNavigationType } from 'react-router-dom-v5-compat'; +import { useNavigate, useNavigationType, useParams } from 'react-router-dom'; import { Nft } from '@metamask/assets-controllers'; import { toHex } from '@metamask/controller-utils'; import { getNftImage, getNftImageAlt } from '../../../../../helpers/utils/nfts'; @@ -35,24 +35,11 @@ import { PREVIOUS_ROUTE, } from '../../../../../helpers/constants/routes'; -type NftFullImageProps = { - params?: { - asset?: string; - id?: string; - }; -}; - -/** - * Component displaying full NFT image - * - * @param options0 - Component props - * @param options0.params - Route parameters including asset and id - */ // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 // eslint-disable-next-line @typescript-eslint/naming-convention -export default function NftFullImage({ params }: NftFullImageProps) { +export default function NftFullImage() { const t = useI18nContext(); - const { asset, id } = params ?? {}; + const { asset, id } = useParams<{ asset: string; id: string }>(); const allNfts = useSelector(getAllNfts); const nfts = Object.values(allNfts).flat() as Nft[]; const nft = nfts.find( diff --git a/ui/components/app/assets/nfts/nft-empty-state/nft-empty-state.test.tsx b/ui/components/app/assets/nfts/nft-empty-state/nft-empty-state.test.tsx index f92281c4ff94..8803e0e08c81 100644 --- a/ui/components/app/assets/nfts/nft-empty-state/nft-empty-state.test.tsx +++ b/ui/components/app/assets/nfts/nft-empty-state/nft-empty-state.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; import thunk from 'redux-thunk'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../../test/data/mock-state.json'; import { ThemeType } from '../../../../../../shared/constants/preferences'; import * as actions from '../../../../../store/actions'; diff --git a/ui/components/app/assets/nfts/nft-options/nft-options.test.js b/ui/components/app/assets/nfts/nft-options/nft-options.test.js index 7d6652f3b9c7..76fa3f4d1910 100644 --- a/ui/components/app/assets/nfts/nft-options/nft-options.test.js +++ b/ui/components/app/assets/nfts/nft-options/nft-options.test.js @@ -1,6 +1,6 @@ import { fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import NftOptions from './nft-options'; describe('NFT Options Component', () => { diff --git a/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx b/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx index ac2ef1b3c79d..955f554ba8fb 100644 --- a/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx +++ b/ui/components/app/assets/nfts/nfts-detection-notice-import-nfts/nfts-detection-notice-import-nfts.tsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { BannerAlert } from '../../../../component-library'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { SECURITY_ROUTE } from '../../../../../helpers/constants/routes'; diff --git a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx index 9b2c57d8ce4c..f851dde76717 100644 --- a/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx +++ b/ui/components/app/assets/nfts/nfts-tab/nfts-tab.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { toHex } from '@metamask/controller-utils'; import { AlignItems, diff --git a/ui/components/app/assets/token-cell/token-cell.test.tsx b/ui/components/app/assets/token-cell/token-cell.test.tsx index 5d23438bd6c7..5371bca644bf 100644 --- a/ui/components/app/assets/token-cell/token-cell.test.tsx +++ b/ui/components/app/assets/token-cell/token-cell.test.tsx @@ -49,9 +49,9 @@ jest.mock('../../../../hooks/useIsOriginalTokenSymbol', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/app/assets/token-cell/token-cell.tsx b/ui/components/app/assets/token-cell/token-cell.tsx index 701aa4d46008..dfac5dd2532c 100644 --- a/ui/components/app/assets/token-cell/token-cell.tsx +++ b/ui/components/app/assets/token-cell/token-cell.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useTokenDisplayInfo } from '../hooks'; import { ButtonSecondary, diff --git a/ui/components/app/balance-empty-state/balance-empty-state.test.tsx b/ui/components/app/balance-empty-state/balance-empty-state.test.tsx index 45561f506869..a6af16b3fcdb 100644 --- a/ui/components/app/balance-empty-state/balance-empty-state.test.tsx +++ b/ui/components/app/balance-empty-state/balance-empty-state.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import configureStore from '../../../store/store'; import { diff --git a/ui/components/app/basic-configuration-modal/basic-configuration-modal.test.tsx b/ui/components/app/basic-configuration-modal/basic-configuration-modal.test.tsx index 390b46f0e8d7..81081a3d7cff 100644 --- a/ui/components/app/basic-configuration-modal/basic-configuration-modal.test.tsx +++ b/ui/components/app/basic-configuration-modal/basic-configuration-modal.test.tsx @@ -32,8 +32,8 @@ jest.mock('react-redux', () => { }); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => mockUseLocation(), })); diff --git a/ui/components/app/basic-configuration-modal/basic-configuration-modal.tsx b/ui/components/app/basic-configuration-modal/basic-configuration-modal.tsx index cc9b92eac0db..96fd48777ffa 100644 --- a/ui/components/app/basic-configuration-modal/basic-configuration-modal.tsx +++ b/ui/components/app/basic-configuration-modal/basic-configuration-modal.tsx @@ -1,5 +1,5 @@ import React, { useContext, useMemo, useState } from 'react'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Display, 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 9a6c6c7fd25d..9e7aeae406e7 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 @@ -6,7 +6,7 @@ import { EditGasModes, GasEstimateTypes, } from '../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../test/data/mock-estimates.json'; import mockState from '../../../../test/data/mock-state.json'; import { GasFeeContextProvider } from '../../../contexts/gasFee'; diff --git a/ui/components/app/clear-metametrics-data/clear-metametrics-data.test.tsx b/ui/components/app/clear-metametrics-data/clear-metametrics-data.test.tsx index 5ce4ac7573dc..cb38dde286db 100644 --- a/ui/components/app/clear-metametrics-data/clear-metametrics-data.test.tsx +++ b/ui/components/app/clear-metametrics-data/clear-metametrics-data.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { fireEvent } from '@testing-library/react'; import configureStore from '../../../store/store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import * as Actions from '../../../store/actions'; import { DELETE_METAMETRICS_DATA_MODAL_CLOSE } from '../../../store/actionConstants'; import ClearMetaMetricsData from './clear-metametrics-data'; diff --git a/ui/components/app/configure-snap-popup/configure-snap-popup.test.tsx b/ui/components/app/configure-snap-popup/configure-snap-popup.test.tsx index 5bd2334e7277..13527173579c 100644 --- a/ui/components/app/configure-snap-popup/configure-snap-popup.test.tsx +++ b/ui/components/app/configure-snap-popup/configure-snap-popup.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths import messages from '../../../../app/_locales/en/messages.json'; diff --git a/ui/components/app/confirm/info/row/address.test.tsx b/ui/components/app/confirm/info/row/address.test.tsx index b9b49cae3d01..7db0113633b7 100644 --- a/ui/components/app/confirm/info/row/address.test.tsx +++ b/ui/components/app/confirm/info/row/address.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { CHAIN_IDS } from '../../../../../../shared/constants/network'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { ConfirmInfoRowAddress } from './address'; import { TEST_ADDRESS } from './constants'; diff --git a/ui/components/app/confirm/info/row/alert-row/alert-row.test.tsx b/ui/components/app/confirm/info/row/alert-row/alert-row.test.tsx index 4a79428deb05..a3eb0c447219 100644 --- a/ui/components/app/confirm/info/row/alert-row/alert-row.test.tsx +++ b/ui/components/app/confirm/info/row/alert-row/alert-row.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { Text } from '../../../../../component-library'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { Severity, TextColor, diff --git a/ui/components/app/confirm/info/row/currency.test.tsx b/ui/components/app/confirm/info/row/currency.test.tsx index addf91b6583d..f43e49ad4e27 100644 --- a/ui/components/app/confirm/info/row/currency.test.tsx +++ b/ui/components/app/confirm/info/row/currency.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { ConfirmInfoRowCurrency } from './currency'; diff --git a/ui/components/app/connected-sites-list/connected-snaps.js b/ui/components/app/connected-sites-list/connected-snaps.js index 291e23e8b04c..c1b071442b9a 100644 --- a/ui/components/app/connected-sites-list/connected-snaps.js +++ b/ui/components/app/connected-sites-list/connected-snaps.js @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Box, IconName, IconSize, Text } from '../../component-library'; import { useI18nContext } from '../../../hooks/useI18nContext'; diff --git a/ui/components/app/connected-status-indicator/connected-status-indicator.test.tsx b/ui/components/app/connected-status-indicator/connected-status-indicator.test.tsx index 208c192ec3ff..4c96b29e8d5c 100644 --- a/ui/components/app/connected-status-indicator/connected-status-indicator.test.tsx +++ b/ui/components/app/connected-status-indicator/connected-status-indicator.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import configureStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { Color, BackgroundColor, diff --git a/ui/components/app/contact-list/contact-list.test.js b/ui/components/app/contact-list/contact-list.test.js index 1beecc17e0fa..a9c48f17cd0c 100644 --- a/ui/components/app/contact-list/contact-list.test.js +++ b/ui/components/app/contact-list/contact-list.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MOCK_ADDRESS_BOOK } from '../../../../test/data/mock-data'; import { createMockInternalAccount } from '../../../../test/jest/mocks'; import ContactList from '.'; diff --git a/ui/components/app/create-new-vault/create-new-vault.test.js b/ui/components/app/create-new-vault/create-new-vault.test.js index fe59b5222321..651b0c75233e 100644 --- a/ui/components/app/create-new-vault/create-new-vault.test.js +++ b/ui/components/app/create-new-vault/create-new-vault.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { screen, fireEvent, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import CreateNewVault from './create-new-vault'; diff --git a/ui/components/app/currency-input/currency-input.test.js b/ui/components/app/currency-input/currency-input.test.js index c7fbd0392860..10016cd76df0 100644 --- a/ui/components/app/currency-input/currency-input.test.js +++ b/ui/components/app/currency-input/currency-input.test.js @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent, waitFor } from '@testing-library/react'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useIsOriginalNativeTokenSymbol } from '../../../hooks/useIsOriginalNativeTokenSymbol'; import CurrencyInput from '.'; diff --git a/ui/components/app/data-deletion-error-modal/data-deletion-error-modal.test.tsx b/ui/components/app/data-deletion-error-modal/data-deletion-error-modal.test.tsx index cbb541f5648e..9fc60b61a423 100644 --- a/ui/components/app/data-deletion-error-modal/data-deletion-error-modal.test.tsx +++ b/ui/components/app/data-deletion-error-modal/data-deletion-error-modal.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { fireEvent } from '@testing-library/react'; import configureStore from '../../../store/store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { DATA_DELETION_ERROR_MODAL_CLOSE } from '../../../store/actionConstants'; import DataDeletionErrorModal from './data-deletion-error-modal'; diff --git a/ui/components/app/detected-token/detected-token-address/detected-token-address.test.js b/ui/components/app/detected-token/detected-token-address/detected-token-address.test.js index cf7c0bade7b6..b64b57fe00b9 100644 --- a/ui/components/app/detected-token/detected-token-address/detected-token-address.test.js +++ b/ui/components/app/detected-token/detected-token-address/detected-token-address.test.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { renderWithProvider, screen } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import DetectedTokenAddress from './detected-token-address'; @@ -11,9 +11,12 @@ describe('DetectedTokenAddress', () => { it('should render the detected token address', async () => { const store = configureStore({}); - renderWithProvider(, store); + const { getByText } = renderWithProvider( + , + store, + ); - expect(screen.getByText('Token address:')).toBeInTheDocument(); - expect(screen.getByText('0xc011a...f2a6f')).toBeInTheDocument(); + expect(getByText('Token address:')).toBeInTheDocument(); + expect(getByText('0xc011a...f2a6f')).toBeInTheDocument(); }); }); diff --git a/ui/components/app/detected-token/detected-token-aggregators/detected-token-aggregators.test.js b/ui/components/app/detected-token/detected-token-aggregators/detected-token-aggregators.test.js index 15f596b45e1c..0b53d9295ac1 100644 --- a/ui/components/app/detected-token/detected-token-aggregators/detected-token-aggregators.test.js +++ b/ui/components/app/detected-token/detected-token-aggregators/detected-token-aggregators.test.js @@ -1,9 +1,6 @@ import * as React from 'react'; -import { - renderWithProvider, - screen, - fireEvent, -} from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../../test/jest'; import configureStore from '../../../../store/store'; import DetectedTokenAggregators from './detected-token-aggregators'; @@ -28,14 +25,17 @@ describe('DetectedTokenAggregators', () => { it('should render the detected token aggregators', async () => { const store = configureStore({}); - renderWithProvider(, store); + const { getByText } = renderWithProvider( + , + store, + ); - expect(screen.getByText('From token lists:')).toBeInTheDocument(); - expect(screen.getByText('Aave, Bancor')).toBeInTheDocument(); - expect(screen.getByText('+ 10 more')).toBeInTheDocument(); - fireEvent.click(screen.getByText('+ 10 more')); + expect(getByText('From token lists:')).toBeInTheDocument(); + expect(getByText('Aave, Bancor')).toBeInTheDocument(); + expect(getByText('+ 10 more')).toBeInTheDocument(); + fireEvent.click(getByText('+ 10 more')); expect( - screen.getByText( + getByText( 'Aave, Bancor, CMC, Crypto.com, CoinGecko, 1inch, Paraswap, PMM, Synthetix, Zapper, Zerion, 0x.', ), ).toBeInTheDocument(); diff --git a/ui/components/app/detected-token/detected-token-details/detected-token-details.test.js b/ui/components/app/detected-token/detected-token-details/detected-token-details.test.js index 1c15944445fb..f7cb64bebe12 100644 --- a/ui/components/app/detected-token/detected-token-details/detected-token-details.test.js +++ b/ui/components/app/detected-token/detected-token-details/detected-token-details.test.js @@ -1,9 +1,6 @@ import * as React from 'react'; -import { - renderWithProvider, - screen, - fireEvent, -} from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../../test/jest'; import configureStore from '../../../../store/store'; import testData from '../../../../../.storybook/test-data'; @@ -75,18 +72,21 @@ describe('DetectedTokenDetails', () => { it('should render the detected token details', async () => { const store = configureStore(testData); - renderWithProvider(, store); + const { getByText } = renderWithProvider( + , + store, + ); - expect(screen.getByText('0 SNX')).toBeInTheDocument(); - expect(screen.getByText('$0')).toBeInTheDocument(); - expect(screen.getByText('Token address:')).toBeInTheDocument(); - expect(screen.getByText('0xc011a...f2a6f')).toBeInTheDocument(); - expect(screen.getByText('From token lists:')).toBeInTheDocument(); - expect(screen.getByText('Aave, Bancor')).toBeInTheDocument(); - expect(screen.getByText('+ 10 more')).toBeInTheDocument(); - fireEvent.click(screen.getByText('+ 10 more')); + expect(getByText('0 SNX')).toBeInTheDocument(); + expect(getByText('$0')).toBeInTheDocument(); + expect(getByText('Token address:')).toBeInTheDocument(); + expect(getByText('0xc011a...f2a6f')).toBeInTheDocument(); + expect(getByText('From token lists:')).toBeInTheDocument(); + expect(getByText('Aave, Bancor')).toBeInTheDocument(); + expect(getByText('+ 10 more')).toBeInTheDocument(); + fireEvent.click(getByText('+ 10 more')); expect( - screen.getByText( + getByText( 'Aave, Bancor, CMC, Crypto.com, CoinGecko, 1inch, Paraswap, PMM, Synthetix, Zapper, Zerion, 0x.', ), ).toBeInTheDocument(); diff --git a/ui/components/app/detected-token/detected-token-values/detected-token-values.test.js b/ui/components/app/detected-token/detected-token-values/detected-token-values.test.js index e94557eac16c..ca01f00bc19d 100644 --- a/ui/components/app/detected-token/detected-token-values/detected-token-values.test.js +++ b/ui/components/app/detected-token/detected-token-values/detected-token-values.test.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { renderWithProvider, screen } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import testData from '../../../../../.storybook/test-data'; @@ -71,9 +71,12 @@ describe('DetectedTokenValues', () => { it('should render the detected token address', async () => { const store = configureStore(testData); - renderWithProvider(, store); + const { getByText } = renderWithProvider( + , + store, + ); - expect(screen.getByText('0 SNX')).toBeInTheDocument(); - expect(screen.getByText('$0')).toBeInTheDocument(); + expect(getByText('0 SNX')).toBeInTheDocument(); + expect(getByText('$0')).toBeInTheDocument(); }); }); diff --git a/ui/components/app/detected-token/detected-token.test.js b/ui/components/app/detected-token/detected-token.test.js index c6b37237ac28..933aaac163f5 100644 --- a/ui/components/app/detected-token/detected-token.test.js +++ b/ui/components/app/detected-token/detected-token.test.js @@ -1,5 +1,6 @@ import * as React from 'react'; -import { renderWithProvider, screen, fireEvent } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import testData from '../../../../.storybook/test-data'; @@ -96,36 +97,39 @@ describe('DetectedToken', () => { setShowDetectedTokens: jest.fn(), }; - renderWithProvider(, store); + const { getByText, getAllByText } = renderWithProvider( + , + store, + ); - expect(screen.getByText('0 LINK')).toBeInTheDocument(); - expect(screen.getByText('0 COMP')).toBeInTheDocument(); - expect(screen.getByText('0 FSW')).toBeInTheDocument(); - expect(screen.getAllByText('$0')).toHaveLength(3); - expect(screen.getAllByText('Token address:')).toHaveLength(3); - expect(screen.getByText('0x51491...986CA')).toBeInTheDocument(); - expect(screen.getByText('0xc00e9...26888')).toBeInTheDocument(); - expect(screen.getByText('0xfffff...126DB')).toBeInTheDocument(); - expect(screen.getAllByText('From token lists:')).toHaveLength(3); - expect(screen.getByText('Aave, Bancor')).toBeInTheDocument(); - expect(screen.getByText('+ 9 more')).toBeInTheDocument(); - fireEvent.click(screen.getByText('+ 9 more')); + expect(getByText('0 LINK')).toBeInTheDocument(); + expect(getByText('0 COMP')).toBeInTheDocument(); + expect(getByText('0 FSW')).toBeInTheDocument(); + expect(getAllByText('$0')).toHaveLength(3); + expect(getAllByText('Token address:')).toHaveLength(3); + expect(getByText('0x51491...986CA')).toBeInTheDocument(); + expect(getByText('0xc00e9...26888')).toBeInTheDocument(); + expect(getByText('0xfffff...126DB')).toBeInTheDocument(); + expect(getAllByText('From token lists:')).toHaveLength(3); + expect(getByText('Aave, Bancor')).toBeInTheDocument(); + expect(getByText('+ 9 more')).toBeInTheDocument(); + fireEvent.click(getByText('+ 9 more')); expect( - screen.getByText( + getByText( 'Aave, Bancor, CMC, Crypto.com, CoinGecko, 1inch, Paraswap, PMM, Zapper, Zerion, 0x.', ), ).toBeInTheDocument(); - expect(screen.getByText('Bancor, CMC')).toBeInTheDocument(); - expect(screen.getByText('+ 8 more')).toBeInTheDocument(); - fireEvent.click(screen.getByText('+ 8 more')); + expect(getByText('Bancor, CMC')).toBeInTheDocument(); + expect(getByText('+ 8 more')).toBeInTheDocument(); + fireEvent.click(getByText('+ 8 more')); expect( - screen.getByText( + getByText( 'Bancor, CMC, Crypto.com, CoinGecko, 1inch, Paraswap, PMM, Zapper, Zerion, 0x.', ), ).toBeInTheDocument(); - expect(screen.getByText('CoinGecko, 1inch')).toBeInTheDocument(); - expect(screen.getByText('+ 1 more')).toBeInTheDocument(); - fireEvent.click(screen.getByText('+ 1 more')); - expect(screen.getByText('CoinGecko, 1inch, Lifi.')).toBeInTheDocument(); + expect(getByText('CoinGecko, 1inch')).toBeInTheDocument(); + expect(getByText('+ 1 more')).toBeInTheDocument(); + fireEvent.click(getByText('+ 1 more')); + expect(getByText('CoinGecko, 1inch, Lifi.')).toBeInTheDocument(); }); }); diff --git a/ui/components/app/flask/experimental-area/experimental-area.js b/ui/components/app/flask/experimental-area/experimental-area.js index 405105c95aa2..9bfb8243b486 100644 --- a/ui/components/app/flask/experimental-area/experimental-area.js +++ b/ui/components/app/flask/experimental-area/experimental-area.js @@ -1,5 +1,5 @@ import React, { Fragment, useContext } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import PropTypes from 'prop-types'; import { I18nContext } from '../../../../contexts/i18n'; import { Button, ButtonVariant } from '../../../component-library'; diff --git a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js index 2658b3ceca15..949c795b3e6c 100644 --- a/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js +++ b/ui/components/app/hold-to-reveal-button/hold-to-reveal-button.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { render, fireEvent, waitFor } from '@testing-library/react'; import configureMockState from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { MetaMetricsEventCategory, diff --git a/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.test.tsx b/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.test.tsx index 11158bbad6e5..0a71f3998f20 100644 --- a/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.test.tsx +++ b/ui/components/app/identity/backup-and-sync-features-toggles/backup-and-sync-features-toggles.test.tsx @@ -6,7 +6,7 @@ import { BACKUPANDSYNC_FEATURES } from '@metamask/profile-sync-controller/user-s import * as useBackupAndSyncHook from '../../../../hooks/identity/useBackupAndSync/useBackupAndSync'; import { MetamaskIdentityProvider } from '../../../../contexts/identity'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { BackupAndSyncFeaturesToggles, backupAndSyncFeaturesTogglesTestIds, diff --git a/ui/components/app/identity/backup-and-sync-toggle/backup-and-sync-toggle.test.tsx b/ui/components/app/identity/backup-and-sync-toggle/backup-and-sync-toggle.test.tsx index 4f8d8f12002e..e21bcee19ef6 100644 --- a/ui/components/app/identity/backup-and-sync-toggle/backup-and-sync-toggle.test.tsx +++ b/ui/components/app/identity/backup-and-sync-toggle/backup-and-sync-toggle.test.tsx @@ -8,7 +8,7 @@ import * as useBackupAndSyncHook from '../../../../hooks/identity/useBackupAndSy import { CONFIRM_TURN_ON_BACKUP_AND_SYNC_MODAL_NAME } from '../../modals/identity'; import { showModal } from '../../../../store/actions'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { BackupAndSyncToggle, backupAndSyncToggleTestIds, diff --git a/ui/components/app/import-token/network-filter-import-token/index.test.tsx b/ui/components/app/import-token/network-filter-import-token/index.test.tsx index ba4129b19e9d..56cceff4b0a9 100644 --- a/ui/components/app/import-token/network-filter-import-token/index.test.tsx +++ b/ui/components/app/import-token/network-filter-import-token/index.test.tsx @@ -3,7 +3,7 @@ import configureStore from 'redux-mock-store'; import { screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import { useSelector } from 'react-redux'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { getIsTokenNetworkFilterEqualCurrentNetwork } from '../../../../selectors/selectors'; import { getNetworkConfigurationsByChainId } from '../../../../../shared/modules/selectors/networks'; diff --git a/ui/components/app/import-token/network-filter-import-token/network-filter-dropdown/network-filter-drop-down-item/index.test.tsx b/ui/components/app/import-token/network-filter-import-token/network-filter-dropdown/network-filter-drop-down-item/index.test.tsx index c5257c0ee36d..b2364e10fc76 100644 --- a/ui/components/app/import-token/network-filter-import-token/network-filter-dropdown/network-filter-drop-down-item/index.test.tsx +++ b/ui/components/app/import-token/network-filter-import-token/network-filter-dropdown/network-filter-drop-down-item/index.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { getCurrentNetwork } from '../../../../../../selectors'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { getNetworkConfigurationsByChainId } from '../../../../../../../shared/modules/selectors/networks'; import { NetworkFilterDropdownItem } from '.'; diff --git a/ui/components/app/import-token/network-selector-custom-import/index.test.tsx b/ui/components/app/import-token/network-selector-custom-import/index.test.tsx index 5963211aaa69..0a9bbaf430b4 100644 --- a/ui/components/app/import-token/network-selector-custom-import/index.test.tsx +++ b/ui/components/app/import-token/network-selector-custom-import/index.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureStore from 'redux-mock-store'; import { fireEvent, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { NetworkSelectorCustomImport } from '.'; diff --git a/ui/components/app/import-token/token-list/token-list.component.test.tsx b/ui/components/app/import-token/token-list/token-list.component.test.tsx index ce2545df36da..b03be62df6e9 100644 --- a/ui/components/app/import-token/token-list/token-list.component.test.tsx +++ b/ui/components/app/import-token/token-list/token-list.component.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { screen } from '@testing-library/react'; import * as bridgeControllerModule from '@metamask/bridge-controller'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import * as assetUtilsModule from '../../../../../shared/lib/asset-utils'; import * as utilModule from '../../../../helpers/utils/util'; diff --git a/ui/components/app/modal/modal-content/modal-content.component.test.js b/ui/components/app/modal/modal-content/modal-content.component.test.js index 0a97016308aa..94f85f4be038 100644 --- a/ui/components/app/modal/modal-content/modal-content.component.test.js +++ b/ui/components/app/modal/modal-content/modal-content.component.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import ModalContent from '.'; describe('ModalContent Component', () => { diff --git a/ui/components/app/modal/modal.component.test.js b/ui/components/app/modal/modal.component.test.js index 21fae44f4fa5..f503ca912fe3 100644 --- a/ui/components/app/modal/modal.component.test.js +++ b/ui/components/app/modal/modal.component.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import Modal from './modal.component'; describe('Modal Component', () => { diff --git a/ui/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js b/ui/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js index 8966fa01b749..b4a153717624 100644 --- a/ui/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js +++ b/ui/components/app/modals/cancel-transaction/cancel-transaction-gas-fee/cancel-transaction-gas-fee.component.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { mockNetworkState } from '../../../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../../../shared/constants/network'; import CancelTransactionGasFee from './cancel-transaction-gas-fee.component'; diff --git a/ui/components/app/modals/confirm-delete-network/confirm-delete-network.test.js b/ui/components/app/modals/confirm-delete-network/confirm-delete-network.test.js index bc27c94bfec0..29ca2970ba38 100644 --- a/ui/components/app/modals/confirm-delete-network/confirm-delete-network.test.js +++ b/ui/components/app/modals/confirm-delete-network/confirm-delete-network.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import ConfirmDeleteNetwork from '.'; @@ -42,7 +42,7 @@ describe('Confirm Delete Network', () => { , ); - fireEvent.click(queryByText('[cancel]')); + fireEvent.click(queryByText('Cancel')); expect(props.removeNetwork).not.toHaveBeenCalled(); expect(props.onConfirm).not.toHaveBeenCalled(); @@ -55,7 +55,7 @@ describe('Confirm Delete Network', () => { , ); - fireEvent.click(queryByText('[delete]')); + fireEvent.click(queryByText('Delete')); await waitFor(() => { expect(props.removeNetwork).toHaveBeenCalled(); diff --git a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.test.js b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.test.js index 4e19851fff49..a536a3a7306b 100644 --- a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.test.js +++ b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.test.js @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { BtcAccountType } from '@metamask/keyring-api'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { createMockInternalAccount } from '../../../../../test/jest/mocks'; import { addressSummary } from '../../../../helpers/utils/util'; import { getMultichainAccountUrl } from '../../../../helpers/utils/multichain/blockExplorer'; diff --git a/ui/components/app/modals/confirm-reset-account/__snapshots__/confirm-reset-account.test.js.snap b/ui/components/app/modals/confirm-reset-account/__snapshots__/confirm-reset-account.test.js.snap index 967f6aa6e3b3..6610f8035658 100644 --- a/ui/components/app/modals/confirm-reset-account/__snapshots__/confirm-reset-account.test.js.snap +++ b/ui/components/app/modals/confirm-reset-account/__snapshots__/confirm-reset-account.test.js.snap @@ -14,12 +14,12 @@ exports[`Confirm Reset Account should match snapshot 1`] = ` @@ -29,12 +29,12 @@ exports[`Confirm Reset Account should match snapshot 1`] = ` diff --git a/ui/components/app/modals/confirm-reset-account/confirm-reset-account.test.js b/ui/components/app/modals/confirm-reset-account/confirm-reset-account.test.js index 84596a6f556f..3b3d4e884b30 100644 --- a/ui/components/app/modals/confirm-reset-account/confirm-reset-account.test.js +++ b/ui/components/app/modals/confirm-reset-account/confirm-reset-account.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import ConfirmResetAccount from '.'; describe('Confirm Reset Account', () => { @@ -18,22 +18,22 @@ describe('Confirm Reset Account', () => { }); it('hides modal when nevermind button is clicked', () => { - const { queryByText } = renderWithProvider( + const { getByText } = renderWithProvider( , ); - fireEvent.click(queryByText('[nevermind]')); + fireEvent.click(getByText('Nevermind')); expect(props.resetAccount).not.toHaveBeenCalled(); expect(props.hideModal).toHaveBeenCalled(); }); it('resets account and hides modal when reset button is clicked', async () => { - const { queryByText } = renderWithProvider( + const { getByText } = renderWithProvider( , ); - fireEvent.click(queryByText('[clear]')); + await fireEvent.click(getByText('Clear')); expect(props.resetAccount).toHaveBeenCalled(); expect(props.hideModal).toHaveBeenCalled(); diff --git a/ui/components/app/modals/convert-token-to-nft-modal/convert-token-to-nft-modal.js b/ui/components/app/modals/convert-token-to-nft-modal/convert-token-to-nft-modal.js index 42605d121541..85e48e3177f6 100644 --- a/ui/components/app/modals/convert-token-to-nft-modal/convert-token-to-nft-modal.js +++ b/ui/components/app/modals/convert-token-to-nft-modal/convert-token-to-nft-modal.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import Modal from '../../modal'; import { Text } from '../../../component-library/text'; diff --git a/ui/components/app/modals/customize-nonce/customize-nonce.test.js b/ui/components/app/modals/customize-nonce/customize-nonce.test.js index a11413ddfaa4..34880ae5fd31 100644 --- a/ui/components/app/modals/customize-nonce/customize-nonce.test.js +++ b/ui/components/app/modals/customize-nonce/customize-nonce.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import CustomizeNonce from '.'; const mockHideModal = jest.fn(); diff --git a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.test.js b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.test.js index cde1f407dfcc..94adb3d3d5da 100644 --- a/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.test.js +++ b/ui/components/app/modals/hold-to-reveal-modal/hold-to-reveal-modal.test.js @@ -13,7 +13,7 @@ import { // eslint-disable-next-line import/no-restricted-paths } from '../../../../../app/_locales/en/messages.json'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import HoldToRevealModal from '.'; diff --git a/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.test.tsx b/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.test.tsx index 75f0c72ea075..80a62e736b0c 100644 --- a/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.test.tsx +++ b/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.test.tsx @@ -27,9 +27,9 @@ jest.mock('react-redux', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.tsx b/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.tsx index b94c4a508385..d47c464b8e44 100644 --- a/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.tsx +++ b/ui/components/app/modals/identity/turn-on-backup-and-sync-modal/turn-on-backup-and-sync-modal.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { BACKUPANDSYNC_FEATURES } from '@metamask/profile-sync-controller/user-storage'; import { useModalProps } from '../../../../../hooks/useModalProps'; import { diff --git a/ui/components/app/modals/keyring-snap-removal-modal/keyring-snap-removal-result-modal.test.tsx b/ui/components/app/modals/keyring-snap-removal-modal/keyring-snap-removal-result-modal.test.tsx index 9f8536ce81c2..ae5c054107b6 100644 --- a/ui/components/app/modals/keyring-snap-removal-modal/keyring-snap-removal-result-modal.test.tsx +++ b/ui/components/app/modals/keyring-snap-removal-modal/keyring-snap-removal-result-modal.test.tsx @@ -1,11 +1,8 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockStore from '../../../../../test/data/mock-state.json'; -import { - fireEvent, - renderWithProvider, - waitFor, -} from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; +import { fireEvent, waitFor } from '../../../../../test/jest'; import KeyringSnapRemovalResult from './keyring-snap-removal-result-modal'; const mockOnClose = jest.fn(); diff --git a/ui/components/app/modals/multichain-accounts/intro-modal/multichain-account-intro-modal.container.tsx b/ui/components/app/modals/multichain-accounts/intro-modal/multichain-account-intro-modal.container.tsx index 5ab49b0d64ca..4ee1bb8bfe3d 100644 --- a/ui/components/app/modals/multichain-accounts/intro-modal/multichain-account-intro-modal.container.tsx +++ b/ui/components/app/modals/multichain-accounts/intro-modal/multichain-account-intro-modal.container.tsx @@ -6,7 +6,7 @@ import React, { useMemo, } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { captureException } from '../../../../../../shared/lib/sentry'; diff --git a/ui/components/app/modals/new-account-modal/new-account-modal.test.tsx b/ui/components/app/modals/new-account-modal/new-account-modal.test.tsx index bacf4f6a2d0d..5e6e4380b9ce 100644 --- a/ui/components/app/modals/new-account-modal/new-account-modal.test.tsx +++ b/ui/components/app/modals/new-account-modal/new-account-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import thunk from 'redux-thunk'; import { waitFor, fireEvent } from '@testing-library/react'; import configureStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths diff --git a/ui/components/app/modals/reject-transactions/__snapshots__/reject-transactions.test.js.snap b/ui/components/app/modals/reject-transactions/__snapshots__/reject-transactions.test.js.snap index 3910d916431e..f2f3991261fc 100644 --- a/ui/components/app/modals/reject-transactions/__snapshots__/reject-transactions.test.js.snap +++ b/ui/components/app/modals/reject-transactions/__snapshots__/reject-transactions.test.js.snap @@ -11,7 +11,7 @@ exports[`Reject Transactions Model should match snapshot 1`] = ` @@ -35,12 +35,12 @@ exports[`Reject Transactions Model should match snapshot 1`] = ` diff --git a/ui/components/app/modals/reject-transactions/reject-transactions.test.js b/ui/components/app/modals/reject-transactions/reject-transactions.test.js index ce61a0c04bb3..54149c8f393f 100644 --- a/ui/components/app/modals/reject-transactions/reject-transactions.test.js +++ b/ui/components/app/modals/reject-transactions/reject-transactions.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import RejectTransactionsModal from '.'; describe('Reject Transactions Model', () => { @@ -23,7 +23,7 @@ describe('Reject Transactions Model', () => { , ); - fireEvent.click(queryByText('[cancel]')); + fireEvent.click(queryByText('Cancel')); expect(props.onSubmit).not.toHaveBeenCalled(); expect(props.hideModal).toHaveBeenCalled(); @@ -34,7 +34,7 @@ describe('Reject Transactions Model', () => { , ); - fireEvent.click(queryByText('[rejectAll]')); + fireEvent.click(queryByText('Reject all')); await waitFor(() => { expect(props.onSubmit).toHaveBeenCalled(); diff --git a/ui/components/app/modals/transaction-already-confirmed/transaction-already-confirmed.test.tsx b/ui/components/app/modals/transaction-already-confirmed/transaction-already-confirmed.test.tsx index 7c04a452fbc2..74fdfe93b0e6 100644 --- a/ui/components/app/modals/transaction-already-confirmed/transaction-already-confirmed.test.tsx +++ b/ui/components/app/modals/transaction-already-confirmed/transaction-already-confirmed.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockStore from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import TransactionAlreadyConfirmed from '.'; const getStoreWithModalData = () => { diff --git a/ui/components/app/modals/transaction-confirmed/__snapshots__/transaction-confirmed.test.js.snap b/ui/components/app/modals/transaction-confirmed/__snapshots__/transaction-confirmed.test.js.snap index af17bbc07d58..7aa476225513 100644 --- a/ui/components/app/modals/transaction-confirmed/__snapshots__/transaction-confirmed.test.js.snap +++ b/ui/components/app/modals/transaction-confirmed/__snapshots__/transaction-confirmed.test.js.snap @@ -18,12 +18,12 @@ exports[`Transaction Confirmed should match snapshot 1`] = `

- [confirmed]! + Confirmed!

- [initialTransactionConfirmed] + Your initial transaction was confirmed by the network. Click OK to go back.

@@ -33,7 +33,7 @@ exports[`Transaction Confirmed should match snapshot 1`] = ` diff --git a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.test.js b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.test.js index 411324f4b7ac..162ca28e9d06 100644 --- a/ui/components/app/modals/transaction-confirmed/transaction-confirmed.test.js +++ b/ui/components/app/modals/transaction-confirmed/transaction-confirmed.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import TransactionConfirmed from '.'; describe('Transaction Confirmed', () => { @@ -22,7 +22,7 @@ describe('Transaction Confirmed', () => { , ); - fireEvent.click(queryByText('[ok]')); + fireEvent.click(queryByText('Ok')); expect(props.onSubmit).toHaveBeenCalled(); expect(props.hideModal).toHaveBeenCalled(); diff --git a/ui/components/app/modals/turn-on-metamask-notifications/turn-on-metamask-notifications.tsx b/ui/components/app/modals/turn-on-metamask-notifications/turn-on-metamask-notifications.tsx index 4427921e8195..8cf7e4d1235e 100644 --- a/ui/components/app/modals/turn-on-metamask-notifications/turn-on-metamask-notifications.tsx +++ b/ui/components/app/modals/turn-on-metamask-notifications/turn-on-metamask-notifications.tsx @@ -1,6 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { I18nContext } from '../../../../contexts/i18n'; import { useModalProps } from '../../../../hooks/useModalProps'; import { useMetamaskNotificationsContext } from '../../../../contexts/metamask-notifications/metamask-notifications'; diff --git a/ui/components/app/modals/visit-support-data-consent-modal/visit-support-data.test.tsx b/ui/components/app/modals/visit-support-data-consent-modal/visit-support-data.test.tsx index dbc29b90a1ac..aaca10b7eadc 100644 --- a/ui/components/app/modals/visit-support-data-consent-modal/visit-support-data.test.tsx +++ b/ui/components/app/modals/visit-support-data-consent-modal/visit-support-data.test.tsx @@ -6,7 +6,7 @@ import thunk from 'redux-thunk'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { openWindow } from '../../../../helpers/utils/window'; import { SUPPORT_LINK } from '../../../../../shared/lib/ui-utils'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { MetaMetricsContextProp, diff --git a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx index 1b1109de189f..9f33d47ce1a4 100644 --- a/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx +++ b/ui/components/app/multichain-transaction-details-modal/multichain-transaction-details-modal.test.tsx @@ -7,7 +7,7 @@ import { } from '@metamask/keyring-api'; import { screen, fireEvent } from '@testing-library/react'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MOCK_ACCOUNT_SOLANA_MAINNET, MOCK_ACCOUNT_BIP122_P2WPKH, diff --git a/ui/components/app/name/name-details/name-details.test.tsx b/ui/components/app/name/name-details/name-details.test.tsx index 8c63c8dc6bff..452f59956905 100644 --- a/ui/components/app/name/name-details/name-details.test.tsx +++ b/ui/components/app/name/name-details/name-details.test.tsx @@ -9,7 +9,7 @@ import { MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { mockNetworkState } from '../../../../../test/stub/networks'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { getDomainResolutions } from '../../../../ducks/domains'; diff --git a/ui/components/app/name/name-details/name-display.test.tsx b/ui/components/app/name/name-details/name-display.test.tsx index 734e7e2a50eb..bdaeb8607cde 100644 --- a/ui/components/app/name/name-details/name-display.test.tsx +++ b/ui/components/app/name/name-details/name-display.test.tsx @@ -3,7 +3,7 @@ import { NameType } from '@metamask/name-controller'; import { useDispatch, useSelector } from 'react-redux'; import { useDisplayName } from '../../../../hooks/useDisplayName'; import { TrustSignalDisplayState } from '../../../../hooks/useTrustSignals'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { shortenAddress } from '../../../../helpers/utils/util'; import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils'; import NameDisplay from './name-display'; diff --git a/ui/components/app/name/name.test.tsx b/ui/components/app/name/name.test.tsx index bd59aad5169e..29e0519c53ea 100644 --- a/ui/components/app/name/name.test.tsx +++ b/ui/components/app/name/name.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { NameType } from '@metamask/name-controller'; import { fireEvent } from '@testing-library/react'; import configureStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, diff --git a/ui/components/app/network-connection-banner/network-connection-banner.test.tsx b/ui/components/app/network-connection-banner/network-connection-banner.test.tsx index 1809b66f0eee..d10e7efdb3c5 100644 --- a/ui/components/app/network-connection-banner/network-connection-banner.test.tsx +++ b/ui/components/app/network-connection-banner/network-connection-banner.test.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { useNavigate } from 'react-router-dom-v5-compat'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useNetworkConnectionBanner } from '../../../hooks/useNetworkConnectionBanner'; import { setEditedNetwork } from '../../../store/actions'; @@ -22,8 +21,10 @@ jest.mock('../../../hooks/useNetworkConnectionBanner', () => ({ useNetworkConnectionBanner: jest.fn(), })); -jest.mock('react-router-dom-v5-compat', () => ({ - useNavigate: jest.fn(), +const mockUseNavigate = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockUseNavigate, })); jest.mock('../../../hooks/useTheme', () => ({ @@ -31,13 +32,11 @@ jest.mock('../../../hooks/useTheme', () => ({ })); const mockUseNetworkConnectionBanner = jest.mocked(useNetworkConnectionBanner); -const mockUseNavigate = jest.mocked(useNavigate); const mockSetEditedNetwork = jest.mocked(setEditedNetwork); describe('NetworkConnectionBanner', () => { beforeEach(() => { jest.clearAllMocks(); - mockUseNavigate.mockReturnValue(jest.fn()); }); describe('when the status of the banner is "degraded"', () => { @@ -96,8 +95,6 @@ describe('NetworkConnectionBanner', () => { trackNetworkBannerEvent: jest.fn(), }); const store = configureStore({}); - const navigateMock = jest.fn(); - mockUseNavigate.mockReturnValue(navigateMock); const { getByText } = renderWithProvider( , @@ -109,7 +106,7 @@ describe('NetworkConnectionBanner', () => { chainId: '0x1', trackRpcUpdateFromBanner: true, }); - expect(navigateMock).toHaveBeenCalledWith('/settings/networks'); + expect(mockUseNavigate).toHaveBeenCalledWith('/settings/networks'); }); it('creates a metrics event', () => { @@ -206,8 +203,6 @@ describe('NetworkConnectionBanner', () => { trackNetworkBannerEvent: jest.fn(), }); const store = configureStore({}); - const navigateMock = jest.fn(); - mockUseNavigate.mockReturnValue(navigateMock); const { getByText } = renderWithProvider( , @@ -219,7 +214,7 @@ describe('NetworkConnectionBanner', () => { chainId: '0x1', trackRpcUpdateFromBanner: true, }); - expect(navigateMock).toHaveBeenCalledWith('/settings/networks'); + expect(mockUseNavigate).toHaveBeenCalledWith('/settings/networks'); }); it('creates a metrics event', () => { diff --git a/ui/components/app/network-connection-banner/network-connection-banner.tsx b/ui/components/app/network-connection-banner/network-connection-banner.tsx index 4bc6fa3a3899..60f270480704 100644 --- a/ui/components/app/network-connection-banner/network-connection-banner.tsx +++ b/ui/components/app/network-connection-banner/network-connection-banner.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { diff --git a/ui/components/app/password-outdated-modal/password-outdated-modal.tsx b/ui/components/app/password-outdated-modal/password-outdated-modal.tsx index 986090c5331b..7f91454e4dbf 100644 --- a/ui/components/app/password-outdated-modal/password-outdated-modal.tsx +++ b/ui/components/app/password-outdated-modal/password-outdated-modal.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { AlignItems, diff --git a/ui/components/app/permission-cell/permission-cell.test.js b/ui/components/app/permission-cell/permission-cell.test.js index 515275d1db46..5adc327fc0bd 100644 --- a/ui/components/app/permission-cell/permission-cell.test.js +++ b/ui/components/app/permission-cell/permission-cell.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import PermissionCell from './permission-cell'; diff --git a/ui/components/app/permission-connect-header/permission-connect-header.test.js b/ui/components/app/permission-connect-header/permission-connect-header.test.js index b2119db0829d..a7ca2d0de0c5 100644 --- a/ui/components/app/permission-connect-header/permission-connect-header.test.js +++ b/ui/components/app/permission-connect-header/permission-connect-header.test.js @@ -1,16 +1,16 @@ import React from 'react'; import { screen } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import PermissionConnectHeader from './permission-connect-header'; const STORE_MOCK = configureMockStore()({ metamask: { pendingApprovals: {} } }); const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/components/app/qr-hardware-popover/base-reader.test.js b/ui/components/app/qr-hardware-popover/base-reader.test.js index 747f90bdbd3f..d815e55e9821 100644 --- a/ui/components/app/qr-hardware-popover/base-reader.test.js +++ b/ui/components/app/qr-hardware-popover/base-reader.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import WebcamUtils from '../../../helpers/utils/webcam-utils'; import BaseReader from './base-reader'; import EnhancedReader from './enhanced-reader'; diff --git a/ui/components/app/recovery-phrase-reminder/recovery-phrase-reminder.js b/ui/components/app/recovery-phrase-reminder/recovery-phrase-reminder.js index 006a4343c02c..90ca7273dff0 100644 --- a/ui/components/app/recovery-phrase-reminder/recovery-phrase-reminder.js +++ b/ui/components/app/recovery-phrase-reminder/recovery-phrase-reminder.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useI18nContext } from '../../../hooks/useI18nContext'; // Helpers import { diff --git a/ui/components/app/selected-account/selected-account-component.test.js b/ui/components/app/selected-account/selected-account-component.test.js index 7bdfcdb49f92..7569b78194da 100644 --- a/ui/components/app/selected-account/selected-account-component.test.js +++ b/ui/components/app/selected-account/selected-account-component.test.js @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import copyToClipboard from 'copy-to-clipboard'; import { fireEvent, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { COPY_OPTIONS } from '../../../../shared/constants/copy'; import SelectedAccount from '.'; diff --git a/ui/components/app/shield-entry-modal/shield-entry-modal.test.tsx b/ui/components/app/shield-entry-modal/shield-entry-modal.test.tsx index 8de7b9abd42d..785f2d76e734 100644 --- a/ui/components/app/shield-entry-modal/shield-entry-modal.test.tsx +++ b/ui/components/app/shield-entry-modal/shield-entry-modal.test.tsx @@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { fireEvent, waitFor } from '@testing-library/react'; import { SubscriptionUserEvent } from '@metamask/subscription-controller'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { SHIELD_PLAN_ROUTE } from '../../../helpers/constants/routes'; import MockState from '../../../../test/data/mock-state.json'; @@ -11,9 +11,9 @@ import ShieldEntryModal from './shield-entry-modal'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/components/app/shield-entry-modal/shield-entry-modal.tsx b/ui/components/app/shield-entry-modal/shield-entry-modal.tsx index 80796a309e26..3465f52f7441 100644 --- a/ui/components/app/shield-entry-modal/shield-entry-modal.tsx +++ b/ui/components/app/shield-entry-modal/shield-entry-modal.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useLocation, useNavigate } from 'react-router-dom-v5-compat'; +import { useLocation, useNavigate } from 'react-router-dom'; import { COHORT_NAMES, MODAL_TYPE, diff --git a/ui/components/app/snaps/copyable/copyable.test.js b/ui/components/app/snaps/copyable/copyable.test.js index 58734632a373..b9c6e2236c02 100644 --- a/ui/components/app/snaps/copyable/copyable.test.js +++ b/ui/components/app/snaps/copyable/copyable.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; import { useCopyToClipboard } from '../../../../hooks/useCopyToClipboard'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { Copyable } from './copyable'; jest.mock('../../../../hooks/useCopyToClipboard'); diff --git a/ui/components/app/snaps/keyring-snap-removal-warning/keyring-snap-removal-warning.test.tsx b/ui/components/app/snaps/keyring-snap-removal-warning/keyring-snap-removal-warning.test.tsx index 9aadb305df00..e78c717fa83e 100644 --- a/ui/components/app/snaps/keyring-snap-removal-warning/keyring-snap-removal-warning.test.tsx +++ b/ui/components/app/snaps/keyring-snap-removal-warning/keyring-snap-removal-warning.test.tsx @@ -4,7 +4,7 @@ import configureMockStore from 'redux-mock-store'; import { Snap } from '@metamask/snaps-utils'; import { userEvent } from '@testing-library/user-event'; import mockStore from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths diff --git a/ui/components/app/snaps/snap-home-page/snap-home-renderer.js b/ui/components/app/snaps/snap-home-page/snap-home-renderer.js index b89f52faf344..150d6439385b 100644 --- a/ui/components/app/snaps/snap-home-page/snap-home-renderer.js +++ b/ui/components/app/snaps/snap-home-page/snap-home-renderer.js @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Box, Text } from '../../../component-library'; import { SnapUIRenderer } from '../snap-ui-renderer'; diff --git a/ui/components/app/snaps/snap-list-item/snap-list-item.test.js b/ui/components/app/snaps/snap-list-item/snap-list-item.test.js index d818b0c3f80f..66ebf1208885 100644 --- a/ui/components/app/snaps/snap-list-item/snap-list-item.test.js +++ b/ui/components/app/snaps/snap-list-item/snap-list-item.test.js @@ -2,7 +2,7 @@ import * as React from 'react'; import { screen } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import SnapListItem from '.'; diff --git a/ui/components/app/snaps/snap-permission-adapter/snap-permission-adapter.test.js b/ui/components/app/snaps/snap-permission-adapter/snap-permission-adapter.test.js index 4ae5f59a7ab7..bd3e6a353549 100644 --- a/ui/components/app/snaps/snap-permission-adapter/snap-permission-adapter.test.js +++ b/ui/components/app/snaps/snap-permission-adapter/snap-permission-adapter.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { mockNetworkState } from '../../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; diff --git a/ui/components/app/snaps/snap-permission-cell/snap-permission-cell.test.js b/ui/components/app/snaps/snap-permission-cell/snap-permission-cell.test.js index 1a9abbdfec06..d14b1281ae53 100644 --- a/ui/components/app/snaps/snap-permission-cell/snap-permission-cell.test.js +++ b/ui/components/app/snaps/snap-permission-cell/snap-permission-cell.test.js @@ -2,7 +2,7 @@ import { screen } from '@testing-library/react'; import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import SnapPermissionCell from './snap-permission-cell'; diff --git a/ui/components/app/snaps/snap-permissions-list/snap-permissions-list.test.js b/ui/components/app/snaps/snap-permissions-list/snap-permissions-list.test.js index c8529a5be9e9..caba643109cc 100644 --- a/ui/components/app/snaps/snap-permissions-list/snap-permissions-list.test.js +++ b/ui/components/app/snaps/snap-permissions-list/snap-permissions-list.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import { mockNetworkState } from '../../../../../test/stub/networks'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import SnapPermissionsList from './snap-permissions-list'; diff --git a/ui/components/app/snaps/snap-privacy-warning/snap-privacy-warning.test.js b/ui/components/app/snaps/snap-privacy-warning/snap-privacy-warning.test.js index 517b23730932..e81a340ad37d 100644 --- a/ui/components/app/snaps/snap-privacy-warning/snap-privacy-warning.test.js +++ b/ui/components/app/snaps/snap-privacy-warning/snap-privacy-warning.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import SnapPrivacyWarning from './snap-privacy-warning'; describe('Snap Privacy Warning Popover', () => { diff --git a/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx b/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx index a76f1b386124..333505a18f9e 100644 --- a/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx +++ b/ui/components/app/snaps/snap-settings-page/snap-settings-renderer.tsx @@ -1,6 +1,6 @@ import React, { FunctionComponent, useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { deleteInterface } from '../../../../store/actions'; diff --git a/ui/components/app/snaps/snap-ui-address/snap-ui-address.test.tsx b/ui/components/app/snaps/snap-ui-address/snap-ui-address.test.tsx index e7c18a70a7c5..adecede3c948 100644 --- a/ui/components/app/snaps/snap-ui-address/snap-ui-address.test.tsx +++ b/ui/components/app/snaps/snap-ui-address/snap-ui-address.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { SnapUIAddress } from './snap-ui-address'; const mockStore = configureMockStore([])(mockState); diff --git a/ui/components/app/snaps/snap-ui-renderer/test-utils.tsx b/ui/components/app/snaps/snap-ui-renderer/test-utils.tsx index 276a310d5b16..4a8b46cc726f 100644 --- a/ui/components/app/snaps/snap-ui-renderer/test-utils.tsx +++ b/ui/components/app/snaps/snap-ui-renderer/test-utils.tsx @@ -4,7 +4,7 @@ import { RenderResult } from '@testing-library/react'; import type { SnapId } from '@metamask/snaps-sdk'; import { JSXElement } from '@metamask/snaps-sdk/jsx'; import configureStore, { MetaMaskReduxState } from '../../../../store/store'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { SnapUIRenderer } from './snap-ui-renderer'; @@ -20,17 +20,8 @@ type RenderInterfaceOptions = { metamaskState?: DeepPartial; }; -// The return type from renderWithProvider includes RenderResult plus a history property -type RenderWithProviderResult = RenderResult & { - history: { - location: { - pathname: string; - }; - }; -}; - // Combine the renderWithProvider result with our custom properties -type RenderInterfaceResult = RenderWithProviderResult & { +type RenderInterfaceResult = RenderResult & { updateInterface: ( newContent: JSXElement, newState?: Record | null, diff --git a/ui/components/app/srp-details-modal/srp-details-modal.test.tsx b/ui/components/app/srp-details-modal/srp-details-modal.test.tsx index 0f24abb78508..9d8ea8619e31 100644 --- a/ui/components/app/srp-details-modal/srp-details-modal.test.tsx +++ b/ui/components/app/srp-details-modal/srp-details-modal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SRPDetailsModal from './srp-details-modal'; describe('SRP Details Modal', () => { diff --git a/ui/components/app/srp-input-import/srp-input-import.test.tsx b/ui/components/app/srp-input-import/srp-input-import.test.tsx index 60d789cd0fbe..85ac0501c2ac 100644 --- a/ui/components/app/srp-input-import/srp-input-import.test.tsx +++ b/ui/components/app/srp-input-import/srp-input-import.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import * as browserRuntime from '../../../../shared/modules/browser-runtime.utils'; import { PLATFORM_FIREFOX } from '../../../../shared/constants/app'; import SrpInputImport from './srp-input-import'; diff --git a/ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.tsx b/ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.tsx index 5d0701f5c42b..06f10acae51f 100644 --- a/ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.tsx +++ b/ui/components/app/srp-quiz-modal/SRPQuiz/SRPQuiz.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, import/no-commonjs */ import React, { useCallback, useContext, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import type { To } from 'react-router-dom-v5-compat'; +import type { To } from 'react-router-dom'; import { MetaMetricsEventCategory, MetaMetricsEventKeyType, diff --git a/ui/components/app/terms-of-use-popup/terms-of-use-popup.test.js b/ui/components/app/terms-of-use-popup/terms-of-use-popup.test.js index 9ee6d656464e..5ef992a7bb2a 100644 --- a/ui/components/app/terms-of-use-popup/terms-of-use-popup.test.js +++ b/ui/components/app/terms-of-use-popup/terms-of-use-popup.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import TermsOfUsePopup from './terms-of-use-popup'; diff --git a/ui/components/app/toast-master/toast-master.js b/ui/components/app/toast-master/toast-master.js index 880a4b29e5bd..3de956eaaab5 100644 --- a/ui/components/app/toast-master/toast-master.js +++ b/ui/components/app/toast-master/toast-master.js @@ -2,7 +2,7 @@ import React, { useContext, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import classnames from 'classnames'; import { getAllScopesFromCaip25CaveatValue } from '@metamask/chain-agnostic-permission'; import { AvatarAccountSize } from '@metamask/design-system-react'; @@ -113,12 +113,13 @@ import { setShieldEndingToastLastClickedOrClosed, } from './utils'; -export function ToastMaster({ location } = {}) { +export function ToastMaster() { + const location = useLocation(); const isMultichainAccountsFeatureState2Enabled = useSelector( getIsMultichainAccountsState2Enabled, ); - // Use passed location or fallback to DEFAULT_ROUTE + // Get current pathname from React Router const currentPathname = location?.pathname ?? DEFAULT_ROUTE; const onHomeScreen = currentPathname === DEFAULT_ROUTE; const onSettingsScreen = currentPathname.startsWith(SETTINGS_ROUTE); diff --git a/ui/components/app/transaction-activity-empty-state/transaction-activity-empty-state.test.tsx b/ui/components/app/transaction-activity-empty-state/transaction-activity-empty-state.test.tsx index a6c9ae1d7801..0f46c37dde7b 100644 --- a/ui/components/app/transaction-activity-empty-state/transaction-activity-empty-state.test.tsx +++ b/ui/components/app/transaction-activity-empty-state/transaction-activity-empty-state.test.tsx @@ -4,7 +4,7 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { EthMethod } from '@metamask/keyring-api'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { ThemeType } from '../../../../shared/constants/preferences'; import useBridging from '../../../hooks/bridge/useBridging'; diff --git a/ui/components/app/transaction-activity-log/__snapshots__/transaction-activity-log.component.test.js.snap b/ui/components/app/transaction-activity-log/__snapshots__/transaction-activity-log.component.test.js.snap index 31d7667af99a..b464a67410f4 100644 --- a/ui/components/app/transaction-activity-log/__snapshots__/transaction-activity-log.component.test.js.snap +++ b/ui/components/app/transaction-activity-log/__snapshots__/transaction-activity-log.component.test.js.snap @@ -8,7 +8,7 @@ exports[`TransactionActivityLog Component should match snapshot 1`] = `
- [activityLog] + Activity log
- [transactionCreated] + Transaction created with a value of 0.01 ETH at 21:13 on 12/4/2018.
@@ -51,9 +51,9 @@ exports[`TransactionActivityLog Component should match snapshot 1`] = ` >
- [transactionSubmitted] + Transaction submitted with estimated gas fee of 0.000021 ETH at 21:13 on 12/4/2018.
@@ -73,9 +73,9 @@ exports[`TransactionActivityLog Component should match snapshot 1`] = ` >
- [transactionResubmitted] + Transaction resubmitted with estimated gas fee increased to 0.000023 ETH at 21:13 on 12/4/2018
@@ -95,9 +95,9 @@ exports[`TransactionActivityLog Component should match snapshot 1`] = ` >
- [transactionConfirmed] + Transaction confirmed at 21:13 on 12/4/2018.
diff --git a/ui/components/app/transaction-activity-log/transaction-activity-log.component.test.js b/ui/components/app/transaction-activity-log/transaction-activity-log.component.test.js index 3308136d1ce7..047ad9109afc 100644 --- a/ui/components/app/transaction-activity-log/transaction-activity-log.component.test.js +++ b/ui/components/app/transaction-activity-log/transaction-activity-log.component.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import TransactionActivityLog from '.'; describe('TransactionActivityLog Component', () => { diff --git a/ui/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js b/ui/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js index 0d0a8f3fc9b0..91179fb2a3a2 100644 --- a/ui/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js +++ b/ui/components/app/transaction-breakdown/transaction-breakdown-row/transaction-breakdown-row.component.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import Button from '../../../ui/button'; import TransactionBreakdownRow from '.'; diff --git a/ui/components/app/transaction-breakdown/transaction-breakdown.test.js b/ui/components/app/transaction-breakdown/transaction-breakdown.test.js index 664ac3611728..943b38cc2945 100644 --- a/ui/components/app/transaction-breakdown/transaction-breakdown.test.js +++ b/ui/components/app/transaction-breakdown/transaction-breakdown.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { within } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { mockNetworkState } from '../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../shared/constants/network'; 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 c6f671e5f9de..e80fd6027680 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 @@ -3,9 +3,8 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { TransactionStatus } from '@metamask/transaction-controller'; import { act, waitFor } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; import { GAS_LIMITS } from '../../../../shared/constants/gas'; -import { renderWithProviderAndHistory } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import mockSwapTxGroup from '../../../../test/data/swap/mock-legacy-swap-transaction-group.json'; import TransactionListItemDetails from '.'; @@ -37,23 +36,21 @@ const render = async (overrideProps) => { recipientAddress: '0x0000000000000000000000000000000000000000', senderAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', tryReverseResolveAddress: jest.fn(), - transactionStatus: () =>
, + transactionStatus: () =>
, blockExplorerLinkText, rpcPrefs, ...overrideProps, }; const mockStore = configureMockStore([thunk])(mockState); - const history = createMemoryHistory(); let result; await act( async () => - (result = renderWithProviderAndHistory( + (result = renderWithProvider( , mockStore, - history, )), ); diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.js b/ui/components/app/transaction-list-item/transaction-list-item.component.js index 169cc86b79c3..3c01825b693b 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.js @@ -2,7 +2,7 @@ import React, { useMemo, useState, useCallback, useContext } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.test.js b/ui/components/app/transaction-list-item/transaction-list-item.component.test.js index 9fb59ba174fd..2643fb372afa 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.test.js +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.test.js @@ -4,7 +4,6 @@ import { fireEvent } from '@testing-library/react'; import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import configureStore from 'redux-mock-store'; -import { createMemoryHistory } from 'history'; import { TrustSignalDisplayState, useTrustSignals, @@ -17,7 +16,7 @@ import { import transactionGroup from '../../../../test/data/mock-pending-transaction-data.json'; import mockLegacySwapTxGroup from '../../../../test/data/swap/mock-legacy-swap-transaction-group.json'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProviderAndHistory } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { selectBridgeHistoryForAccountGroup } from '../../../ducks/bridge-status/selectors'; import { getTokens } from '../../../ducks/metamask/metamask'; @@ -160,8 +159,6 @@ const generateUseSelectorRouter = (opts) => (selector) => { }; describe('TransactionListItem', () => { - const history = createMemoryHistory(); - beforeAll(() => { useGasFeeEstimates.mockImplementation( () => FEE_MARKET_ESTIMATE_RETURN_VALUE, @@ -179,9 +176,6 @@ describe('TransactionListItem', () => { useGasFeeEstimates.mockRestore(); }); - const renderWithProvider = (component, store) => - renderWithProviderAndHistory(component, store, history); - describe('ActivityListItem interactions', () => { it('should show the activity details popover and log metrics when the activity list item is clicked', () => { useSelector.mockImplementation( diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.unified-swap-bridge.test.tsx b/ui/components/app/transaction-list-item/transaction-list-item.component.unified-swap-bridge.test.tsx index a67151f859cd..a4658737355b 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.unified-swap-bridge.test.tsx +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.unified-swap-bridge.test.tsx @@ -13,9 +13,9 @@ import TransactionListItem from '.'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.test.js b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.test.js index 2a6193847fa4..dbe21c3cde72 100644 --- a/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.test.js +++ b/ui/components/app/user-preferenced-currency-display/user-preferenced-currency-display.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { mockNetworkState } from '../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import UserPreferencedCurrencyDisplay from '.'; diff --git a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.test.js b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.test.js index 88dcaa1a363e..3c7e16c0a665 100644 --- a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.test.js +++ b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { useIsOriginalNativeTokenSymbol } from '../../../hooks/useIsOriginalNativeTokenSymbol'; import UserPreferencedCurrencyInput from '.'; diff --git a/ui/components/app/user-preferenced-token-input/user-preferenced-token-input.test.js b/ui/components/app/user-preferenced-token-input/user-preferenced-token-input.test.js index b4c6387ffaef..372742845507 100644 --- a/ui/components/app/user-preferenced-token-input/user-preferenced-token-input.test.js +++ b/ui/components/app/user-preferenced-token-input/user-preferenced-token-input.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import UserPreferencedTokenInput from '.'; describe('UserPreferencedCurrencyInput Component', () => { diff --git a/ui/components/app/wallet-overview/coin-buttons.tsx b/ui/components/app/wallet-overview/coin-buttons.tsx index 566b2bb80484..86eadf3f5e60 100644 --- a/ui/components/app/wallet-overview/coin-buttons.tsx +++ b/ui/components/app/wallet-overview/coin-buttons.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useContext, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { toHex } from '@metamask/controller-utils'; import { isCaipChainId, diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx index 985877be2be9..5160c5dbfc32 100644 --- a/ui/components/app/wallet-overview/coin-overview.tsx +++ b/ui/components/app/wallet-overview/coin-overview.tsx @@ -1,6 +1,6 @@ import React, { useContext, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import classnames from 'classnames'; import { CaipChainId } from '@metamask/utils'; import type { Hex } from '@metamask/utils'; diff --git a/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.test.ts b/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.test.ts index 8910ee5a37ef..1a951baa11a5 100644 --- a/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.test.ts +++ b/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.test.ts @@ -24,9 +24,9 @@ jest.mock('react-redux', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.ts b/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.ts index 7c4fa0d2553b..7b5ab40776aa 100644 --- a/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.ts +++ b/ui/components/app/wallet-overview/hooks/useHandleSendNonEvm.ts @@ -2,7 +2,7 @@ import { SnapId } from '@metamask/snaps-sdk'; import { parseCaipAssetType, CaipAssetType } from '@metamask/utils'; import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { sendMultichainTransaction, setDefaultHomeActiveTabName, diff --git a/ui/components/component-library/modal-footer/modal-footer.test.tsx b/ui/components/component-library/modal-footer/modal-footer.test.tsx index b6c418e36da1..291d4d5a2f9b 100644 --- a/ui/components/component-library/modal-footer/modal-footer.test.tsx +++ b/ui/components/component-library/modal-footer/modal-footer.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { ModalFooter } from './modal-footer'; diff --git a/ui/components/component-library/picker-network/picker-network.test.tsx b/ui/components/component-library/picker-network/picker-network.test.tsx index f96fd1708cde..98956c0bd338 100644 --- a/ui/components/component-library/picker-network/picker-network.test.tsx +++ b/ui/components/component-library/picker-network/picker-network.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; import { IconName } from '../icon'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { AvatarType } from '../../multichain/avatar-group/avatar-group.types'; import { PickerNetwork } from './picker-network'; diff --git a/ui/components/multichain-accounts/account-remove-modal/account-remove-modal.test.tsx b/ui/components/multichain-accounts/account-remove-modal/account-remove-modal.test.tsx index 09eb9420c000..6eb66124d3b2 100644 --- a/ui/components/multichain-accounts/account-remove-modal/account-remove-modal.test.tsx +++ b/ui/components/multichain-accounts/account-remove-modal/account-remove-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import configureStore from '../../../store/store'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { AccountRemoveModal } from './account-remove-modal'; describe('AccountRemoveModal', () => { diff --git a/ui/components/multichain-accounts/account-show-private-key-row/account-show-private-key-row.test.tsx b/ui/components/multichain-accounts/account-show-private-key-row/account-show-private-key-row.test.tsx index 95ce9e6a6093..b45645c3119a 100644 --- a/ui/components/multichain-accounts/account-show-private-key-row/account-show-private-key-row.test.tsx +++ b/ui/components/multichain-accounts/account-show-private-key-row/account-show-private-key-row.test.tsx @@ -1,9 +1,8 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; -import { MemoryRouter } from 'react-router-dom-v5-compat'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MOCK_ACCOUNT_EOA } from '../../../../test/data/mock-accounts'; import { AccountShowPrivateKeyRow } from './account-show-private-key-row'; @@ -126,9 +125,7 @@ describe('AccountShowPrivateKeyRow', () => { const store = mockStore(state); renderWithProvider( - - - , + , store, ); @@ -148,9 +145,7 @@ describe('AccountShowPrivateKeyRow', () => { }; renderWithProvider( - - - , + , store, ); @@ -169,9 +164,7 @@ describe('AccountShowPrivateKeyRow', () => { }; renderWithProvider( - - - , + , store, ); @@ -185,9 +178,7 @@ describe('AccountShowPrivateKeyRow', () => { const store = mockStore(state); renderWithProvider( - - - , + , store, ); @@ -207,9 +198,7 @@ describe('AccountShowPrivateKeyRow', () => { const store = mockStore(state); renderWithProvider( - - - , + , store, ); @@ -231,9 +220,7 @@ describe('AccountShowPrivateKeyRow', () => { const store = mockStore(state); renderWithProvider( - - - , + , store, ); @@ -257,9 +244,7 @@ describe('AccountShowPrivateKeyRow', () => { const store = mockStore(state); renderWithProvider( - - - , + , store, ); @@ -290,9 +275,7 @@ describe('AccountShowPrivateKeyRow', () => { }; renderWithProvider( - - - , + , store, ); diff --git a/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.test.tsx b/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.test.tsx index f5c4a3fb4c37..bab812b2fb82 100644 --- a/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.test.tsx +++ b/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.test.tsx @@ -8,9 +8,9 @@ import { ONBOARDING_REVIEW_SRP_ROUTE } from '../../../helpers/constants/routes'; import { AccountShowSrpRow } from './account-show-srp-row'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.tsx b/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.tsx index 27378c9f9140..44c5681a5cd4 100644 --- a/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.tsx +++ b/ui/components/multichain-accounts/account-show-srp-row/account-show-srp-row.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { TextVariant, diff --git a/ui/components/multichain-accounts/add-multichain-account/add-multichain-account.test.tsx b/ui/components/multichain-accounts/add-multichain-account/add-multichain-account.test.tsx index 0ea00616c0d0..7d6099dae401 100644 --- a/ui/components/multichain-accounts/add-multichain-account/add-multichain-account.test.tsx +++ b/ui/components/multichain-accounts/add-multichain-account/add-multichain-account.test.tsx @@ -4,7 +4,7 @@ import { fireEvent, screen, waitFor } from '@testing-library/react'; import configureStore, { MetaMaskReduxDispatch } from '../../../store/store'; import { createNextMultichainAccountGroup } from '../../../store/actions'; import { useAccountsOperationsLoadingStates } from '../../../hooks/accounts/useAccountsOperationsLoadingStates'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { AddMultichainAccount } from './add-multichain-account'; const addMultichainAccountButtonTestId = 'add-multichain-account-button'; diff --git a/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.test.tsx b/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.test.tsx index 81de0166c2fd..b57ec9519788 100644 --- a/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.test.tsx +++ b/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.test.tsx @@ -17,9 +17,9 @@ const mockOpenExtensionInBrowser = jest.fn(); const mockUseSelector = useSelector as jest.MockedFunction; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.tsx b/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.tsx index d132205f8cfe..e3ee731cb015 100644 --- a/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.tsx +++ b/ui/components/multichain-accounts/add-wallet-modal/add-wallet-modal.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useContext } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, BoxAlignItems, diff --git a/ui/components/multichain-accounts/address-qr-code-modal/address-qr-code-modal.test.tsx b/ui/components/multichain-accounts/address-qr-code-modal/address-qr-code-modal.test.tsx index ad85d8667b49..fd230e2fb63a 100644 --- a/ui/components/multichain-accounts/address-qr-code-modal/address-qr-code-modal.test.tsx +++ b/ui/components/multichain-accounts/address-qr-code-modal/address-qr-code-modal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { openBlockExplorer } from '../../multichain/menu-items/view-explorer-menu-item'; import { getBlockExplorerInfo } from '../../../helpers/utils/multichain/getBlockExplorerInfo'; diff --git a/ui/components/multichain-accounts/edit-account-name-modal/edit-account-name-modal.test.tsx b/ui/components/multichain-accounts/edit-account-name-modal/edit-account-name-modal.test.tsx index eba18b1d5ef6..a48a4e6f369b 100644 --- a/ui/components/multichain-accounts/edit-account-name-modal/edit-account-name-modal.test.tsx +++ b/ui/components/multichain-accounts/edit-account-name-modal/edit-account-name-modal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore, { MetaMaskReduxDispatch } from '../../../store/store'; import { EditAccountNameModal } from './edit-account-name-modal'; diff --git a/ui/components/multichain-accounts/multichain-account-cell/multichain-account-cell.test.tsx b/ui/components/multichain-accounts/multichain-account-cell/multichain-account-cell.test.tsx index 0d97072af764..aa708caa9534 100644 --- a/ui/components/multichain-accounts/multichain-account-cell/multichain-account-cell.test.tsx +++ b/ui/components/multichain-accounts/multichain-account-cell/multichain-account-cell.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { screen, fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockDefaultState from '../../../../test/data/mock-state.json'; import { diff --git a/ui/components/multichain-accounts/multichain-account-edit-modal/multichain-account-edit-modal.test.tsx b/ui/components/multichain-accounts/multichain-account-edit-modal/multichain-account-edit-modal.test.tsx index 20113819a58a..a1e84093e791 100644 --- a/ui/components/multichain-accounts/multichain-account-edit-modal/multichain-account-edit-modal.test.tsx +++ b/ui/components/multichain-accounts/multichain-account-edit-modal/multichain-account-edit-modal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockDefaultState from '../../../../test/data/mock-state.json'; import { setAccountGroupName } from '../../../store/actions'; diff --git a/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.test.tsx b/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.test.tsx index 26849cc6f303..b0472d49b165 100644 --- a/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.test.tsx +++ b/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.test.tsx @@ -35,9 +35,9 @@ jest.mock('@metamask/chain-agnostic-permission', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.tsx b/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.tsx index 1df6a4047308..99b198c5e9fb 100644 --- a/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.tsx +++ b/ui/components/multichain-accounts/multichain-account-list/multichain-account-list.tsx @@ -12,7 +12,7 @@ import { AccountWalletType, } from '@metamask/account-api'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { parseCaipAccountId } from '@metamask/utils'; import { Box, diff --git a/ui/components/multichain-accounts/multichain-account-menu-items/multichain-account-menu-items.test.tsx b/ui/components/multichain-accounts/multichain-account-menu-items/multichain-account-menu-items.test.tsx index 4b28df102086..0a8c163bb0aa 100644 --- a/ui/components/multichain-accounts/multichain-account-menu-items/multichain-account-menu-items.test.tsx +++ b/ui/components/multichain-accounts/multichain-account-menu-items/multichain-account-menu-items.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { TextColor } from '../../../helpers/constants/design-system'; import { IconName } from '../../component-library'; import { MultichainAccountMenuItems } from './multichain-account-menu-items'; diff --git a/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.test.tsx b/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.test.tsx index 15a2604d194e..4c807a85b839 100644 --- a/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.test.tsx +++ b/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.test.tsx @@ -49,9 +49,9 @@ jest.mock('../../../store/actions', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.tsx b/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.tsx index 0739d027912f..090861f39ecc 100644 --- a/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.tsx +++ b/ui/components/multichain-accounts/multichain-account-menu/multichain-account-menu.tsx @@ -1,5 +1,5 @@ import React, { useMemo, useRef } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Box, diff --git a/ui/components/multichain-accounts/multichain-accounts-tree/multichain-accounts-tree.tsx b/ui/components/multichain-accounts/multichain-accounts-tree/multichain-accounts-tree.tsx index d7cedccef04f..1e18aff0a5aa 100644 --- a/ui/components/multichain-accounts/multichain-accounts-tree/multichain-accounts-tree.tsx +++ b/ui/components/multichain-accounts/multichain-accounts-tree/multichain-accounts-tree.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useMemo } from 'react'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, ButtonLink, ButtonLinkSize, Text } from '../../component-library'; import { AlignItems, diff --git a/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.test.tsx b/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.test.tsx index 1e664f5e4f9b..8699fa33505c 100644 --- a/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.test.tsx +++ b/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.test.tsx @@ -21,9 +21,9 @@ import { MultichainHoveredAddressRowsList } from './multichain-hovered-address-r const mockStore = configureStore([]); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.tsx b/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.tsx index d909224b264e..9d4763b957b8 100644 --- a/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.tsx +++ b/ui/components/multichain-accounts/multichain-address-rows-hovered-list/multichain-hovered-address-rows-hovered-list.tsx @@ -24,7 +24,7 @@ import { TextColor, TextVariant, } from '@metamask/design-system-react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { BackgroundColor } from '../../../helpers/constants/design-system'; import { Popover, PopoverPosition } from '../../component-library'; import { useI18nContext } from '../../../hooks/useI18nContext'; diff --git a/ui/components/multichain-accounts/multichain-site-cell/avatar-group/multichain-avatar-group.test.tsx b/ui/components/multichain-accounts/multichain-site-cell/avatar-group/multichain-avatar-group.test.tsx index 94895d968983..dbf2ed4ea9fe 100644 --- a/ui/components/multichain-accounts/multichain-site-cell/avatar-group/multichain-avatar-group.test.tsx +++ b/ui/components/multichain-accounts/multichain-site-cell/avatar-group/multichain-avatar-group.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import mockState from '../../../../../test/data/mock-state.json'; import { diff --git a/ui/components/multichain-accounts/multichain-site-cell/tool-tip/multichain-site-cell-tooltip.test.tsx b/ui/components/multichain-accounts/multichain-site-cell/tool-tip/multichain-site-cell-tooltip.test.tsx index 4de9dd5cce10..7a5c2ec0e5af 100644 --- a/ui/components/multichain-accounts/multichain-site-cell/tool-tip/multichain-site-cell-tooltip.test.tsx +++ b/ui/components/multichain-accounts/multichain-site-cell/tool-tip/multichain-site-cell-tooltip.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { CaipChainId } from '@metamask/utils'; import { RpcEndpointType } from '@metamask/network-controller'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import mockState from '../../../../../test/data/mock-state.json'; import { createMockInternalAccount } from '../../../../../test/jest/mocks'; diff --git a/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.test.tsx b/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.test.tsx index 199491dba851..908cab77851c 100644 --- a/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.test.tsx +++ b/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.test.tsx @@ -10,9 +10,9 @@ const srpBackupRowTestId = 'multichain-srp-backup'; const srpQuizHeaderTestId = 'srp-quiz-header'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.tsx b/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.tsx index 045b063ddf1b..b55921b3493d 100644 --- a/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.tsx +++ b/ui/components/multichain-accounts/multichain-srp-backup/multichain-srp-backup.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useState } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import classnames from 'classnames'; import { IconSize } from '@metamask/design-system-react'; import { Box, Icon, IconName, Text } from '../../component-library'; diff --git a/ui/components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper.test.tsx b/ui/components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper.test.tsx index 3eb62a2b5ca6..27473e6a7688 100644 --- a/ui/components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper.test.tsx +++ b/ui/components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper.test.tsx @@ -9,7 +9,7 @@ import { AccountWalletType, AccountGroupId, } from '@metamask/account-api'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { createMockInternalAccount } from '../../../../../test/jest/mocks'; import { diff --git a/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.test.tsx b/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.test.tsx index 3b7a737caead..5f844a579b11 100644 --- a/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.test.tsx +++ b/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.test.tsx @@ -16,9 +16,9 @@ import { import { MultichainReviewPermissions } from './multichain-review-permissions-page'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => ({ origin: 'https%3A//test.dapp' }), useLocation: () => ({ @@ -31,12 +31,6 @@ jest.mock('react-router-dom-v5-compat', () => { }; }); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), - useNavigate: () => jest.fn(), - useLocation: () => ({ pathname: '/test', search: '', hash: '', state: null }), -})); - jest.mock('../../../../hooks/useAccountGroupsForPermissions', () => ({ useAccountGroupsForPermissions: jest.fn(() => ({ supportedAccountGroups: [], diff --git a/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.tsx b/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.tsx index 24efcdaec165..b474a3f9649e 100644 --- a/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.tsx +++ b/ui/components/multichain-accounts/permissions/permission-review-page/multichain-review-permissions-page.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { CaipChainId, NonEmptyArray, Hex } from '@metamask/utils'; import { getAllScopesFromCaip25CaveatValue, @@ -73,28 +73,11 @@ export enum MultichainReviewPermissionsPageMode { EditAccounts = 'edit-accounts', } -type MultichainReviewPermissionsProps = { - params?: { origin: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - -export const MultichainReviewPermissions = ({ - params, - navigate: navigateProp, -}: MultichainReviewPermissionsProps = {}) => { +export const MultichainReviewPermissions = () => { const t = useI18nContext(); const dispatch = useDispatch(); - const navigateHook = useNavigate(); - const urlParamsHook = useParams<{ origin: string }>(); - - // Use props if provided, otherwise fall back to hooks - const navigate = (navigateProp || navigateHook) as NonNullable< - typeof navigateProp - >; - const urlParams = params || urlParamsHook; + const navigate = useNavigate(); + const urlParams = useParams<{ origin: string }>(); // @ts-expect-error TODO: Fix this type error by handling undefined parameters const securedOrigin = decodeURIComponent(urlParams.origin); diff --git a/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.test.tsx b/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.test.tsx index 157ea525aa1c..75fc33ee1859 100644 --- a/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.test.tsx +++ b/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.test.tsx @@ -13,9 +13,9 @@ jest.mock('../../../pages/confirmations/hooks/useEIP7702Account'); jest.mock('../../../pages/confirmations/hooks/useBatchAuthorizationRequests'); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.tsx b/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.tsx index c261816097ea..6c2ee836e267 100644 --- a/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.tsx +++ b/ui/components/multichain-accounts/smart-contract-account-toggle/smart-contract-account-toggle.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { Hex } from '@metamask/utils'; import { useSelector, useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { TransactionMeta } from '@metamask/transaction-controller'; import { useEIP7702Account } from '../../../pages/confirmations/hooks/useEIP7702Account'; import { useBatchAuthorizationRequests } from '../../../pages/confirmations/hooks/useBatchAuthorizationRequests'; diff --git a/ui/components/multichain/account-details/account-details-display.test.tsx b/ui/components/multichain/account-details/account-details-display.test.tsx index e0acbc796512..e00d80bce863 100644 --- a/ui/components/multichain/account-details/account-details-display.test.tsx +++ b/ui/components/multichain/account-details/account-details-display.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/dom'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { toChecksumHexAddress } from '../../../../shared/modules/hexstring-utils'; import configureStore from '../../../store/store'; import * as EIP7702NetworkUtils from '../../../pages/confirmations/hooks/useEIP7702Networks'; diff --git a/ui/components/multichain/account-details/account-details.tsx b/ui/components/multichain/account-details/account-details.tsx index dfe4faccc7b4..517a179c7c7e 100644 --- a/ui/components/multichain/account-details/account-details.tsx +++ b/ui/components/multichain/account-details/account-details.tsx @@ -3,7 +3,7 @@ import React, { useCallback, useContext, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { KeyringObject, KeyringTypes } from '@metamask/keyring-controller'; import { AvatarAccountSize } from '@metamask/design-system-react'; -import type { To } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { MetaMetricsEventCategory, MetaMetricsEventKeyType, @@ -48,16 +48,10 @@ import { AccountDetailsKey } from './account-details-key'; type AccountDetailsProps = { address: string; - navigate?: { - ( - to: To, - options?: { replace?: boolean; state?: Record }, - ): void; - (delta: number): void; - }; }; -export const AccountDetails = ({ address, navigate }: AccountDetailsProps) => { +export const AccountDetails = ({ address }: AccountDetailsProps) => { + const navigate = useNavigate(); const dispatch = useDispatch(); const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); diff --git a/ui/components/multichain/account-list-item-menu/account-list-item-menu.test.js b/ui/components/multichain/account-list-item-menu/account-list-item-menu.test.js index 0d845f32533e..bc291c8ece35 100644 --- a/ui/components/multichain/account-list-item-menu/account-list-item-menu.test.js +++ b/ui/components/multichain/account-list-item-menu/account-list-item-menu.test.js @@ -9,9 +9,9 @@ const mockShowModal = jest.fn(); const mockAddPermittedAccount = jest.fn(); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain/account-menu/account-menu.test.tsx b/ui/components/multichain/account-menu/account-menu.test.tsx index adee102e632e..c99db3f4761b 100644 --- a/ui/components/multichain/account-menu/account-menu.test.tsx +++ b/ui/components/multichain/account-menu/account-menu.test.tsx @@ -38,9 +38,9 @@ jest.mock('../../../store/actions', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain/account-menu/account-menu.tsx b/ui/components/multichain/account-menu/account-menu.tsx index c9b347995b56..8edb76f6f35c 100644 --- a/ui/components/multichain/account-menu/account-menu.tsx +++ b/ui/components/multichain/account-menu/account-menu.tsx @@ -5,7 +5,7 @@ import React, { useMemo, useState, } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { CaipChainId } from '@metamask/utils'; import { diff --git a/ui/components/multichain/account-network-indicator/account-network-indicator.test.tsx b/ui/components/multichain/account-network-indicator/account-network-indicator.test.tsx index 42b0af22ac43..7aebc55f7cc7 100644 --- a/ui/components/multichain/account-network-indicator/account-network-indicator.test.tsx +++ b/ui/components/multichain/account-network-indicator/account-network-indicator.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { BNB_DISPLAY_NAME, diff --git a/ui/components/multichain/account-overview/account-overview-tabs.tsx b/ui/components/multichain/account-overview/account-overview-tabs.tsx index f9c9d650a5b8..d70944c8333a 100644 --- a/ui/components/multichain/account-overview/account-overview-tabs.tsx +++ b/ui/components/multichain/account-overview/account-overview-tabs.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useContext, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Hex, isStrictHexString } from '@metamask/utils'; import { toEvmCaipChainId } from '@metamask/multichain-network-controller'; import { diff --git a/ui/components/multichain/account-picker/account-picker.test.js b/ui/components/multichain/account-picker/account-picker.test.js index bffa2a00f659..22eacf81d25d 100644 --- a/ui/components/multichain/account-picker/account-picker.test.js +++ b/ui/components/multichain/account-picker/account-picker.test.js @@ -1,7 +1,7 @@ /* eslint-disable jest/require-top-level-describe */ import React from 'react'; import 'jest-canvas-mock'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { AccountPicker } from '.'; diff --git a/ui/components/multichain/address-copy-button/address-copy-button.test.js b/ui/components/multichain/address-copy-button/address-copy-button.test.js index ed64724678b8..6ca761b65bc4 100644 --- a/ui/components/multichain/address-copy-button/address-copy-button.test.js +++ b/ui/components/multichain/address-copy-button/address-copy-button.test.js @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import copyToClipboard from 'copy-to-clipboard'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { COPY_OPTIONS } from '../../../../shared/constants/copy'; import { shortenAddress } from '../../../helpers/utils/util'; diff --git a/ui/components/multichain/address-list-item/address-list-item.test.tsx b/ui/components/multichain/address-list-item/address-list-item.test.tsx index a56f814985c7..3d63077f898a 100644 --- a/ui/components/multichain/address-list-item/address-list-item.test.tsx +++ b/ui/components/multichain/address-list-item/address-list-item.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { shortenAddress } from '../../../helpers/utils/util'; import { CHAIN_IDS } from '../../../../shared/constants/network'; diff --git a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap index 021e5fb0c725..7c20442bf0ea 100644 --- a/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap +++ b/ui/components/multichain/app-header/__snapshots__/app-header.test.js.snap @@ -2,72 +2,35 @@ exports[`App Header locked state matches snapshot: locked 1`] = `
-
+
-
-
- -
+
-
-
-
-`; - -exports[`App Header unlocked state matches snapshot: unlocked 1`] = ` -
-
- +
+
+`; + +exports[`App Header unlocked state matches snapshot: unlocked 1`] = ` +
+ +
-
- - - - - -
+ /> + + +
+
+
-
- -
+
+
+
+
-
+ -
+
diff --git a/ui/components/multichain/app-header/app-header-locked-content.tsx b/ui/components/multichain/app-header/app-header-locked-content.tsx index 5ac709cfc94a..3efb393fe08b 100644 --- a/ui/components/multichain/app-header/app-header-locked-content.tsx +++ b/ui/components/multichain/app-header/app-header-locked-content.tsx @@ -1,6 +1,6 @@ import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller'; import React from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import MetafoxLogo from '../../ui/metafox-logo'; diff --git a/ui/components/multichain/app-header/app-header-unlocked-content.tsx b/ui/components/multichain/app-header/app-header-unlocked-content.tsx index ca2785986c35..04491f85264d 100644 --- a/ui/components/multichain/app-header/app-header-unlocked-content.tsx +++ b/ui/components/multichain/app-header/app-header-unlocked-content.tsx @@ -9,7 +9,7 @@ import React, { import browser from 'webextension-polyfill'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { AlignItems, BackgroundColor, diff --git a/ui/components/multichain/app-header/app-header.js b/ui/components/multichain/app-header/app-header.js index d432e33639d4..646fb1fcbd24 100644 --- a/ui/components/multichain/app-header/app-header.js +++ b/ui/components/multichain/app-header/app-header.js @@ -2,7 +2,7 @@ import React, { useCallback, useContext, useRef } from 'react'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { matchPath } from 'react-router-dom-v5-compat'; +import { matchPath } from 'react-router-dom'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, diff --git a/ui/components/multichain/app-header/app-header.test.js b/ui/components/multichain/app-header/app-header.test.js index a0413c642811..5b4b38aea1f0 100644 --- a/ui/components/multichain/app-header/app-header.test.js +++ b/ui/components/multichain/app-header/app-header.test.js @@ -15,7 +15,8 @@ jest.mock('../../../../app/scripts/lib/util', () => ({ getEnvironmentType: jest.fn(), })); -jest.mock('react-router-dom-v5-compat', () => ({ +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), // eslint-disable-next-line react/prop-types Link: ({ children, ...props }) => {children}, // eslint-disable-next-line react/prop-types diff --git a/ui/components/multichain/app-header/multichain-meta-fox-logo.js b/ui/components/multichain/app-header/multichain-meta-fox-logo.js index e79da9c9b3b5..442fe527e6fa 100644 --- a/ui/components/multichain/app-header/multichain-meta-fox-logo.js +++ b/ui/components/multichain/app-header/multichain-meta-fox-logo.js @@ -1,6 +1,6 @@ import React, { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { useTheme } from '../../../hooks/useTheme'; diff --git a/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx b/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx index 88db613fd837..30edf5236aaf 100644 --- a/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx +++ b/ui/components/multichain/asset-picker-amount/asset-balance/asset-balance-text.test.tsx @@ -3,7 +3,7 @@ import { AssetType } from '../../../../../shared/constants/transaction'; import mockSendState from '../../../../../test/data/mock-send-state.json'; import configureStore from '../../../../store/store'; import { TextColor } from '../../../../helpers/constants/design-system'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { AssetBalanceText } from './asset-balance-text'; const store = configureStore({ diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx index fcabe7412be2..244330e3a34b 100644 --- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx +++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx @@ -4,7 +4,7 @@ import thunk from 'redux-thunk'; import { screen, fireEvent } from '@testing-library/react'; import { RpcEndpointType } from '@metamask/network-controller'; import { CHAIN_IDS } from '@metamask/transaction-controller'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-send-state.json'; import { NETWORK_TO_SHORT_NETWORK_NAME_MAP } from '../../../../../shared/constants/bridge'; import { AssetPickerModalNetwork } from './asset-picker-modal-network'; diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx index 89e76f447051..4d6df125879c 100644 --- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx +++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-nft-tab.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box } from '../../../component-library'; import Spinner from '../../../ui/spinner'; import { diff --git a/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx b/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx index 37237c8bd525..7c101b8613a9 100644 --- a/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx +++ b/ui/components/multichain/asset-picker-amount/asset-picker/asset-picker.test.tsx @@ -17,9 +17,9 @@ import { AssetPicker } from './asset-picker'; const unknownChainId = '0x2489078'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain/avatar-group/avatar-group.test.tsx b/ui/components/multichain/avatar-group/avatar-group.test.tsx index 22feec62d524..deca7e065a54 100644 --- a/ui/components/multichain/avatar-group/avatar-group.test.tsx +++ b/ui/components/multichain/avatar-group/avatar-group.test.tsx @@ -3,7 +3,7 @@ import { screen } from '@testing-library/react'; import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { AvatarGroup } from './avatar-group'; diff --git a/ui/components/multichain/badge-status/badge-status.test.js b/ui/components/multichain/badge-status/badge-status.test.js index c7980e52ebc4..146f70e123d3 100644 --- a/ui/components/multichain/badge-status/badge-status.test.js +++ b/ui/components/multichain/badge-status/badge-status.test.js @@ -6,7 +6,7 @@ import { BorderColor, } from '../../../helpers/constants/design-system'; import configureStore from '../../../store/store'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { BadgeStatus } from './badge-status'; describe('Badge Status', () => { diff --git a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx index faeb18ff7e0c..bbba33de4d6a 100644 --- a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx +++ b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal-list.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { EthAccountType, EthScope } from '@metamask/keyring-api'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods'; import { ConnectAccountsModalList } from './connect-accounts-modal-list'; diff --git a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx index ae4f4ef84d98..c532b69c0959 100644 --- a/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx +++ b/ui/components/multichain/connect-accounts-modal/connect-accounts-modal.test.tsx @@ -6,7 +6,7 @@ import { waitFor } from '@testing-library/react'; import messages from '../../../../app/_locales/en/messages.json'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { createMockInternalAccount } from '../../../../test/jest/mocks'; import { shortenAddress } from '../../../helpers/utils/util'; // TODO: Remove restricted import diff --git a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx index 34a80f6604bd..2f506024541e 100644 --- a/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx +++ b/ui/components/multichain/connected-accounts-menu/connected-accounts-menu.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import { EthAccountType, EthMethod } from '@metamask/keyring-api'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { createMockInternalAccount } from '../../../../test/jest/mocks'; diff --git a/ui/components/multichain/connected-site-menu/connected-site-menu.test.js b/ui/components/multichain/connected-site-menu/connected-site-menu.test.js index 31c5cb3a1611..7d7617b5836a 100644 --- a/ui/components/multichain/connected-site-menu/connected-site-menu.test.js +++ b/ui/components/multichain/connected-site-menu/connected-site-menu.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { STATUS_CONNECTED, STATUS_CONNECTED_TO_ANOTHER_ACCOUNT, diff --git a/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx b/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx index 908b232b534d..d5a9ff9075eb 100644 --- a/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx +++ b/ui/components/multichain/connected-site-popover/connected-site-popover.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { ConnectedSitePopover } from './connected-site-popover'; const props = { diff --git a/ui/components/multichain/create-account/create-account.tsx b/ui/components/multichain/create-account/create-account.tsx index 5f266c979abe..906c8dbd4fb3 100644 --- a/ui/components/multichain/create-account/create-account.tsx +++ b/ui/components/multichain/create-account/create-account.tsx @@ -8,7 +8,7 @@ import React, { useState, } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { CaipChainId } from '@metamask/utils'; import { KeyringTypes } from '@metamask/keyring-controller'; diff --git a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx index 0df8d261ffa5..f654ef6d657f 100644 --- a/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx +++ b/ui/components/multichain/create-named-snap-account/create-named-snap-account.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { KeyringTypes } from '@metamask/keyring-controller'; import { CreateAccount } from '..'; diff --git a/ui/components/multichain/detected-token-banner/detected-token-banner.test.js b/ui/components/multichain/detected-token-banner/detected-token-banner.test.js index 262147179ad1..77c48fe7890e 100644 --- a/ui/components/multichain/detected-token-banner/detected-token-banner.test.js +++ b/ui/components/multichain/detected-token-banner/detected-token-banner.test.js @@ -1,5 +1,6 @@ import React from 'react'; -import { fireEvent, renderWithProvider, screen } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import testData from '../../../../.storybook/test-data'; @@ -37,13 +38,14 @@ describe('DetectedTokensBanner', () => { }); it('should render number of tokens detected link', () => { const store = configureStore(mockStore); - renderWithProvider(, store); + const { getByText } = renderWithProvider( + , + store, + ); - expect( - screen.getByText('3 new tokens found in this account'), - ).toBeInTheDocument(); + expect(getByText('3 new tokens found in this account')).toBeInTheDocument(); - fireEvent.click(screen.getByText('Import tokens')); + fireEvent.click(getByText('Import tokens')); expect(setShowDetectedTokensSpy).toHaveBeenCalled(); }); }); diff --git a/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx b/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx index e268d7603a5f..076173c79960 100644 --- a/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx +++ b/ui/components/multichain/disconnect-permissions-modal/disconnect-permissions-modal.test.tsx @@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store'; import { Hex } from '@metamask/utils'; import { fireEvent } from '../../../../test/jest'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { DisconnectPermissionsModal } from '.'; diff --git a/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js b/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js index 4ac721ab2dc0..0e77fc9a022e 100644 --- a/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js +++ b/ui/components/multichain/edit-networks-modal/edit-networks-modal.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import configureStore from '../../../store/store'; import { EditNetworksModal } from '.'; diff --git a/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx b/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx index 56cd2cd3a8d4..80148c8e50d1 100644 --- a/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx +++ b/ui/components/multichain/funding-method-modal/funding-method-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import useRamps from '../../../hooks/ramps/useRamps/useRamps'; import { FundingMethodModal } from './funding-method-modal'; diff --git a/ui/components/multichain/global-menu/global-menu.test.tsx b/ui/components/multichain/global-menu/global-menu.test.tsx index 3d0d9cf0f169..72f7e8349c83 100644 --- a/ui/components/multichain/global-menu/global-menu.test.tsx +++ b/ui/components/multichain/global-menu/global-menu.test.tsx @@ -34,8 +34,8 @@ const render = (metamaskStateChanges = {}) => { }; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, Link: ({ children, diff --git a/ui/components/multichain/global-menu/global-menu.tsx b/ui/components/multichain/global-menu/global-menu.tsx index fc9872166c48..965a6f1b58cb 100644 --- a/ui/components/multichain/global-menu/global-menu.tsx +++ b/ui/components/multichain/global-menu/global-menu.tsx @@ -1,5 +1,5 @@ import React, { useContext, useMemo } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import browser from 'webextension-polyfill'; import { diff --git a/ui/components/multichain/import-account/json.test.tsx b/ui/components/multichain/import-account/json.test.tsx index bad3e4befc87..de84b7bf8741 100644 --- a/ui/components/multichain/import-account/json.test.tsx +++ b/ui/components/multichain/import-account/json.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent, waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths diff --git a/ui/components/multichain/import-nfts-modal/import-nfts-modal.js b/ui/components/multichain/import-nfts-modal/import-nfts-modal.js index e7de4e120a37..0d03d505078a 100644 --- a/ui/components/multichain/import-nfts-modal/import-nfts-modal.js +++ b/ui/components/multichain/import-nfts-modal/import-nfts-modal.js @@ -2,7 +2,7 @@ import { isValidHexAddress } from '@metamask/controller-utils'; import PropTypes from 'prop-types'; import React, { useContext, useState, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { getErrorMessage } from '../../../../shared/modules/error'; import { MetaMetricsEventName, diff --git a/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js b/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js index cd7758e180b7..586126bf7e9c 100644 --- a/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js +++ b/ui/components/multichain/import-nfts-modal/import-nfts-modal.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent, waitFor } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { @@ -36,9 +36,9 @@ jest.mock('../../../store/actions.ts', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js index bd3dbe309840..4163f57f1106 100644 --- a/ui/components/multichain/import-tokens-modal/import-tokens-modal.js +++ b/ui/components/multichain/import-tokens-modal/import-tokens-modal.js @@ -12,7 +12,7 @@ import { isNonEvmChainId, } from '@metamask/bridge-controller'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import PropTypes from 'prop-types'; import { getTokenTrackerLink } from '@metamask/etherscan-link/dist/token-tracker-link'; import { CHAIN_IDS } from '@metamask/transaction-controller'; diff --git a/ui/components/multichain/menu-items/account-details-menu-item.js b/ui/components/multichain/menu-items/account-details-menu-item.js index 0bb01deb1935..2078c9653f45 100644 --- a/ui/components/multichain/menu-items/account-details-menu-item.js +++ b/ui/components/multichain/menu-items/account-details-menu-item.js @@ -1,9 +1,7 @@ import React, { useCallback, useContext } from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; - -import { useNavigate } from 'react-router-dom-v5-compat'; - +import { useNavigate } from 'react-router-dom'; import { MenuItem } from '../../ui/menu'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; @@ -13,7 +11,7 @@ import { } from '../../../../shared/constants/metametrics'; import { IconName, Text } from '../../component-library'; import { getSelectedAccountGroup } from '../../../selectors/multichain-accounts/account-tree'; -import { getHDEntropyIndex } from '../../../selectors/selectors'; +import { getHDEntropyIndex } from '../../../selectors'; import { MULTICHAIN_ACCOUNT_DETAILS_PAGE_ROUTE } from '../../../helpers/constants/routes'; export const AccountDetailsMenuItem = ({ diff --git a/ui/components/multichain/menu-items/account-details-menu-item.test.js b/ui/components/multichain/menu-items/account-details-menu-item.test.js index 6fc2a317cec8..33d7698a773c 100644 --- a/ui/components/multichain/menu-items/account-details-menu-item.test.js +++ b/ui/components/multichain/menu-items/account-details-menu-item.test.js @@ -11,8 +11,8 @@ const mockInternalAccount = getSelectedInternalAccountFromMockState(mockState); const mockNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, })); diff --git a/ui/components/multichain/menu-items/discover-menu-item.test.tsx b/ui/components/multichain/menu-items/discover-menu-item.test.tsx index 1a11bb351649..2436c9a6a9d1 100644 --- a/ui/components/multichain/menu-items/discover-menu-item.test.tsx +++ b/ui/components/multichain/menu-items/discover-menu-item.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import { fireEvent, renderWithProvider } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { DiscoverMenuItem } from './discover-menu-item'; diff --git a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx index aade38141a3f..b5c7fd0d45db 100644 --- a/ui/components/multichain/menu-items/view-explorer-menu-item.tsx +++ b/ui/components/multichain/menu-items/view-explorer-menu-item.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { parseCaipChainId } from '@metamask/utils'; import { InternalAccount } from '@metamask/keyring-internal-api'; diff --git a/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx b/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx index 8e2fcd5de239..3875a2c35c05 100644 --- a/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx +++ b/ui/components/multichain/multi-srp/select-srp/select-srp.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { SelectSrp, SelectSrpProps } from './select-srp'; const mockSrpName = 'Test Srp'; diff --git a/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx b/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx index aac53049c5fb..6488258270d8 100644 --- a/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx +++ b/ui/components/multichain/multi-srp/srp-list/srp-list-item.test.tsx @@ -4,7 +4,7 @@ import thunk from 'redux-thunk'; import mockState from '../../../../../test/data/mock-state.json'; import { createMockInternalAccount } from '../../../../../test/jest/mocks'; import { InternalAccountWithBalance } from '../../../../selectors'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { shortenAddress } from '../../../../helpers/utils/util'; import { SrpListItem } from './srp-list-item'; diff --git a/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx b/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx index 204149f733f5..8bd26ab7abc9 100644 --- a/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx +++ b/ui/components/multichain/multi-srp/srp-list/srp-list.test.tsx @@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { KeyringTypes } from '@metamask/keyring-controller'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { InternalAccountWithBalance } from '../../../../selectors'; import { shortenAddress } from '../../../../helpers/utils/util'; diff --git a/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx b/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx index c9e3dacf26cc..5a72daaccc4a 100644 --- a/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx +++ b/ui/components/multichain/multichain-accounts/wallet-details-account-item/wallet-details-account-item.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import { InternalAccount } from '@metamask/keyring-internal-api'; import configureStore from '../../../../store/store'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import WalletDetailsAccountItem from './wallet-details-account-item'; diff --git a/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx b/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx index 8efca30b61fc..68de8a62d5ab 100644 --- a/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx +++ b/ui/components/multichain/network-list-menu/network-confirmation-popover/network-confirmation-popover.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { ApprovalType } from '@metamask/controller-utils'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import NetworkConfirmationPopover from './network-confirmation-popover'; diff --git a/ui/components/multichain/network-list-menu/network-list-menu.test.tsx b/ui/components/multichain/network-list-menu/network-list-menu.test.tsx index 494048dfaa12..0cd1a92206aa 100644 --- a/ui/components/multichain/network-list-menu/network-list-menu.test.tsx +++ b/ui/components/multichain/network-list-menu/network-list-menu.test.tsx @@ -16,7 +16,7 @@ import { MONAD_TESTNET_DISPLAY_NAME, } from '../../../../shared/constants/network'; import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { NetworkListMenu } from '.'; const mockSetShowTestNetworks = jest.fn(); diff --git a/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx b/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx index 1ffb957df1c7..7103edd7419a 100644 --- a/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx +++ b/ui/components/multichain/network-list-menu/popular-network-list/popular-network-list.test.tsx @@ -4,7 +4,7 @@ import '@testing-library/jest-dom'; import { useDispatch, useSelector } from 'react-redux'; import configureStore from 'redux-mock-store'; import { RpcEndpointType } from '@metamask/network-controller'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { getUnapprovedConfirmations } from '../../../../selectors'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; import PopularNetworkList from './popular-network-list'; diff --git a/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx b/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx index 3d4e0ae276c0..a07ed7d33ee4 100644 --- a/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx +++ b/ui/components/multichain/network-list-menu/select-rpc-url-modal/select-rpc-url-modal.tsx @@ -4,7 +4,7 @@ import { NetworkConfiguration } from '@metamask/network-controller'; import { type CaipChainId } from '@metamask/utils'; import classnames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { AvatarNetwork, AvatarNetworkSize, diff --git a/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx b/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx index 6239e4e4ede4..db82cd2029bf 100644 --- a/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx +++ b/ui/components/multichain/network-manager/components/add-network/AddNetwork.tsx @@ -1,6 +1,6 @@ import { UpdateNetworkFields } from '@metamask/network-controller'; import React from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { NetworksForm } from '../../../../../pages/settings/networks-tab/networks-form/networks-form'; import { useNetworkFormState } from '../../../../../pages/settings/networks-tab/networks-form/networks-form-state'; diff --git a/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx b/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx index 47106d3e87a0..05cc57486b24 100644 --- a/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx +++ b/ui/components/multichain/network-manager/components/additional-networks-info/additional-networks-info.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { screen, fireEvent, act } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url'; import { AdditionalNetworksInfo } from './additional-networks-info'; diff --git a/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx b/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx index 6aa3202b4202..2f1e0d4ba06f 100644 --- a/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx +++ b/ui/components/multichain/network-manager/components/custom-networks/custom-networks.tsx @@ -1,7 +1,7 @@ import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller'; import React, { useCallback, useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { endTrace, TraceName } from '../../../../../../shared/lib/trace'; import { convertCaipToHexChainId, diff --git a/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts b/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts index cbe0dd40a571..5d4cb60b4048 100644 --- a/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts +++ b/ui/components/multichain/network-manager/hooks/useNetworkItemCallbacks.ts @@ -3,7 +3,7 @@ import { EthScope } from '@metamask/keyring-api'; import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller'; import { type Hex } from '@metamask/utils'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { CHAIN_ID_PORTFOLIO_LANDING_PAGE_URL_MAP } from '../../../../../shared/constants/network'; import { convertCaipToHexChainId, diff --git a/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts b/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts index 556cd3c44d6e..e06a599986e5 100644 --- a/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts +++ b/ui/components/multichain/network-manager/hooks/useNetworkManagerState.test.ts @@ -1,5 +1,5 @@ import { SolScope } from '@metamask/keyring-api'; -import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers-navigate'; import { getAllEnabledNetworksForAllNamespaces } from '../../../../selectors'; import { useNetworkManagerInitialTab } from './useNetworkManagerState'; diff --git a/ui/components/multichain/network-manager/network-manager.tsx b/ui/components/multichain/network-manager/network-manager.tsx index 0afb3d087fb6..3f867eccba86 100644 --- a/ui/components/multichain/network-manager/network-manager.tsx +++ b/ui/components/multichain/network-manager/network-manager.tsx @@ -5,12 +5,7 @@ import { } from '@metamask/network-controller'; import React, { useCallback, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { - Route, - Routes, - useNavigate, - useLocation, -} from 'react-router-dom-v5-compat'; +import { Route, Routes, useNavigate, useLocation } from 'react-router-dom'; import * as URI from 'uri-js'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { useNetworkFormState } from '../../../pages/settings/networks-tab/networks-form/networks-form-state'; diff --git a/ui/components/multichain/nft-item/nft-item.test.js b/ui/components/multichain/nft-item/nft-item.test.js index b2dc0b7f5ca0..c04d142fa12b 100644 --- a/ui/components/multichain/nft-item/nft-item.test.js +++ b/ui/components/multichain/nft-item/nft-item.test.js @@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react'; import configureStore from '../../../store/store'; import '@testing-library/jest-dom'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { NftItem } from '.'; const store = configureStore(mockState); diff --git a/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx b/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx index d97692b5e206..6158c2e6ebb9 100644 --- a/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx +++ b/ui/components/multichain/notification-detail-address/notification-detail-address.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import configureStore from '../../../store/store'; import { NotificationDetailAddress } from './notification-detail-address'; diff --git a/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx b/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx index 231d32431d87..d93e2509e673 100644 --- a/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx +++ b/ui/components/multichain/notification-detail-nft/notification-detail-nft.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { NotificationDetailNft } from './notification-detail-nft'; diff --git a/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx b/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx index be7ac97996b7..feb3fdc0c085 100644 --- a/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx +++ b/ui/components/multichain/notifications-settings-account/notifications-settings-account.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { NotificationsSettingsAccount } from './notifications-settings-account'; diff --git a/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx b/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx index 68a0f332ec11..addecc26d771 100644 --- a/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx +++ b/ui/components/multichain/notifications-settings-box/notifications-settings-box.test.tsx @@ -36,7 +36,7 @@ describe('NotificationsSettingsBox', () => { it('toggles value on click', () => { const onToggleMock = jest.fn(); const testId = 'test-id'; - const { container } = render( + render( { , ); - console.log(container.innerHTML); fireEvent.click(screen.getByTestId(`${testId}-toggle-input`)); expect(onToggleMock).toHaveBeenCalledTimes(1); diff --git a/ui/components/multichain/pages/connections/components/no-connections.test.tsx b/ui/components/multichain/pages/connections/components/no-connections.test.tsx index f696f11083a3..264d963dfb6d 100644 --- a/ui/components/multichain/pages/connections/components/no-connections.test.tsx +++ b/ui/components/multichain/pages/connections/components/no-connections.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { NoConnectionContent } from './no-connection'; describe('No Connections Content', () => { diff --git a/ui/components/multichain/pages/connections/connections.test.tsx b/ui/components/multichain/pages/connections/connections.test.tsx index 857f38ecc84a..f01a07dcf945 100644 --- a/ui/components/multichain/pages/connections/connections.test.tsx +++ b/ui/components/multichain/pages/connections/connections.test.tsx @@ -8,9 +8,9 @@ import { Connections } from './connections'; const mockUseNavigate = jest.fn(); const mockUseParams = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), useLocation: () => mockUseLocation(), diff --git a/ui/components/multichain/pages/connections/connections.tsx b/ui/components/multichain/pages/connections/connections.tsx index 5a8f2e735131..767c7b0f2f68 100644 --- a/ui/components/multichain/pages/connections/connections.tsx +++ b/ui/components/multichain/pages/connections/connections.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { NonEmptyArray } from '@metamask/utils'; import { AlignItems, @@ -68,28 +68,11 @@ import { } from './components/connections.types'; import { NoConnectionContent } from './components/no-connection'; -type ConnectionsProps = { - params?: { origin: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - -export const Connections = ({ - params, - navigate: navigateProp, -}: ConnectionsProps = {}) => { +export const Connections = () => { const t = useI18nContext(); const dispatch = useDispatch(); - const navigateHook = useNavigate(); - const urlParamsHook = useParams<{ origin: string }>(); - - // Use props if provided, otherwise fall back to hooks - const navigate = (navigateProp || navigateHook) as NonNullable< - typeof navigateProp - >; - const urlParams = params || urlParamsHook; + const navigate = useNavigate(); + const urlParams = useParams<{ origin: string }>(); const [showConnectAccountsModal, setShowConnectAccountsModal] = useState(false); diff --git a/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx index 5c143d0d659b..9eac4f978793 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permission-group-list-item.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Hex } from '@metamask/utils'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { PermissionGroupListItem } from './permission-group-list-item'; diff --git a/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx index 199a3e9701e9..fa7df9dce1a9 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permission-list-item.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { PermissionListItem } from './permission-list-item'; describe('Permission List Item', () => { diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx index bdd287232807..6e3b961250f7 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-connection-list-item.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import { CaipChainId } from '@metamask/utils'; import { BoxSpacing, IconName } from '@metamask/design-system-react'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; import { PermissionsCellConnectionListItem } from './permissions-cell-connection-list-item'; diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx index a64e985b9e62..005bd499b8c2 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell-tooltip.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; import { PermissionsCellTooltip } from './permissions-cell-tooltip'; diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx index 88e02193675d..3ea62cc6a7a7 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.test.tsx @@ -10,9 +10,9 @@ import { EvmAndMultichainNetworkConfigurationsWithCaipChainId } from '../../../. import { PermissionsCell } from './permissions-cell'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx index ee8ead43bfd8..a76a6b9c2180 100644 --- a/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/permissions-cell.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, BoxBackgroundColor, diff --git a/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx b/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx index 5c0a52c1c06c..0374fe22c544 100644 --- a/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx +++ b/ui/components/multichain/pages/gator-permissions/components/review-gator-permission-item.test.tsx @@ -10,7 +10,7 @@ import { } from '@metamask/gator-permissions-controller'; import { fireEvent } from '@testing-library/react'; import { Settings } from 'luxon'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; import { ReviewGatorPermissionItem } from './review-gator-permission-item'; diff --git a/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx b/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx index e2f1b5f4a3ca..5846529d74e0 100644 --- a/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx +++ b/ui/components/multichain/pages/gator-permissions/gator-permissions-page.tsx @@ -1,5 +1,5 @@ import React, { useRef } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Content, Header, Page } from '../page'; import { diff --git a/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx b/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx index 7344520d119a..0f073947a3f4 100644 --- a/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx +++ b/ui/components/multichain/pages/gator-permissions/review-permissions/review-gator-permissions-page.tsx @@ -5,7 +5,7 @@ import React, { useRef, useState, } from 'react'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Hex } from '@metamask/utils'; import { @@ -44,28 +44,15 @@ import { import { ReviewGatorPermissionItem } from '../components'; import { PREVIOUS_ROUTE } from '../../../../../helpers/constants/routes'; -type ReviewGatorPermissionsPageProps = { - params?: { chainId: string; permissionGroupName: string; origin?: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - -export const ReviewGatorPermissionsPage = ({ - params, - navigate: navigateProp, -}: ReviewGatorPermissionsPageProps = {}) => { +export const ReviewGatorPermissionsPage = () => { const t = useI18nContext(); - const navigateHook = useNavigate(); - const navigate = navigateProp || navigateHook; - const urlParamsHook = useParams<{ + const navigate = useNavigate(); + const { chainId, origin } = useParams<{ chainId: string; permissionGroupName: string; origin?: string; }>(); - const { chainId, origin } = params || urlParamsHook; const originDecoded = origin ? safeDecodeURIComponent(origin) : undefined; const [, evmNetworks] = useSelector( diff --git a/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx b/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx index 3f5835c7f44f..5ea12172d987 100644 --- a/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx +++ b/ui/components/multichain/pages/gator-permissions/token-transfer/token-transfer-page.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Hex } from '@metamask/utils'; import { @@ -33,25 +33,10 @@ import { } from '../../../../../selectors/gator-permissions/gator-permissions'; import { getDisplayOrigin, safeDecodeURIComponent } from '../helper'; -type TokenTransferPageProps = { - params?: { origin?: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - -export const TokenTransferPage = ({ - params, - navigate: navigateProp, -}: TokenTransferPageProps = {}) => { +export const TokenTransferPage = () => { const t = useI18nContext(); - const navigateHook = useNavigate(); - const navigate = (navigateProp || navigateHook) as NonNullable< - typeof navigateProp - >; - const urlParamsHook = useParams<{ origin?: string }>(); - const urlParams = params || urlParamsHook; + const navigate = useNavigate(); + const urlParams = useParams<{ origin?: string }>(); const origin = urlParams.origin ? safeDecodeURIComponent(urlParams.origin) : undefined; diff --git a/ui/components/multichain/pages/page/page.tsx b/ui/components/multichain/pages/page/page.tsx index ddf6a6b62721..b6cc14c870aa 100644 --- a/ui/components/multichain/pages/page/page.tsx +++ b/ui/components/multichain/pages/page/page.tsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { Box } from '../../../component-library'; import { BackgroundColor, diff --git a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js index fab896a66235..c925a061c8b8 100644 --- a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js +++ b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js @@ -4,7 +4,7 @@ import { fireEvent } from '@testing-library/react'; import configureStore from '../../../../store/store'; import mockState from '../../../../../test/data/mock-state.json'; import { getURLHost } from '../../../../helpers/utils/util'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { getAccountGroupWithInternalAccounts } from '../../../../selectors/multichain-accounts/account-tree'; import { ConnectionListItem } from './connection-list-item'; diff --git a/ui/components/multichain/pages/permissions-page/permissions-page.js b/ui/components/multichain/pages/permissions-page/permissions-page.js index 03d193e2d6cb..a1c9770f1971 100644 --- a/ui/components/multichain/pages/permissions-page/permissions-page.js +++ b/ui/components/multichain/pages/permissions-page/permissions-page.js @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { isSnapId } from '@metamask/snaps-utils'; import { Content, Header, Page } from '../page'; diff --git a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx index 42759939f3cc..a30544d8d39d 100644 --- a/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx +++ b/ui/components/multichain/pages/review-permissions-page/review-permissions-page.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { CaipAccountId, CaipChainId, @@ -61,28 +61,11 @@ import { CAIP_FORMATTED_EVM_TEST_CHAINS } from '../../../../../shared/constants/ import { endTrace, trace, TraceName } from '../../../../../shared/lib/trace'; import { SiteCell } from './site-cell/site-cell'; -type ReviewPermissionsProps = { - params?: { origin: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - -export const ReviewPermissions = ({ - params, - navigate: navigateProp, -}: ReviewPermissionsProps = {}) => { +export const ReviewPermissions = () => { const t = useI18nContext(); const dispatch = useDispatch(); - const navigateHook = useNavigate(); - const urlParamsHook = useParams<{ origin: string }>(); - - // Use props if provided, otherwise fall back to hooks - const navigate = (navigateProp || navigateHook) as NonNullable< - typeof navigateProp - >; - const urlParams = params || urlParamsHook; + const navigate = useNavigate(); + const urlParams = useParams<{ origin: string }>(); // @ts-expect-error TODO: Fix this type error by handling undefined parameters const securedOrigin = decodeURIComponent(urlParams.origin); diff --git a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js index 568e077ad0ed..91f7a7abb7d1 100644 --- a/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js +++ b/ui/components/multichain/pages/review-permissions-page/site-cell/site-cell-tooltip.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; import { SiteCellTooltip } from './site-cell-tooltip'; diff --git a/ui/components/multichain/pages/send/components/network-picker.test.tsx b/ui/components/multichain/pages/send/components/network-picker.test.tsx index f7610072744b..a55c0221823e 100644 --- a/ui/components/multichain/pages/send/components/network-picker.test.tsx +++ b/ui/components/multichain/pages/send/components/network-picker.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { fireEvent, renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../../../test/jest'; import { SendPageNetworkPicker } from '.'; const mockToggleNetworkMenu = jest.fn(); diff --git a/ui/components/multichain/pages/send/components/recipient.test.tsx b/ui/components/multichain/pages/send/components/recipient.test.tsx index 4d4874510d0a..83f59773ea1c 100644 --- a/ui/components/multichain/pages/send/components/recipient.test.tsx +++ b/ui/components/multichain/pages/send/components/recipient.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { CONFUSING_ENS_ERROR, ENS_UNKNOWN_ERROR, diff --git a/ui/components/multichain/pages/send/components/your-accounts.test.tsx b/ui/components/multichain/pages/send/components/your-accounts.test.tsx index 48bebd93cad9..4b1371b702d3 100644 --- a/ui/components/multichain/pages/send/components/your-accounts.test.tsx +++ b/ui/components/multichain/pages/send/components/your-accounts.test.tsx @@ -2,7 +2,8 @@ import React from 'react'; import { BtcAccountType } from '@metamask/keyring-api'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { fireEvent, renderWithProvider } from '../../../../../../test/jest'; +import { fireEvent } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { createMockInternalAccount } from '../../../../../../test/jest/mocks'; import { MultichainNativeAssets } from '../../../../../../shared/constants/multichain/assets'; import { SendPageYourAccounts } from '.'; diff --git a/ui/components/multichain/pages/send/send.js b/ui/components/multichain/pages/send/send.js index 05ce1fa7080b..9b93178b028b 100644 --- a/ui/components/multichain/pages/send/send.js +++ b/ui/components/multichain/pages/send/send.js @@ -7,7 +7,7 @@ import React, { } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { Tooltip } from 'react-tippy'; import { I18nContext } from '../../../../contexts/i18n'; import { @@ -96,8 +96,7 @@ export const SendPage = ({ const sendStage = useSelector(getSendStage); const isSwapAndSend = getIsDraftSwapAndSend(draftTransaction); - // Use v5-compat hooks as fallback (works in test environment with CompatRouter) - // In production, props are provided by createV5CompatRoute + // Use React Router v6 hooks const navigateHook = useNavigate(); const locationHook = useLocation(); const navigate = navigateProp || navigateHook; diff --git a/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx b/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx index 8a43e6072472..fd6f70ede179 100644 --- a/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx +++ b/ui/components/multichain/permission-details-modal/permission-details-modal.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; import configureStore from 'redux-mock-store'; import { EthAccountType, EthMethod, EthScope } from '@metamask/keyring-api'; -import { fireEvent, renderWithProvider } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { mockNetworkState } from '../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods'; diff --git a/ui/components/multichain/permissions-header/permissions-header.tsx b/ui/components/multichain/permissions-header/permissions-header.tsx index 8eba3829f4b5..543702d8754d 100644 --- a/ui/components/multichain/permissions-header/permissions-header.tsx +++ b/ui/components/multichain/permissions-header/permissions-header.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { AlignItems, BackgroundColor, diff --git a/ui/components/multichain/receive-modal/receive-modal.test.js b/ui/components/multichain/receive-modal/receive-modal.test.js index 16cc5b1e5f28..99f3ae8d0ee0 100644 --- a/ui/components/multichain/receive-modal/receive-modal.test.js +++ b/ui/components/multichain/receive-modal/receive-modal.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { ReceiveModal } from '.'; diff --git a/ui/components/multichain/token-list-item/token-list-item.tsx b/ui/components/multichain/token-list-item/token-list-item.tsx index 832a9bdde7b6..72c89e24927e 100644 --- a/ui/components/multichain/token-list-item/token-list-item.tsx +++ b/ui/components/multichain/token-list-item/token-list-item.tsx @@ -1,6 +1,6 @@ import React, { useContext, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import classnames from 'classnames'; import { getNativeTokenAddress } from '@metamask/assets-controllers'; import { type Hex } from '@metamask/utils'; diff --git a/ui/components/ui/account-list/account-list.test.js b/ui/components/ui/account-list/account-list.test.js index 30b6d89ac166..83d7fbc34b1f 100644 --- a/ui/components/ui/account-list/account-list.test.js +++ b/ui/components/ui/account-list/account-list.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { screen, fireEvent } from '@testing-library/react'; import { BtcAccountType, BtcMethod, BtcScope } from '@metamask/keyring-api'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { MultichainNativeAssets } from '../../../../shared/constants/multichain/assets'; diff --git a/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js b/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js index d04cb9179ec5..3bfbec5f2487 100644 --- a/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js +++ b/ui/components/ui/account-mismatch-warning/acccount-mismatch-warning.component.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import AccountMismatchWarning from './account-mismatch-warning.component'; diff --git a/ui/components/ui/actionable-message/actionable-message.test.js b/ui/components/ui/actionable-message/actionable-message.test.js index 9c86be37b089..90be697ee3c3 100644 --- a/ui/components/ui/actionable-message/actionable-message.test.js +++ b/ui/components/ui/actionable-message/actionable-message.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ActionableMessage from '.'; const createProps = (customProps = {}) => { diff --git a/ui/components/ui/aggregated-balance/index.test.tsx b/ui/components/ui/aggregated-balance/index.test.tsx index 623305589225..7680c7e7bb67 100644 --- a/ui/components/ui/aggregated-balance/index.test.tsx +++ b/ui/components/ui/aggregated-balance/index.test.tsx @@ -5,7 +5,7 @@ import '@testing-library/jest-dom'; import thunk from 'redux-thunk'; import { SolAccountType, SolMethod, SolScope } from '@metamask/keyring-api'; import { Cryptocurrency } from '@metamask/assets-controllers'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MultichainNativeAssets } from '../../../../shared/constants/multichain/assets'; import mockState from '../../../../test/data/mock-state.json'; import { SOLANA_WALLET_SNAP_ID } from '../../../../shared/lib/accounts'; diff --git a/ui/components/ui/alert/index.test.js b/ui/components/ui/alert/index.test.js index 7c5900f811e9..af871dba6500 100644 --- a/ui/components/ui/alert/index.test.js +++ b/ui/components/ui/alert/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import Alert from '.'; describe('Alert', () => { diff --git a/ui/components/ui/button-group/button-group-component.test.js b/ui/components/ui/button-group/button-group-component.test.js index 584042491867..ed512514cc7e 100644 --- a/ui/components/ui/button-group/button-group-component.test.js +++ b/ui/components/ui/button-group/button-group-component.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ButtonGroup from '.'; describe('ButtonGroup Component', () => { diff --git a/ui/components/ui/confusable/confusable.component.test.js b/ui/components/ui/confusable/confusable.component.test.js index c541751c5fed..14f8415d67e3 100644 --- a/ui/components/ui/confusable/confusable.component.test.js +++ b/ui/components/ui/confusable/confusable.component.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import Confusable from '.'; describe('Confusable component', () => { diff --git a/ui/components/ui/currency-display/currency-display.component.test.js b/ui/components/ui/currency-display/currency-display.component.test.js index 897e6e844f9b..24ed170fa4f9 100644 --- a/ui/components/ui/currency-display/currency-display.component.test.js +++ b/ui/components/ui/currency-display/currency-display.component.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import CurrencyDisplay from '.'; diff --git a/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap b/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap index e41638c1fd28..612c4d0a7a36 100644 --- a/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap +++ b/ui/components/ui/form-combo-field/__snapshots__/form-combo-field.test.tsx.snap @@ -25,7 +25,7 @@ exports[`FormComboField renders with no options 1`] = ` value="TestValue" />
{ diff --git a/ui/components/ui/qr-code-view/qr-code-view.test.tsx b/ui/components/ui/qr-code-view/qr-code-view.test.tsx index b8c70526c5c6..a8163ed5dfef 100644 --- a/ui/components/ui/qr-code-view/qr-code-view.test.tsx +++ b/ui/components/ui/qr-code-view/qr-code-view.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import QRCodeView from './qr-code-view'; diff --git a/ui/components/ui/site-origin/site-origin.test.js b/ui/components/ui/site-origin/site-origin.test.js index 6c2b426747c7..a64a1da4d757 100644 --- a/ui/components/ui/site-origin/site-origin.test.js +++ b/ui/components/ui/site-origin/site-origin.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SiteOrigin from './site-origin'; describe('SiteOrigin', () => { diff --git a/ui/components/ui/survey-toast/survey-toast.test.tsx b/ui/components/ui/survey-toast/survey-toast.test.tsx index e7a454c5f8ab..29be2b8baba4 100644 --- a/ui/components/ui/survey-toast/survey-toast.test.tsx +++ b/ui/components/ui/survey-toast/survey-toast.test.tsx @@ -4,7 +4,7 @@ import configureStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { act } from 'react-dom/test-utils'; import fetchWithCache from '../../../../shared/lib/fetch-with-cache'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, diff --git a/ui/components/ui/token-input/token-input.component.test.js b/ui/components/ui/token-input/token-input.component.test.js index 3708d5407d4d..905f67f87375 100644 --- a/ui/components/ui/token-input/token-input.component.test.js +++ b/ui/components/ui/token-input/token-input.component.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { CHAIN_IDS, diff --git a/ui/components/ui/unit-input/unit-input.component.test.js b/ui/components/ui/unit-input/unit-input.component.test.js index 75018952000a..91aa51cd51ca 100644 --- a/ui/components/ui/unit-input/unit-input.component.test.js +++ b/ui/components/ui/unit-input/unit-input.component.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import UnitInput from './unit-input.component'; describe('UnitInput Component', () => { diff --git a/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js b/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js index d03380694682..70785dae15be 100644 --- a/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js +++ b/ui/components/ui/update-nickname-popover/update-nickname-popover.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import UpdateNicknamePopover from './update-nickname-popover'; diff --git a/ui/contexts/metamask-notifications/metamask-notifications.test.ts b/ui/contexts/metamask-notifications/metamask-notifications.test.ts index e14c804066aa..723fc7b6fb5a 100644 --- a/ui/contexts/metamask-notifications/metamask-notifications.test.ts +++ b/ui/contexts/metamask-notifications/metamask-notifications.test.ts @@ -6,7 +6,7 @@ import * as Selectors from '../../selectors/selectors'; import * as MetamaskDucks from '../../ducks/metamask/metamask'; import * as AuthenticationSelectors from '../../selectors/identity/authentication'; import * as StorageHelpers from '../../../shared/lib/storage-helpers'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { useBasicFunctionalityDisableEffect, useEnableNotificationsByDefaultEffect, diff --git a/ui/contexts/metametrics.js b/ui/contexts/metametrics.js index 0460105f7726..38d3131b0f01 100644 --- a/ui/contexts/metametrics.js +++ b/ui/contexts/metametrics.js @@ -12,12 +12,7 @@ import React, { useContext, } from 'react'; import PropTypes from 'prop-types'; -// NOTE: Mixed v5/v5-compat imports during router migration -// - useLocation from v5: Works with the v5 HashRouter to detect navigation changes -// - matchPath from v5-compat: Provides v6 API (reversed args, pattern.path structure) -// When v6 migration is complete, change both imports to: import { useLocation, matchPath } from 'react-router-dom'; -import { useLocation } from 'react-router-dom'; -import { matchPath } from 'react-router-dom-v5-compat'; +import { useLocation, matchPath } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { omit } from 'lodash'; diff --git a/ui/contexts/navigation-state/index.tsx b/ui/contexts/navigation-state/index.tsx deleted file mode 100644 index 5d33edb14155..000000000000 --- a/ui/contexts/navigation-state/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { - createContext, - useContext, - useState, - ReactNode, - Dispatch, - SetStateAction, -} from 'react'; - -// Define types -type NavState = Record | null; -type SetNavState = Dispatch>; - -// Create contexts -const NavStateContext = createContext(null); -const SetNavStateContext = createContext(() => { - // noop default -}); - -type NavigationStateProviderProps = { - children: ReactNode; -}; - -export const NavigationStateProvider = ({ - children, -}: NavigationStateProviderProps) => { - const [navState, setNavState] = useState(null); - - return ( - - - {children} - - - ); -}; - -export const useNavState = (): NavState | null => { - return useContext(NavStateContext); -}; - -export const useSetNavState = (): SetNavState => { - return useContext(SetNavStateContext); -}; diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index 3e4dc6548c8b..7e835940b833 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -94,9 +94,9 @@ jest.mock('lodash', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx b/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx deleted file mode 100644 index 6807c4c05c94..000000000000 --- a/ui/helpers/higher-order-components/authenticated/authenticated-v5-compat.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import { Navigate, useLocation } from 'react-router-dom-v5-compat'; -import { UNLOCK_ROUTE, ONBOARDING_ROUTE } from '../../constants/routes'; - -type AuthenticatedV5CompatProps = { - children: React.ReactNode; -}; - -/** - * AuthenticatedV5Compat - A wrapper component for v5-compat routes that require authentication - * - * This component checks if the user is unlocked and has completed onboarding. - * If not, it redirects to the appropriate route using v5-compat Navigate. - * - * Unlike the v5 Authenticated HOC, this returns the element directly (not wrapped in Route) - * because v5-compat Routes handle their children differently. - * - * @param props - Component props - * @param props.children - Child components to render when authenticated - * @returns Navigate component or children - */ -const AuthenticatedV5Compat = ({ children }: AuthenticatedV5CompatProps) => { - const location = useLocation(); - const isUnlocked = useSelector( - (state: { metamask: { isUnlocked: boolean } }) => state.metamask.isUnlocked, - ); - const completedOnboarding = useSelector( - (state: { metamask: { completedOnboarding: boolean } }) => - state.metamask.completedOnboarding, - ); - - if (!completedOnboarding) { - return ; - } - - if (!isUnlocked) { - return ; - } - - return <>{children}; -}; - -export default AuthenticatedV5Compat; diff --git a/ui/helpers/higher-order-components/authenticated/authenticated.component.js b/ui/helpers/higher-order-components/authenticated/authenticated.component.js index 660b8b79d702..122c6cd6c9c5 100644 --- a/ui/helpers/higher-order-components/authenticated/authenticated.component.js +++ b/ui/helpers/higher-order-components/authenticated/authenticated.component.js @@ -1,41 +1,40 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Redirect, Route, useLocation } from 'react-router-dom'; +import { Navigate, useLocation } from 'react-router-dom'; import { UNLOCK_ROUTE, ONBOARDING_ROUTE } from '../../constants/routes'; -const OnboardingRoute = { pathname: ONBOARDING_ROUTE }; - /** - * Authenticated - A wrapper component for v5 routes that require authentication + * Authenticated - A wrapper component for v6 routes that require authentication * * This component checks if the user is unlocked and has completed onboarding. - * If not, it redirects to the appropriate route using v5 Redirect. - * - * This is the original v5 implementation - for v5-compat routes, use AuthenticatedV5Compat instead. + * If not, it redirects to the appropriate route using v6 Navigate. * * @param {object} props - Component props - * @returns {React.Element} Route or Redirect component + * @param {boolean} props.isUnlocked - Whether the user is unlocked + * @param {boolean} props.completedOnboarding - Whether the user has completed onboarding + * @param {React.ReactNode} props.children - Child elements to render if authenticated + * @returns {React.Element} Children or Navigate component */ -export default function Authenticated(props) { - const { isUnlocked, completedOnboarding } = props; +export default function Authenticated({ + isUnlocked, + completedOnboarding, + children, +}) { const location = useLocation(); - switch (true) { - case isUnlocked && completedOnboarding: - return ; - case !completedOnboarding: - return ; - default: - return ( - - ); + if (!completedOnboarding) { + return ; } + + if (!isUnlocked) { + return ; + } + + return children; } Authenticated.propTypes = { isUnlocked: PropTypes.bool, completedOnboarding: PropTypes.bool, - path: PropTypes.string, - component: PropTypes.elementType, - exact: PropTypes.bool, + children: PropTypes.node, }; diff --git a/ui/helpers/higher-order-components/feature-toggled-route.js b/ui/helpers/higher-order-components/feature-toggled-route.js index 0591c9a32819..b8371f74aa18 100644 --- a/ui/helpers/higher-order-components/feature-toggled-route.js +++ b/ui/helpers/higher-order-components/feature-toggled-route.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate } from 'react-router-dom'; export default function FeatureToggledRoute({ flag, redirectRoute, element }) { if (flag) { diff --git a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx b/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx deleted file mode 100644 index 84f0f951f614..000000000000 --- a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.test.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import { Provider } from 'react-redux'; -import { MemoryRouter, Routes, Route } from 'react-router-dom-v5-compat'; -import configureStore from 'redux-mock-store'; -import { ONBOARDING_ROUTE } from '../../constants/routes'; -import InitializedV5Compat from './initialized-v5-compat'; - -jest.mock('../../../ducks/metamask/metamask', () => ({ - getCompletedOnboarding: (state: { - metamask: { completedOnboarding: boolean }; - }) => state.metamask.completedOnboarding, -})); - -const mockStore = configureStore(); - -describe('InitializedV5Compat', () => { - const MockChildComponent = () => ( -
Child Component
- ); - const MockOnboardingComponent = () => ( -
Onboarding Page
- ); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should render children when onboarding is completed', () => { - const store = mockStore({ - metamask: { - completedOnboarding: true, - }, - }); - - render( - - - - - - - } - /> - } - /> - - - , - ); - - expect(screen.getByTestId('child-component')).toBeInTheDocument(); - expect(screen.getByText('Child Component')).toBeInTheDocument(); - expect(screen.queryByTestId('onboarding')).not.toBeInTheDocument(); - }); - - it('should redirect to onboarding route when onboarding is not completed', () => { - const store = mockStore({ - metamask: { - completedOnboarding: false, - }, - }); - - render( - - - - - - - } - /> - } - /> - - - , - ); - - expect(screen.queryByTestId('child-component')).not.toBeInTheDocument(); - expect(screen.getByTestId('onboarding')).toBeInTheDocument(); - expect(screen.getByText('Onboarding Page')).toBeInTheDocument(); - }); - - it('should accept and render complex React node structures as children', () => { - const store = mockStore({ - metamask: { - completedOnboarding: true, - }, - }); - - const NestedComponent = () => ( - Nested Content - ); - - render( - - - - -
- -

Some text

-
- - } - /> - } - /> -
-
-
, - ); - - expect(screen.getByTestId('parent')).toBeInTheDocument(); - expect(screen.getByTestId('nested')).toBeInTheDocument(); - expect(screen.getByTestId('paragraph')).toBeInTheDocument(); - expect(screen.getByText('Nested Content')).toBeInTheDocument(); - expect(screen.getByText('Some text')).toBeInTheDocument(); - }); -}); diff --git a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx b/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx deleted file mode 100644 index 4ee9460834ab..000000000000 --- a/ui/helpers/higher-order-components/initialized/initialized-v5-compat.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; -import { Navigate } from 'react-router-dom-v5-compat'; -import { getCompletedOnboarding } from '../../../ducks/metamask/metamask'; -import { ONBOARDING_ROUTE } from '../../constants/routes'; - -type InitializedV5CompatProps = { - children: React.ReactNode; -}; - -/** - * InitializedV5Compat - A wrapper component for v5-compat routes that require initialization - * - * This component checks if the user has completed onboarding. - * If not, it redirects to the onboarding route using v5-compat Navigate. - * - * Unlike the v5 Initialized HOC, this returns the element directly (not wrapped in Route) - * because v5-compat Routes handle their children differently. - * - * @param props - Component props - * @param props.children - Child components to render when initialized - * @returns Navigate component or children - */ -const InitializedV5Compat = ({ children }: InitializedV5CompatProps) => { - const completedOnboarding = useSelector(getCompletedOnboarding); - - if (!completedOnboarding) { - return ; - } - - return <>{children}; -}; - -export default InitializedV5Compat; diff --git a/ui/helpers/higher-order-components/initialized/initialized.component.js b/ui/helpers/higher-order-components/initialized/initialized.component.js index 7ab8ad60dc25..95ded1a8089e 100644 --- a/ui/helpers/higher-order-components/initialized/initialized.component.js +++ b/ui/helpers/higher-order-components/initialized/initialized.component.js @@ -1,21 +1,28 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Redirect, Route } from 'react-router-dom'; +import { Navigate } from 'react-router-dom'; import { ONBOARDING_ROUTE } from '../../constants/routes'; -const onboardingRoute = { pathname: ONBOARDING_ROUTE }; +/** + * Initialized - A wrapper component for v6 routes that require onboarding completion + * + * This component checks if the user has completed onboarding. + * If not, it redirects to the onboarding route using v6 Navigate. + * + * @param {object} props - Component props + * @param {boolean} props.completedOnboarding - Whether the user has completed onboarding + * @param {React.ReactNode} props.children - Child elements to render if initialized + * @returns {React.Element} Children or Navigate component + */ +export default function Initialized({ completedOnboarding, children }) { + if (!completedOnboarding) { + return ; + } -export default function Initialized(props) { - return props.completedOnboarding ? ( - - ) : ( - - ); + return children; } Initialized.propTypes = { completedOnboarding: PropTypes.bool, - path: PropTypes.string, - component: PropTypes.func, - exact: PropTypes.bool, + children: PropTypes.node, }; diff --git a/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js b/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js index cd58d5a061b6..5166e68150e7 100644 --- a/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js +++ b/ui/helpers/higher-order-components/with-modal-props/with-modal-props.test.js @@ -1,6 +1,6 @@ import configureMockStore from 'redux-mock-store'; import React from 'react'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import withModalProps from './with-modal-props'; const mockState = { diff --git a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx index 622b15216df5..f3a6a9db7045 100644 --- a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx +++ b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.test.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { MemoryRouter } from 'react-router-dom-v5-compat'; +import { MemoryRouter } from 'react-router-dom'; import withRouterHooks, { RouterHooksProps } from './with-router-hooks'; -// Mock the react-router-dom-v5-compat hooks +// Mock the react-router-dom hooks const mockUseNavigate = jest.fn(); const mockUseLocation = { pathname: '/test', @@ -13,8 +13,8 @@ const mockUseLocation = { }; const mockUseParams = { id: 'test-id' }; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation, useParams: () => mockUseParams, diff --git a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx index b24ebe4b5005..0ddd8eea45da 100644 --- a/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx +++ b/ui/helpers/higher-order-components/with-router-hooks/with-router-hooks.tsx @@ -1,9 +1,5 @@ import React from 'react'; -import { - useNavigate, - useLocation, - useParams, -} from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation, useParams } from 'react-router-dom'; // Types for the router hooks export type RouterHooksProps = { diff --git a/ui/helpers/utils/i18n-helper.test.js b/ui/helpers/utils/i18n-helper.test.js index 8bd2b249a2cd..21fd8941fa89 100644 --- a/ui/helpers/utils/i18n-helper.test.js +++ b/ui/helpers/utils/i18n-helper.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { captureException } from '../../../shared/lib/sentry'; import { getMessage as getMessageShared } from '../../../shared/modules/i18n'; -import { renderWithProvider } from '../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { getMessage } from './i18n-helper'; jest.mock('../../../shared/modules/i18n'); diff --git a/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts b/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts index a78486ceb74a..765cdbf1353b 100644 --- a/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts +++ b/ui/hooks/accounts/useAccountsOperationsLoadingStates.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers-navigate'; import { useAccountsOperationsLoadingStates } from './useAccountsOperationsLoadingStates'; describe('useAccountsOperationsLoadingStates', () => { diff --git a/ui/hooks/bridge/useBridgeQueryParams.test.ts b/ui/hooks/bridge/useBridgeQueryParams.test.ts index 8eaa05118a9a..7706b3bce4f1 100644 --- a/ui/hooks/bridge/useBridgeQueryParams.test.ts +++ b/ui/hooks/bridge/useBridgeQueryParams.test.ts @@ -1,6 +1,6 @@ import * as bridgeControllerUtils from '@metamask/bridge-controller'; import { BigNumber } from 'ethers'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store'; import * as assetUtils from '../../../shared/lib/asset-utils'; @@ -10,7 +10,7 @@ import { mockNetworkState } from '../../../test/stub/networks'; import { useBridgeQueryParams } from './useBridgeQueryParams'; // Helper hook that combines useBridgeQueryParams with useLocation -// so we can inspect the router state from the same v5-compat context +// so we can inspect the router state from the same v6 context const useBridgeQueryParamsWithLocation = () => { const location = useLocation(); useBridgeQueryParams(); diff --git a/ui/hooks/bridge/useBridgeQueryParams.ts b/ui/hooks/bridge/useBridgeQueryParams.ts index dde7bda93b01..b5303ae343c0 100644 --- a/ui/hooks/bridge/useBridgeQueryParams.ts +++ b/ui/hooks/bridge/useBridgeQueryParams.ts @@ -1,6 +1,6 @@ import { useEffect, useMemo, useCallback, useState, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { CaipAssetType, CaipAssetTypeStruct, diff --git a/ui/hooks/bridge/useBridgeTxHistoryData.ts b/ui/hooks/bridge/useBridgeTxHistoryData.ts index d1e090cdcf81..d8fbeba8af67 100644 --- a/ui/hooks/bridge/useBridgeTxHistoryData.ts +++ b/ui/hooks/bridge/useBridgeTxHistoryData.ts @@ -4,7 +4,7 @@ import { type TransactionMeta, TransactionStatus, } from '@metamask/transaction-controller'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { StatusTypes } from '@metamask/bridge-controller'; import { isBridgeComplete } from '../../../shared/lib/bridge-status/utils'; import { CROSS_CHAIN_SWAP_TX_DETAILS_ROUTE } from '../../helpers/constants/routes'; diff --git a/ui/hooks/bridge/useBridging.test.ts b/ui/hooks/bridge/useBridging.test.ts index bc3cbe385462..89cbef6d23ad 100644 --- a/ui/hooks/bridge/useBridging.test.ts +++ b/ui/hooks/bridge/useBridging.test.ts @@ -9,9 +9,9 @@ import * as bridgeSelectors from '../../ducks/bridge/selectors'; import useBridging from './useBridging'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/hooks/bridge/useBridging.ts b/ui/hooks/bridge/useBridging.ts index 66bc824c2023..19d9d5101c29 100644 --- a/ui/hooks/bridge/useBridging.ts +++ b/ui/hooks/bridge/useBridging.ts @@ -1,6 +1,6 @@ import { useCallback, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { type BridgeAsset, formatChainIdToCaip, diff --git a/ui/hooks/bridge/useCountdownTimer.test.ts b/ui/hooks/bridge/useCountdownTimer.test.ts index 843b71816cfd..8548c47c3833 100644 --- a/ui/hooks/bridge/useCountdownTimer.test.ts +++ b/ui/hooks/bridge/useCountdownTimer.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store'; import { flushPromises } from '../../../test/lib/timer-helpers'; import { useCountdownTimer } from './useCountdownTimer'; diff --git a/ui/hooks/bridge/useRewards.test.ts b/ui/hooks/bridge/useRewards.test.ts index 8ed865bc4c4a..50eebd4be657 100644 --- a/ui/hooks/bridge/useRewards.test.ts +++ b/ui/hooks/bridge/useRewards.test.ts @@ -3,7 +3,7 @@ import { act } from '@testing-library/react-hooks'; import log from 'loglevel'; import { useSelector } from 'react-redux'; import { selectBridgeQuotes } from '@metamask/bridge-controller'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { createMockInternalAccount } from '../../../test/jest/mocks'; import { getRewardsHasAccountOptedIn, diff --git a/ui/hooks/bridge/useTokenAlerts.test.ts b/ui/hooks/bridge/useTokenAlerts.test.ts index 4b011028bdc4..1992a9477cb6 100644 --- a/ui/hooks/bridge/useTokenAlerts.test.ts +++ b/ui/hooks/bridge/useTokenAlerts.test.ts @@ -1,5 +1,5 @@ import { ChainId, formatChainIdToCaip } from '@metamask/bridge-controller'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { CHAIN_IDS } from '../../../shared/constants/network'; import { MultichainNetworks } from '../../../shared/constants/multichain/networks'; import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store'; diff --git a/ui/hooks/bridge/useTokensWithFiltering.test.ts b/ui/hooks/bridge/useTokensWithFiltering.test.ts index ba85c2a9d2a5..4597e8d74c24 100644 --- a/ui/hooks/bridge/useTokensWithFiltering.test.ts +++ b/ui/hooks/bridge/useTokensWithFiltering.test.ts @@ -2,7 +2,7 @@ import { getNativeAssetForChainId } from '@metamask/bridge-controller'; import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller'; import { SolScope } from '@metamask/keyring-api'; import { MultichainNetwork } from '@metamask/multichain-transactions-controller'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store'; import { STATIC_MAINNET_TOKEN_LIST } from '../../../shared/constants/tokens'; import { CHAIN_IDS } from '../../../shared/constants/network'; diff --git a/ui/hooks/defi/useDeFiPolling.test.ts b/ui/hooks/defi/useDeFiPolling.test.ts index eb9f6a5acaea..090d49c6f022 100644 --- a/ui/hooks/defi/useDeFiPolling.test.ts +++ b/ui/hooks/defi/useDeFiPolling.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import useDeFiPolling from './useDeFiPolling'; import { deFiStartPolling, deFiStopPolling } from './defiPollingActions'; diff --git a/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx b/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx index 8b9f2cbc13d0..698b814f31d5 100644 --- a/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx +++ b/ui/hooks/identity/useAccountSyncing/useAccountSyncing.test.tsx @@ -1,5 +1,5 @@ import { waitFor } from '@testing-library/react'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { diff --git a/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx index cdbca570c477..04db88c78341 100644 --- a/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx +++ b/ui/hooks/identity/useAuthentication/useAutoSignIn.test.tsx @@ -1,5 +1,5 @@ import { act } from '@testing-library/react-hooks'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { useAutoSignIn } from './useAutoSignIn'; diff --git a/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx b/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx index 6e23bd2a36cb..f899b01b427f 100644 --- a/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx +++ b/ui/hooks/identity/useAuthentication/useAutoSignOut.test.tsx @@ -1,5 +1,5 @@ import { act } from '@testing-library/react-hooks'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { useAutoSignOut } from './useAutoSignOut'; diff --git a/ui/hooks/identity/useAuthentication/useSignIn.test.tsx b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx index 8bbdc2650022..d380af19d935 100644 --- a/ui/hooks/identity/useAuthentication/useSignIn.test.tsx +++ b/ui/hooks/identity/useAuthentication/useSignIn.test.tsx @@ -1,5 +1,5 @@ import { act } from '@testing-library/react-hooks'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { useSignIn } from './useSignIn'; diff --git a/ui/hooks/identity/useAuthentication/useSignOut.test.tsx b/ui/hooks/identity/useAuthentication/useSignOut.test.tsx index deb1f9dec269..3e6f6e817550 100644 --- a/ui/hooks/identity/useAuthentication/useSignOut.test.tsx +++ b/ui/hooks/identity/useAuthentication/useSignOut.test.tsx @@ -1,5 +1,5 @@ import { act } from '@testing-library/react-hooks'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { useSignOut } from './useSignOut'; diff --git a/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx b/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx index bb434065e0eb..3e2c8e3363ce 100644 --- a/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx +++ b/ui/hooks/identity/useBackupAndSync/useBackupAndSync.test.tsx @@ -1,6 +1,6 @@ import { act } from '@testing-library/react-hooks'; import { BACKUPANDSYNC_FEATURES } from '@metamask/profile-sync-controller/user-storage'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import * as actions from '../../../store/actions'; import { useBackupAndSync } from './useBackupAndSync'; diff --git a/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx b/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx index c3a4fbf31f04..93ecbc1056d1 100644 --- a/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx +++ b/ui/hooks/identity/useContactSyncing/useContactSyncing.test.tsx @@ -1,5 +1,5 @@ import { waitFor } from '@testing-library/react'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import * as actions from '../../../store/actions'; import { MetamaskIdentityProvider } from '../../../contexts/identity'; import { diff --git a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx index 7e5963044706..f3a9bc21b687 100644 --- a/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx +++ b/ui/hooks/metamask-notifications/useSwitchNotifications.test.tsx @@ -1,7 +1,7 @@ import { waitFor } from '@testing-library/react'; import * as ActionsModule from '../../store/actions'; import * as NotificationSelectorsModule from '../../selectors/metamask-notifications/metamask-notifications'; -import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../test/lib/render-helpers-navigate'; import { useSwitchFeatureAnnouncementsChange, useSwitchAccountNotificationsChange, diff --git a/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts b/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts index 9b029b9ca518..2c824bb0cccd 100644 --- a/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts +++ b/ui/hooks/multi-srp/useHdKeyringsWithSnapAccounts.test.ts @@ -1,5 +1,5 @@ import { KeyringTypes } from '@metamask/keyring-controller'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { getMetaMaskHdKeyrings } from '../../selectors'; import { getInternalAccounts } from '../../selectors/accounts'; import { createMockInternalAccount } from '../../../test/jest/mocks'; diff --git a/ui/hooks/rewards/useCandidateSubscriptionId.test.ts b/ui/hooks/rewards/useCandidateSubscriptionId.test.ts index ed392f96d0d8..6fb40f2931fc 100644 --- a/ui/hooks/rewards/useCandidateSubscriptionId.test.ts +++ b/ui/hooks/rewards/useCandidateSubscriptionId.test.ts @@ -1,7 +1,7 @@ import { act } from '@testing-library/react-hooks'; import { waitFor } from '@testing-library/react'; import log from 'loglevel'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { useCandidateSubscriptionId } from './useCandidateSubscriptionId'; // Mock store actions used by the hook diff --git a/ui/hooks/rewards/useGeoRewardsMetadata.test.ts b/ui/hooks/rewards/useGeoRewardsMetadata.test.ts index 846a1f9b0594..d69727aa3913 100644 --- a/ui/hooks/rewards/useGeoRewardsMetadata.test.ts +++ b/ui/hooks/rewards/useGeoRewardsMetadata.test.ts @@ -1,6 +1,6 @@ import { act } from '@testing-library/react-hooks'; import { waitFor } from '@testing-library/react'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { RewardsGeoMetadata } from '../../../shared/types/rewards'; import { useGeoRewardsMetadata } from './useGeoRewardsMetadata'; diff --git a/ui/hooks/rewards/useLinkAccountAddress.test.tsx b/ui/hooks/rewards/useLinkAccountAddress.test.tsx index a6dc281783d4..9d8690ee2a0b 100644 --- a/ui/hooks/rewards/useLinkAccountAddress.test.tsx +++ b/ui/hooks/rewards/useLinkAccountAddress.test.tsx @@ -1,7 +1,7 @@ import { act } from '@testing-library/react-hooks'; import React from 'react'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../contexts/metametrics'; import { createMockInternalAccount } from '../../../test/jest/mocks'; import { diff --git a/ui/hooks/rewards/useLinkAccountGroup.test.tsx b/ui/hooks/rewards/useLinkAccountGroup.test.tsx index f529a8e21978..94414a5b461e 100644 --- a/ui/hooks/rewards/useLinkAccountGroup.test.tsx +++ b/ui/hooks/rewards/useLinkAccountGroup.test.tsx @@ -8,7 +8,7 @@ import { AccountWalletStatus, } from '@metamask/account-api'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../contexts/metametrics'; import { createMockInternalAccount } from '../../../test/jest/mocks'; import { createMockMultichainAccountsState } from '../../selectors/multichain-accounts/test-utils'; diff --git a/ui/hooks/rewards/useOptIn.test.tsx b/ui/hooks/rewards/useOptIn.test.tsx index 5a2bce527fa1..14a601838ffc 100644 --- a/ui/hooks/rewards/useOptIn.test.tsx +++ b/ui/hooks/rewards/useOptIn.test.tsx @@ -1,7 +1,7 @@ import { act } from '@testing-library/react-hooks'; import React from 'react'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../contexts/metametrics'; import { MetaMetricsEventName, diff --git a/ui/hooks/rewards/useSeasonStatus.test.ts b/ui/hooks/rewards/useSeasonStatus.test.ts index a349ff7cae84..fd46af055aff 100644 --- a/ui/hooks/rewards/useSeasonStatus.test.ts +++ b/ui/hooks/rewards/useSeasonStatus.test.ts @@ -1,6 +1,6 @@ import { act } from '@testing-library/react-hooks'; import { waitFor } from '@testing-library/react'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { SeasonDtoState, SeasonStatusState, diff --git a/ui/hooks/rewards/useValidateReferralCode.test.tsx b/ui/hooks/rewards/useValidateReferralCode.test.tsx index 9b3f88efc9ee..52be14c37166 100644 --- a/ui/hooks/rewards/useValidateReferralCode.test.tsx +++ b/ui/hooks/rewards/useValidateReferralCode.test.tsx @@ -1,6 +1,6 @@ import { act } from '@testing-library/react-hooks'; import { waitFor } from '@testing-library/react'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import { useValidateReferralCode } from './useValidateReferralCode'; jest.useFakeTimers(); diff --git a/ui/hooks/shield/useClaimState.ts b/ui/hooks/shield/useClaimState.ts index 7b743534cd00..ed1e5d576f3e 100644 --- a/ui/hooks/shield/useClaimState.ts +++ b/ui/hooks/shield/useClaimState.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { Attachment as ClaimAttachment } from '@metamask/claims-controller'; import { useClaims } from '../../contexts/claims/claims'; import { generateClaimSignature } from '../../store/actions'; diff --git a/ui/hooks/snaps/useSnapNameResolution.test.ts b/ui/hooks/snaps/useSnapNameResolution.test.ts index a19048f4ccc5..8f125539b789 100644 --- a/ui/hooks/snaps/useSnapNameResolution.test.ts +++ b/ui/hooks/snaps/useSnapNameResolution.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import baseMockState from '../../../test/data/mock-state.json'; import { useSnapNameResolution } from './useSnapNameResolution'; diff --git a/ui/hooks/snaps/useSnapNavigation.ts b/ui/hooks/snaps/useSnapNavigation.ts index 6a6230925cdc..86261742fef1 100644 --- a/ui/hooks/snaps/useSnapNavigation.ts +++ b/ui/hooks/snaps/useSnapNavigation.ts @@ -1,5 +1,5 @@ import { useCallback, useMemo } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { parseMetaMaskUrl } from '@metamask/snaps-utils'; import { getSnapRoute } from '../../helpers/utils/util'; diff --git a/ui/hooks/subscription/useAddFundTrigger.test.ts b/ui/hooks/subscription/useAddFundTrigger.test.ts index 40d41ecef312..5e1a1d8e6b2b 100644 --- a/ui/hooks/subscription/useAddFundTrigger.test.ts +++ b/ui/hooks/subscription/useAddFundTrigger.test.ts @@ -9,7 +9,7 @@ import { } from '@metamask/subscription-controller'; import { cloneDeep } from 'lodash'; import { flushPromises } from '../../../test/lib/timer-helpers'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import mockState from '../../../test/data/mock-state.json'; import * as actions from '../../store/actions'; import { MINUTE } from '../../../shared/constants/time'; diff --git a/ui/hooks/subscription/useHandlePayment.ts b/ui/hooks/subscription/useHandlePayment.ts index e9d733e3325a..e3ec02aed71e 100644 --- a/ui/hooks/subscription/useHandlePayment.ts +++ b/ui/hooks/subscription/useHandlePayment.ts @@ -1,5 +1,5 @@ import { useCallback, useMemo } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { CRYPTO_PAYMENT_METHOD_ERRORS, PAYMENT_TYPES, diff --git a/ui/hooks/subscription/useSubscription.ts b/ui/hooks/subscription/useSubscription.ts index cdc9c3f8880c..88da96d78784 100644 --- a/ui/hooks/subscription/useSubscription.ts +++ b/ui/hooks/subscription/useSubscription.ts @@ -12,7 +12,7 @@ import { ModalType, } from '@metamask/subscription-controller'; import log from 'loglevel'; -import { useLocation, useNavigate } from 'react-router-dom-v5-compat'; +import { useLocation, useNavigate } from 'react-router-dom'; import { TransactionParams, TransactionType, diff --git a/ui/hooks/subscription/useSubscriptionPricing.test.ts b/ui/hooks/subscription/useSubscriptionPricing.test.ts index 8d2baf5def85..ffd2fab7cc70 100644 --- a/ui/hooks/subscription/useSubscriptionPricing.test.ts +++ b/ui/hooks/subscription/useSubscriptionPricing.test.ts @@ -6,7 +6,7 @@ import { ProductType, PaymentType, } from '@metamask/subscription-controller'; -import { renderHookWithProvider } from '../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../test/lib/render-helpers-navigate'; import baseMockState from '../../../test/data/mock-state.json'; import { useSubscriptionPricing, diff --git a/ui/hooks/useAlerts.test.ts b/ui/hooks/useAlerts.test.ts index a2db52fc3052..f8254f711c9a 100644 --- a/ui/hooks/useAlerts.test.ts +++ b/ui/hooks/useAlerts.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { Alert, AlertSeverity, diff --git a/ui/hooks/useCurrencyRatePolling.test.ts b/ui/hooks/useCurrencyRatePolling.test.ts index 51958472a443..a9c4cab778bb 100644 --- a/ui/hooks/useCurrencyRatePolling.test.ts +++ b/ui/hooks/useCurrencyRatePolling.test.ts @@ -1,6 +1,6 @@ import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller'; import { BtcScope } from '@metamask/keyring-api'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { getOriginalNativeTokenSymbol } from '../helpers/utils/isOriginalNativeTokenSymbol'; import { currencyRateStartPolling, diff --git a/ui/hooks/useCurrentAsset.js b/ui/hooks/useCurrentAsset.js index c5e8cbd086d9..4b593190e5a9 100644 --- a/ui/hooks/useCurrentAsset.js +++ b/ui/hooks/useCurrentAsset.js @@ -1,5 +1,5 @@ import { useSelector } from 'react-redux'; -import { useMatch } from 'react-router-dom-v5-compat'; +import { useMatch } from 'react-router-dom'; import { getTokens } from '../ducks/metamask/metamask'; import { getCurrentChainId } from '../../shared/modules/selectors/networks'; import { ASSET_ROUTE } from '../helpers/constants/routes'; diff --git a/ui/hooks/useDecodedTransactionData.test.ts b/ui/hooks/useDecodedTransactionData.test.ts index a608ca386983..01249c6948ef 100644 --- a/ui/hooks/useDecodedTransactionData.test.ts +++ b/ui/hooks/useDecodedTransactionData.test.ts @@ -7,7 +7,7 @@ import { import { Hex } from '@metamask/utils'; import { renderHook } from '@testing-library/react-hooks'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { decodeTransactionData } from '../store/actions'; import { TRANSACTION_DATA_UNISWAP, diff --git a/ui/hooks/useDisplayName.test.ts b/ui/hooks/useDisplayName.test.ts index d6384861b95f..566ed25fe0a8 100644 --- a/ui/hooks/useDisplayName.test.ts +++ b/ui/hooks/useDisplayName.test.ts @@ -7,7 +7,7 @@ import { FIRST_PARTY_CONTRACT_NAMES, } from '../../shared/constants/first-party-contracts'; import mockState from '../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { getDomainResolutions } from '../ducks/domains'; import { IconName } from '../components/component-library'; import { IconColor } from '../helpers/constants/design-system'; diff --git a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts index 5d12650cc08e..64a7a931a99e 100644 --- a/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts +++ b/ui/hooks/useIsOriginalNativeTokenSymbol.test.ts @@ -1,6 +1,6 @@ import { waitFor } from '@testing-library/react'; import { CaipChainId, Hex } from '@metamask/utils'; -import { renderHookWithProviderTyped } from '../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../test/lib/render-helpers-navigate'; import * as SelectorsModule from '../selectors/selectors'; import * as MultichainSelectorsModule from '../selectors/multichain'; import * as IsOriginalNativeTokenSymbolModule from '../helpers/utils/isOriginalNativeTokenSymbol'; diff --git a/ui/hooks/useIsOriginalTokenSymbol.test.js b/ui/hooks/useIsOriginalTokenSymbol.test.js index 136481b9b968..f6256338fea6 100644 --- a/ui/hooks/useIsOriginalTokenSymbol.test.js +++ b/ui/hooks/useIsOriginalTokenSymbol.test.js @@ -2,7 +2,7 @@ import { act } from '@testing-library/react-hooks'; import * as actions from '../store/actions'; import mockState from '../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { useIsOriginalTokenSymbol } from './useIsOriginalTokenSymbol'; // Mocking the getTokenSymbol function diff --git a/ui/hooks/useMultiPolling.test.ts b/ui/hooks/useMultiPolling.test.ts index 865221eeac99..99a1446eaf20 100644 --- a/ui/hooks/useMultiPolling.test.ts +++ b/ui/hooks/useMultiPolling.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import useMultiPolling from './useMultiPolling'; describe('useMultiPolling', () => { diff --git a/ui/hooks/useMultichainAccountsIntroModal.test.ts b/ui/hooks/useMultichainAccountsIntroModal.test.ts index b31b0659f9cc..67d31699da55 100644 --- a/ui/hooks/useMultichainAccountsIntroModal.test.ts +++ b/ui/hooks/useMultichainAccountsIntroModal.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { useMultichainAccountsIntroModal, BIP44_ACCOUNTS_INTRODUCTION_VERSION, diff --git a/ui/hooks/useMultichainBalances.test.ts b/ui/hooks/useMultichainBalances.test.ts index 8deedbcb20fa..9dc738207512 100644 --- a/ui/hooks/useMultichainBalances.test.ts +++ b/ui/hooks/useMultichainBalances.test.ts @@ -1,5 +1,5 @@ import { createBridgeMockStore } from '../../test/data/bridge/mock-bridge-store'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { useMultichainBalances } from './useMultichainBalances'; describe('useMultichainBalances', () => { diff --git a/ui/hooks/useMultichainSelector.test.ts b/ui/hooks/useMultichainSelector.test.ts index f04fef64783a..74c46445d8cc 100644 --- a/ui/hooks/useMultichainSelector.test.ts +++ b/ui/hooks/useMultichainSelector.test.ts @@ -1,6 +1,6 @@ import { InternalAccount } from '@metamask/keyring-internal-api'; import { createMockInternalAccount } from '../../test/jest/mocks'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { getSelectedNetworkClientId } from '../../shared/modules/selectors/networks'; import { MultichainState, getMultichainIsEvm } from '../selectors/multichain'; import { CHAIN_IDS } from '../../shared/constants/network'; diff --git a/ui/hooks/useNetworkConnectionBanner.test.ts b/ui/hooks/useNetworkConnectionBanner.test.ts index 147f0c594efd..0e009a3b50fd 100644 --- a/ui/hooks/useNetworkConnectionBanner.test.ts +++ b/ui/hooks/useNetworkConnectionBanner.test.ts @@ -1,6 +1,6 @@ import { act } from '@testing-library/react'; import { RpcEndpointType } from '@metamask/network-controller'; -import { renderHookWithProviderTyped } from '../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../test/lib/render-helpers-navigate'; import { selectFirstUnavailableEvmNetwork } from '../selectors/multichain/networks'; import { getNetworkConnectionBanner } from '../selectors/selectors'; import { updateNetworkConnectionBanner } from '../store/actions'; diff --git a/ui/hooks/usePolling.test.js b/ui/hooks/usePolling.test.js index a556bb86be54..a08ea872bd84 100644 --- a/ui/hooks/usePolling.test.js +++ b/ui/hooks/usePolling.test.js @@ -1,5 +1,5 @@ import { cleanup } from '@testing-library/react-hooks'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import usePolling from './usePolling'; describe('usePolling', () => { diff --git a/ui/hooks/useSafeNavigation.test.ts b/ui/hooks/useSafeNavigation.test.ts deleted file mode 100644 index 3d5fccab2f4c..000000000000 --- a/ui/hooks/useSafeNavigation.test.ts +++ /dev/null @@ -1,435 +0,0 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; -import { useSetNavState } from '../contexts/navigation-state'; -import { useSafeNavigation } from './useSafeNavigation'; - -// Mock dependencies -jest.mock('react-router-dom-v5-compat', () => ({ - useNavigate: jest.fn(), - useLocation: jest.fn(), -})); - -jest.mock('../contexts/navigation-state', () => ({ - useSetNavState: jest.fn(), -})); - -describe('useSafeNavigation', () => { - let mockDefaultNavigate: jest.Mock; - let mockSetNavState: jest.Mock; - let mockLocation: { pathname: string }; - - beforeEach(() => { - jest.useFakeTimers(); - mockDefaultNavigate = jest.fn(); - mockSetNavState = jest.fn(); - mockLocation = { pathname: '/test' }; - - (useNavigate as jest.Mock).mockReturnValue(mockDefaultNavigate); - (useSetNavState as jest.Mock).mockReturnValue(mockSetNavState); - (useLocation as jest.Mock).mockReturnValue(mockLocation); - }); - - afterEach(() => { - jest.clearAllMocks(); - jest.useRealTimers(); - }); - - describe('with defaultNavigate', () => { - it('should navigate without state and clean up', async () => { - const { result } = renderHook(() => useSafeNavigation()); - - act(() => { - result.current.navigate('/destination'); - }); - - // Should set state to null (no state provided) - expect(mockSetNavState).toHaveBeenCalledWith(null); - - // Should call default navigate - expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', { - replace: false, - state: undefined, - }); - - // Should schedule cleanup - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenCalledTimes(2); - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should navigate with state and clean up after 100ms', async () => { - const { result } = renderHook(() => useSafeNavigation()); - const testState = { stayOnHomePage: true }; - - act(() => { - result.current.navigate('/destination', { state: testState }); - }); - - // Should set state immediately - expect(mockSetNavState).toHaveBeenCalledWith(testState); - - // Should call default navigate with state - expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', { - replace: false, - state: testState, - }); - - // State should not be cleared immediately - expect(mockSetNavState).toHaveBeenCalledTimes(1); - - // After 100ms, state should be cleared - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenCalledTimes(2); - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should handle replace option', () => { - const { result } = renderHook(() => useSafeNavigation()); - - act(() => { - result.current.navigate('/destination', { replace: true }); - }); - - expect(mockDefaultNavigate).toHaveBeenCalledWith('/destination', { - replace: true, - state: undefined, - }); - }); - }); - - describe('with customNavigate', () => { - it('should navigate without state and clean up (bug fix)', async () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - - act(() => { - result.current.navigate('/destination'); - }); - - // Should set state to null - expect(mockSetNavState).toHaveBeenCalledWith(null); - - // Should call custom navigate - expect(mockCustomNavigate).toHaveBeenCalledWith( - '/destination', - undefined, - ); - - // Should NOT call default navigate - expect(mockDefaultNavigate).not.toHaveBeenCalled(); - - // CRITICAL: Cleanup should still happen after 100ms (this is the bug fix) - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenCalledTimes(2); - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should navigate with state and clean up after 100ms (bug fix)', async () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - const testState = { stayOnHomePage: true }; - - act(() => { - result.current.navigate('/destination', { state: testState }); - }); - - // Should set state immediately - expect(mockSetNavState).toHaveBeenCalledWith(testState); - - // Should call custom navigate with state - expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', { - state: testState, - }); - - // Should NOT call default navigate - expect(mockDefaultNavigate).not.toHaveBeenCalled(); - - // State should not be cleared immediately - expect(mockSetNavState).toHaveBeenCalledTimes(1); - - // CRITICAL: After 100ms, state MUST be cleared (this is the bug fix) - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenCalledTimes(2); - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should handle replace option with custom navigate', () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - - act(() => { - result.current.navigate('/destination', { replace: true }); - }); - - expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', { - replace: true, - }); - - // Cleanup should still happen - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should handle both state and replace options with custom navigate', () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - const testState = { foo: 'bar' }; - - act(() => { - result.current.navigate('/destination', { - state: testState, - replace: true, - }); - }); - - expect(mockSetNavState).toHaveBeenCalledWith(testState); - expect(mockCustomNavigate).toHaveBeenCalledWith('/destination', { - state: testState, - replace: true, - }); - - // Cleanup should happen after 100ms - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - }); - - describe('memory leak prevention', () => { - it('should clean up state for multiple consecutive navigations with customNavigate', () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - - // First navigation - act(() => { - result.current.navigate('/page1', { state: { page: 1 } }); - }); - - expect(mockSetNavState).toHaveBeenCalledWith({ page: 1 }); - - // Second navigation before cleanup - this clears the first timeout - act(() => { - result.current.navigate('/page2', { state: { page: 2 } }); - }); - - expect(mockSetNavState).toHaveBeenCalledWith({ page: 2 }); - - // Advance timers - only the second cleanup should execute (first was cleared) - act(() => { - jest.advanceTimersByTime(100); - }); - - // Should have been called: page1 state, page2 state, cleanup2 only = 3 calls - // (cleanup1 was cleared when page2 navigation happened) - expect(mockSetNavState).toHaveBeenCalledTimes(3); - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should not accumulate state across multiple navigations', () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - - // Multiple navigations - each clears the previous timeout - for (let i = 0; i < 5; i++) { - act(() => { - result.current.navigate(`/page${i}`, { state: { id: i } }); - }); - } - - // Fast forward all timers - act(() => { - jest.advanceTimersByTime(500); - }); - - // Last call should always be cleanup (null) - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - - // Should have 5 state sets + 1 cleanup (only the last one) = 6 total calls - // Previous 4 cleanup timeouts were cleared by subsequent navigations - expect(mockSetNavState).toHaveBeenCalledTimes(6); - }); - }); - - describe('return value', () => { - it('should return navigate function and location', () => { - const { result } = renderHook(() => useSafeNavigation()); - - expect(result.current).toHaveProperty('navigate'); - expect(result.current).toHaveProperty('location'); - expect(typeof result.current.navigate).toBe('function'); - expect(result.current.location).toBe(mockLocation); - }); - - it('should maintain stable navigate reference', () => { - const { result, rerender } = renderHook(() => useSafeNavigation()); - const firstNavigate = result.current.navigate; - - rerender(); - - expect(result.current.navigate).toBe(firstNavigate); - }); - }); - - describe('edge cases', () => { - it('should handle navigation with empty state object', () => { - const { result } = renderHook(() => useSafeNavigation()); - - act(() => { - result.current.navigate('/destination', { state: {} }); - }); - - expect(mockSetNavState).toHaveBeenCalledWith({}); - - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should handle navigation with null state explicitly', () => { - const { result } = renderHook(() => useSafeNavigation()); - - act(() => { - // @ts-expect-error - testing edge case - result.current.navigate('/destination', { state: null }); - }); - - expect(mockSetNavState).toHaveBeenCalledWith(null); - }); - - it('should handle navigation with undefined options', () => { - const mockCustomNavigate = jest.fn(); - const { result } = renderHook(() => - useSafeNavigation(mockCustomNavigate), - ); - - act(() => { - result.current.navigate('/destination', undefined); - }); - - expect(mockCustomNavigate).toHaveBeenCalledWith( - '/destination', - undefined, - ); - expect(mockSetNavState).toHaveBeenCalledWith(null); - }); - }); - - describe('timeout cleanup', () => { - it('should clear previous timeout when navigate is called multiple times', () => { - const { result } = renderHook(() => useSafeNavigation()); - - act(() => { - result.current.navigate('/path1', { state: { first: true } }); - }); - - // First timeout scheduled, advance time partially - act(() => { - jest.advanceTimersByTime(50); - }); - - // Navigate again before first timeout completes - act(() => { - result.current.navigate('/path2', { state: { second: true } }); - }); - - // Advance remaining time from first timeout (should not trigger) - act(() => { - jest.advanceTimersByTime(50); - }); - - // Only the second navigation's state should remain (not cleaned up yet) - // First timeout was cleared, so we should have: initial calls + second call - expect(mockSetNavState).toHaveBeenCalledWith({ first: true }); - expect(mockSetNavState).toHaveBeenCalledWith({ second: true }); - - // Now advance time to trigger second timeout - act(() => { - jest.advanceTimersByTime(50); - }); - - // Second timeout should clean up - expect(mockSetNavState).toHaveBeenLastCalledWith(null); - }); - - it('should clear timeout on unmount', () => { - const { result, unmount } = renderHook(() => useSafeNavigation()); - - act(() => { - result.current.navigate('/destination', { state: { test: true } }); - }); - - // Unmount before timeout completes - unmount(); - - // Advance time past when cleanup would have happened - act(() => { - jest.advanceTimersByTime(100); - }); - - // The cleanup after unmount should not trigger setNavState again - // We should only see the initial call, not a cleanup call - const callCount = mockSetNavState.mock.calls.length; - - // Advancing timers again should not add more calls - act(() => { - jest.advanceTimersByTime(100); - }); - - expect(mockSetNavState.mock.calls.length).toBe(callCount); - }); - - it('should not accumulate timeouts', () => { - const { result } = renderHook(() => useSafeNavigation()); - - // Navigate 5 times quickly - act(() => { - for (let i = 0; i < 5; i++) { - result.current.navigate(`/path${i}`, { state: { count: i } }); - } - }); - - // Clear all mock calls to focus on cleanup behavior - mockSetNavState.mockClear(); - - // Advance time to trigger cleanup - act(() => { - jest.advanceTimersByTime(100); - }); - - // Only ONE cleanup should happen (from the last navigate call) - expect(mockSetNavState).toHaveBeenCalledTimes(1); - expect(mockSetNavState).toHaveBeenCalledWith(null); - }); - }); -}); diff --git a/ui/hooks/useSafeNavigation.ts b/ui/hooks/useSafeNavigation.ts deleted file mode 100644 index 4498e6c1a9d7..000000000000 --- a/ui/hooks/useSafeNavigation.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; -import { useCallback, useRef, useEffect } from 'react'; -import { useSetNavState } from '../contexts/navigation-state'; - -type SafeNavigateOptions = { - state?: Record; - replace?: boolean; -}; - -export const useSafeNavigation = ( - customNavigate?: (path: string, options?: SafeNavigateOptions) => void, -): { - navigate: (path: string, options?: SafeNavigateOptions) => void; - location: ReturnType; -} => { - const defaultNavigate = useNavigate(); - const location = useLocation(); - const setNavState = useSetNavState(); - const cleanupTimeoutRef = useRef(null); - - // Clear timeout on unmount to prevent memory leaks - useEffect(() => { - return () => { - if (cleanupTimeoutRef.current) { - clearTimeout(cleanupTimeoutRef.current); - } - }; - }, []); - - // Memoize the navigate function to prevent unnecessary re-renders - // This is critical for useEffect dependencies that include navigate - const safeNavigate = useCallback( - (path: string, options?: SafeNavigateOptions) => { - if (options?.state) { - setNavState(options.state); - } else { - setNavState(null); - } - - // Clear any existing timeout before scheduling a new one - if (cleanupTimeoutRef.current) { - clearTimeout(cleanupTimeoutRef.current); - } - - // Schedule cleanup for both custom and default navigate to prevent memory leaks - cleanupTimeoutRef.current = setTimeout(() => { - setNavState(null); - cleanupTimeoutRef.current = null; - }, 100); - - if (customNavigate) { - customNavigate(path, options); - return; - } - - defaultNavigate(path, { - replace: Boolean(options?.replace), - state: options?.state, - }); - }, - [customNavigate, defaultNavigate, setNavState], - ); - - return { - navigate: safeNavigate, - location, - }; -}; diff --git a/ui/hooks/useSegmentContext.js b/ui/hooks/useSegmentContext.js index c1fad3a05f59..5887e31aca10 100644 --- a/ui/hooks/useSegmentContext.js +++ b/ui/hooks/useSegmentContext.js @@ -1,5 +1,5 @@ import { useSelector } from 'react-redux'; -import { useLocation, matchPath } from 'react-router-dom-v5-compat'; +import { useLocation, matchPath } from 'react-router-dom'; import { PATH_NAME_MAP, getPaths } from '../helpers/constants/routes'; import { txDataSelector } from '../selectors'; @@ -19,7 +19,6 @@ export function useSegmentContext() { const paths = getPaths(); // Try to match the current location against each path - // Note: v5-compat matchPath uses v6 signature (pattern first, pathname second) let match; paths.find((path) => { match = matchPath( diff --git a/ui/hooks/useShouldShowSpeedUp.test.ts b/ui/hooks/useShouldShowSpeedUp.test.ts index 2de83c26021f..b87d7fae9148 100644 --- a/ui/hooks/useShouldShowSpeedUp.test.ts +++ b/ui/hooks/useShouldShowSpeedUp.test.ts @@ -1,5 +1,5 @@ import { act } from '@testing-library/react-hooks'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import mockState from '../../test/data/mock-state.json'; import { useShouldShowSpeedUp } from './useShouldShowSpeedUp'; diff --git a/ui/hooks/useTheme.test.ts b/ui/hooks/useTheme.test.ts index 486117f5e13a..be2dc9e1f7ef 100644 --- a/ui/hooks/useTheme.test.ts +++ b/ui/hooks/useTheme.test.ts @@ -1,5 +1,5 @@ import { ThemeType } from '../../shared/constants/preferences'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { useTheme } from './useTheme'; jest.mock('../selectors', () => ({ diff --git a/ui/hooks/useTokenDetectionPolling.test.ts b/ui/hooks/useTokenDetectionPolling.test.ts index 52f6fb2fbf8a..a84ff6b18d2a 100644 --- a/ui/hooks/useTokenDetectionPolling.test.ts +++ b/ui/hooks/useTokenDetectionPolling.test.ts @@ -1,5 +1,5 @@ import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { tokenDetectionStartPolling, tokenDetectionStopPollingByPollingToken, diff --git a/ui/hooks/useTokenListPolling.test.ts b/ui/hooks/useTokenListPolling.test.ts index f60bef7b0027..2be5916de8a3 100644 --- a/ui/hooks/useTokenListPolling.test.ts +++ b/ui/hooks/useTokenListPolling.test.ts @@ -1,6 +1,6 @@ import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller'; import { BtcScope } from '@metamask/keyring-api'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { tokenListStartPolling, tokenListStopPollingByPollingToken, diff --git a/ui/hooks/useTokenRatesPolling.test.ts b/ui/hooks/useTokenRatesPolling.test.ts index a16f9c63b730..8d57253ba562 100644 --- a/ui/hooks/useTokenRatesPolling.test.ts +++ b/ui/hooks/useTokenRatesPolling.test.ts @@ -1,6 +1,6 @@ import { AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS } from '@metamask/multichain-network-controller'; import { BtcScope } from '@metamask/keyring-api'; -import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../test/lib/render-helpers-navigate'; import { tokenRatesStartPolling, tokenRatesStopPollingByPollingToken, diff --git a/ui/hooks/useTransactionDisplayData.js b/ui/hooks/useTransactionDisplayData.js index 6115fe801ea4..93a6645897c4 100644 --- a/ui/hooks/useTransactionDisplayData.js +++ b/ui/hooks/useTransactionDisplayData.js @@ -8,7 +8,7 @@ import { getKnownMethodData, getSelectedAddress, selectERC20TokensByChain, -} from '../selectors/selectors'; +} from '../selectors'; import { getStatusKey, getTransactionTypeTitle, diff --git a/ui/layouts/header.tsx b/ui/layouts/header.tsx index dadd8d148199..fad46c9926e6 100644 --- a/ui/layouts/header.tsx +++ b/ui/layouts/header.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { AppHeader } from '../components/multichain'; import { hideAppHeader, showAppHeader } from '../pages/routes/utils'; diff --git a/ui/layouts/route-with-layout.tsx b/ui/layouts/route-with-layout.tsx index 61f6b0f59639..d7d15ea84f9d 100644 --- a/ui/layouts/route-with-layout.tsx +++ b/ui/layouts/route-with-layout.tsx @@ -1,82 +1,69 @@ -import React, { ComponentType, ReactNode, useMemo } from 'react'; -import { Route, RouteComponentProps } from 'react-router-dom'; +import React, { ComponentType, ReactNode } from 'react'; +import type { RouteObject } from 'react-router-dom'; import Authenticated from '../helpers/higher-order-components/authenticated/authenticated.container'; +import Initialized from '../helpers/higher-order-components/initialized'; +import type { RootLayout } from './root-layout'; +import type { LegacyLayout } from './legacy-layout'; -type Props = { +export type RouteWithLayoutConfig = { path: string; - exact?: boolean; - component?: ComponentType; - children?: ReactNode; - layout: ComponentType<{ children: ReactNode }>; + element?: ReactNode; + component?: ComponentType; // eslint-disable-line @typescript-eslint/no-explicit-any + layout: + | typeof RootLayout + | typeof LegacyLayout + | ComponentType<{ children: ReactNode }>; authenticated?: boolean; + initialized?: boolean; + children?: ReactNode; }; -/* -Once migrated, we can use layouts like this: - }> - } /> - } /> - -*/ - /** - * Interim helper to wrap a component with a layout while we migrate React Router + * Helper function that creates a React Router v6 RouteObject with layout and auth wrapping. + * This is used with the useRoutes() hook for programmatic routing. * - * @param props - Route props - * @param props.path - Path for the route - * @param props.exact - Whether the route should match exactly - * @param props.component - The component to render for the route (receives route props) - * @param props.children - Alternative to component prop, renders children directly - * @param props.layout - The layout to use for the route - * @param props.authenticated - Whether to wrap with the Authenticated component - * @returns Component wrapped in the layout + * @param config - Route configuration + * @param config.path - Path for the route + * @param config.element - The element to render for the route + * @param config.component - Component to instantiate (alternative to element) + * @param config.layout - The layout to use for the route + * @param config.authenticated - Whether to wrap with the Authenticated component + * @param config.initialized - Whether to wrap with the Initialized component + * @param config.children - Nested route content + * @returns RouteObject ready for useRoutes() */ -export const RouteWithLayout = ({ - layout: Layout, - component: Component, - children, - authenticated, - ...routeProps -}: Props) => { - // Exclude function children from deps to prevent re-memoization when render functions change reference - // This is safe because render functions from createV5CompatRoute don't close over changing values - const childrenDep = typeof children === 'function' ? null : children; +export const createRouteWithLayout = ( + config: RouteWithLayoutConfig, +): RouteObject => { + const { + path, + layout: Layout, + element, + component: Component, + authenticated, + initialized, + children, + } = config; - const WrappedComponent = useMemo(() => { - if (Component) { - return (props: RouteComponentProps) => ( - - - - ); - } - return (props: RouteComponentProps) => ( - - {typeof children === 'function' ? children(props) : children} - - ); - }, [Layout, Component, childrenDep]); + // Determine content: children > element > component + let content: ReactNode = + children || element || (Component ? : null); + + // Wrap with Initialized first (outermost guard) + if (initialized && content) { + content = {content}; + } - if (authenticated) { - return ; + // Then wrap with Authenticated (inner guard) + if (authenticated && content) { + content = {content}; } - return ( - { - let content; - if (Component) { - content = ; - } else if (typeof children === 'function') { - content = children(props); - } else { - content = children; - } + // Finally wrap with Layout + const wrappedElement = {content}; - return {content}; - }} - /> - ); + return { + path, + element: wrappedElement, + }; }; diff --git a/ui/pages/asset/asset.tsx b/ui/pages/asset/asset.tsx index 7ec76073e488..cf13f513e5e1 100644 --- a/ui/pages/asset/asset.tsx +++ b/ui/pages/asset/asset.tsx @@ -2,7 +2,7 @@ import { Nft } from '@metamask/assets-controllers'; import { CaipChainId, Hex } from '@metamask/utils'; import React, { useEffect } from 'react'; import { useSelector } from 'react-redux'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate, useParams } from 'react-router-dom'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import NftDetails from '../../components/app/assets/nfts/nft-details/nft-details'; import { getNFTsByChainId } from '../../ducks/metamask/metamask'; @@ -11,21 +11,13 @@ import { getTokenByAccountAndAddressAndChainId } from '../../selectors/assets'; import NativeAsset from './components/native-asset'; import TokenAsset from './components/token-asset'; -type AssetProps = { - params: { - chainId?: Hex; - asset?: string; - id?: string; - }; -}; +const Asset = () => { + const params = useParams<{ + chainId: Hex; + asset: string; + id: string; + }>(); -/** - * A page representing a native, token, or NFT asset - * - * @param options0 - Component props - * @param options0.params - Route parameters including chainId, asset, and id - */ -const Asset = ({ params }: AssetProps) => { const { chainId, asset, id } = params; const decodedAsset = asset ? decodeURIComponent(asset) : undefined; diff --git a/ui/pages/asset/components/asset-options.js b/ui/pages/asset/components/asset-options.js index 302c0e9fa529..0e62037dadb4 100644 --- a/ui/pages/asset/components/asset-options.js +++ b/ui/pages/asset/components/asset-options.js @@ -1,7 +1,6 @@ import React, { useContext, useRef, useState } from 'react'; import PropTypes from 'prop-types'; - -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { I18nContext } from '../../../contexts/i18n'; import { MetaMetricsContext } from '../../../contexts/metametrics'; diff --git a/ui/pages/asset/components/asset-page.tsx b/ui/pages/asset/components/asset-page.tsx index 5d9d6efc0ef5..dea446a228be 100644 --- a/ui/pages/asset/components/asset-page.tsx +++ b/ui/pages/asset/components/asset-page.tsx @@ -15,7 +15,7 @@ import { } from '@metamask/utils'; import React, { ReactNode, useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { AssetType } from '../../../../shared/constants/transaction'; import { isEvmChainId } from '../../../../shared/lib/asset-utils'; import { endTrace, TraceName } from '../../../../shared/lib/trace'; diff --git a/ui/pages/asset/components/token-asset.tsx b/ui/pages/asset/components/token-asset.tsx index db071369cc5d..7b9bc9dcf2f1 100644 --- a/ui/pages/asset/components/token-asset.tsx +++ b/ui/pages/asset/components/token-asset.tsx @@ -9,7 +9,7 @@ import { } from '@metamask/utils'; import React, { useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { formatChainIdToCaip } from '@metamask/bridge-controller'; import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; diff --git a/ui/pages/asset/components/token-buttons.tsx b/ui/pages/asset/components/token-buttons.tsx index a982b7d0d705..b2dc89e54972 100644 --- a/ui/pages/asset/components/token-buttons.tsx +++ b/ui/pages/asset/components/token-buttons.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useContext, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; ///: BEGIN:ONLY_INCLUDE_IF(multichain) import { isEvmAccountType } from '@metamask/keyring-api'; import { CaipAssetType } from '@metamask/utils'; diff --git a/ui/pages/asset/hooks/useChartTimeRanges.test.ts b/ui/pages/asset/hooks/useChartTimeRanges.test.ts index 16220551cb96..bca4253fc191 100644 --- a/ui/pages/asset/hooks/useChartTimeRanges.test.ts +++ b/ui/pages/asset/hooks/useChartTimeRanges.test.ts @@ -1,5 +1,5 @@ import { CaipAssetType } from '@metamask/utils'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useChartTimeRanges } from './useChartTimeRanges'; describe('useChartTimeRanges', () => { diff --git a/ui/pages/asset/hooks/useCurrentPrice.test.ts b/ui/pages/asset/hooks/useCurrentPrice.test.ts index d0fac4b631de..2eb4b7b105b0 100644 --- a/ui/pages/asset/hooks/useCurrentPrice.test.ts +++ b/ui/pages/asset/hooks/useCurrentPrice.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { AssetType } from '@metamask/bridge-controller'; import { EthScope, SolScope } from '@metamask/keyring-api'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { Asset } from '../types/asset'; import { useCurrentPrice } from './useCurrentPrice'; diff --git a/ui/pages/asset/hooks/useHistoricalPrices.test.ts b/ui/pages/asset/hooks/useHistoricalPrices.test.ts index ad1291c7ea4b..cf4ae74870fe 100644 --- a/ui/pages/asset/hooks/useHistoricalPrices.test.ts +++ b/ui/pages/asset/hooks/useHistoricalPrices.test.ts @@ -3,7 +3,7 @@ import { EthScope, SolScope } from '@metamask/keyring-api'; import { waitFor } from '@testing-library/react'; import { cloneDeep } from 'lodash'; import fetchWithCache from '../../../../shared/lib/fetch-with-cache'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { DEFAULT_USE_HISTORICAL_PRICES_METADATA, useHistoricalPrices, diff --git a/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx b/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx index 0fe89df424bb..90f8125dae8f 100644 --- a/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx +++ b/ui/pages/bridge/awaiting-signatures/awaiting-signatures-cancel-button.tsx @@ -1,5 +1,5 @@ import React, { useContext } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { CROSS_CHAIN_SWAP_ROUTE, PREPARE_SWAP_ROUTE, diff --git a/ui/pages/bridge/hooks/useDestinationAccount.test.tsx b/ui/pages/bridge/hooks/useDestinationAccount.test.tsx index 35541b61ace9..490efe41095a 100644 --- a/ui/pages/bridge/hooks/useDestinationAccount.test.tsx +++ b/ui/pages/bridge/hooks/useDestinationAccount.test.tsx @@ -6,7 +6,7 @@ import { MOCK_LEDGER_ACCOUNT, MOCK_SOLANA_ACCOUNT, } from '../../../../test/data/bridge/mock-bridge-store'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { getFromAccount, getFromChain, diff --git a/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx b/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx index f1d6c4d0521f..05e236a7487b 100644 --- a/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx +++ b/ui/pages/bridge/hooks/useExternalAccountResolution.test.tsx @@ -1,5 +1,5 @@ import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useExternalAccountResolution } from './useExternalAccountResolution'; const renderUseExternalAccountResolution = ( diff --git a/ui/pages/bridge/hooks/useGasIncluded7702.test.ts b/ui/pages/bridge/hooks/useGasIncluded7702.test.ts index 517666f41243..8dd057b73194 100644 --- a/ui/pages/bridge/hooks/useGasIncluded7702.test.ts +++ b/ui/pages/bridge/hooks/useGasIncluded7702.test.ts @@ -1,5 +1,5 @@ import { act, waitFor } from '@testing-library/react'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { getIsSmartTransaction } from '../../../../shared/modules/selectors'; import { useGasIncluded7702 } from './useGasIncluded7702'; diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx index 92902febdc4b..60a7f771af36 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.test.tsx @@ -3,7 +3,7 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { renderHook } from '@testing-library/react-hooks'; import { Provider } from 'react-redux'; -import { MemoryRouter } from 'react-router-dom-v5-compat'; +import { MemoryRouter } from 'react-router-dom'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; import * as bridgeStatusActions from '../../../ducks/bridge-status/actions'; import { @@ -14,9 +14,9 @@ import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import useSubmitBridgeTransaction from './useSubmitBridgeTransaction'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); @@ -182,7 +182,6 @@ describe('ui/pages/bridge/hooks/useSubmitBridgeTransaction', () => { // Assert expect(mockUseNavigate).toHaveBeenCalledWith(DEFAULT_ROUTE, { - replace: false, state: { stayOnHomePage: true }, }); }); diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts index 5f061e300e47..48d1c2c6fe60 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts @@ -1,4 +1,5 @@ import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { isNonEvmChainId } from '@metamask/bridge-controller'; import type { QuoteMetadata, QuoteResponse } from '@metamask/bridge-controller'; import { @@ -16,7 +17,6 @@ import { getIsStxEnabled, } from '../../../ducks/bridge/selectors'; import { captureException } from '../../../../shared/lib/sentry'; -import { useSafeNavigation } from '../../../hooks/useSafeNavigation'; const ALLOWANCE_RESET_ERROR = 'Eth USDT allowance reset failed'; const APPROVAL_TX_ERROR = 'Approve transaction failed'; @@ -52,7 +52,7 @@ const isHardwareWalletUserRejection = (error: unknown): boolean => { }; export default function useSubmitBridgeTransaction() { - const { navigate } = useSafeNavigation(); + const navigate = useNavigate(); const dispatch = useDispatch(); const hardwareWalletUsed = useSelector(isHardwareWallet); diff --git a/ui/pages/bridge/index.test.tsx b/ui/pages/bridge/index.test.tsx index eed819695af9..9871ddbf2de1 100644 --- a/ui/pages/bridge/index.test.tsx +++ b/ui/pages/bridge/index.test.tsx @@ -6,10 +6,7 @@ import { setBackgroundConnection } from '../../store/background-connection'; import { MOCKS, CONSTANTS } from '../../../test/jest'; import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { createBridgeMockStore } from '../../../test/data/bridge/mock-bridge-store'; -import { - CROSS_CHAIN_SWAP_ROUTE, - PREPARE_SWAP_ROUTE, -} from '../../helpers/constants/routes'; +import { PREPARE_SWAP_ROUTE } from '../../helpers/constants/routes'; import CrossChainSwap from '.'; const mockResetBridgeState = jest.fn(); @@ -35,9 +32,9 @@ setBackgroundConnection({ } as any); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ pathname: '/cross-chain/swaps/prepare-swap-page', @@ -107,7 +104,7 @@ describe('Bridge', () => { const { container, getByText } = renderWithProvider( , store, - CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE, + PREPARE_SWAP_ROUTE, ); expect(getByText('Swap')).toBeInTheDocument(); diff --git a/ui/pages/bridge/index.tsx b/ui/pages/bridge/index.tsx index 6edaa5f1139b..6d7199c61510 100644 --- a/ui/pages/bridge/index.tsx +++ b/ui/pages/bridge/index.tsx @@ -1,6 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Route, Routes } from 'react-router-dom-v5-compat'; +import { Route, Routes, useNavigate, useLocation } from 'react-router-dom'; import { UnifiedSwapBridgeEventName, isNonEvmChainId, @@ -10,10 +10,10 @@ import { clearSwapsState } from '../../ducks/swaps/swaps'; import { DEFAULT_ROUTE, PREPARE_SWAP_ROUTE, - CROSS_CHAIN_SWAP_ROUTE, AWAITING_SIGNATURES_ROUTE, TRANSACTION_SHIELD_ROUTE, } from '../../helpers/constants/routes'; +import { toRelativeRoutePath } from '../routes/utils'; import { resetBackgroundSwapsState } from '../../store/actions'; import { ButtonIcon, @@ -40,29 +40,20 @@ import { useQuoteFetchEvents } from '../../hooks/bridge/useQuoteFetchEvents'; import { TextVariant } from '../../helpers/constants/design-system'; import { useTxAlerts } from '../../hooks/bridge/useTxAlerts'; import { getFromChain, getBridgeQuotes } from '../../ducks/bridge/selectors'; -import { useSafeNavigation } from '../../hooks/useSafeNavigation'; import PrepareBridgePage from './prepare/prepare-bridge-page'; import AwaitingSignaturesCancelButton from './awaiting-signatures/awaiting-signatures-cancel-button'; import AwaitingSignatures from './awaiting-signatures/awaiting-signatures'; import { BridgeTransactionSettingsModal } from './prepare/bridge-transaction-settings-modal'; -type CrossChainSwapProps = { - location?: { - search?: string; - }; -}; - -const CrossChainSwap = ({ location }: CrossChainSwapProps) => { +const CrossChainSwap = () => { const t = useContext(I18nContext); // Load swaps feature flags so that we can use smart transactions useSwapsFeatureFlags(); useBridging(); - - const { navigate } = useSafeNavigation(); const dispatch = useDispatch(); - - const { search } = location ?? {}; + const navigate = useNavigate(); + const { search } = useLocation(); const isFromTransactionShield = new URLSearchParams(search || '').get( 'isFromTransactionShield', @@ -157,7 +148,7 @@ const CrossChainSwap = ({ location }: CrossChainSwapProps) => { { } /> diff --git a/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx b/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx index afaa158688a8..4a0734271505 100644 --- a/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx +++ b/ui/pages/bridge/prepare/bridge-transaction-settings-modal.test.tsx @@ -7,10 +7,7 @@ import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; import * as bridgeSelectors from '../../../ducks/bridge/selectors'; import CrossChainSwap from '..'; -import { - CROSS_CHAIN_SWAP_ROUTE, - PREPARE_SWAP_ROUTE, -} from '../../../helpers/constants/routes'; +import { PREPARE_SWAP_ROUTE } from '../../../helpers/constants/routes'; import { waitForElementById } from '../../../../test/integration/helpers'; import { setSlippage } from '../../../ducks/bridge/actions'; import { sanitizeAmountInput } from '../utils/quote'; @@ -29,7 +26,7 @@ const renderModal = (initialSlippage?: number) => { const renderResult = renderWithProvider( , store, - CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE, + PREPARE_SWAP_ROUTE, ); store.dispatch(setSlippage(initialSlippage)); return { ...renderResult, store }; diff --git a/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx b/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx index fa10f1b258e1..fbfcd98100c2 100644 --- a/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx +++ b/ui/pages/bridge/prepare/components/destination-account-picker-modal.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { createBridgeMockStore } from '../../../../../test/data/bridge/mock-bridge-store'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { getToAccounts } from '../../../../ducks/bridge/selectors'; import { DestinationAccountPickerModal } from './destination-account-picker-modal'; diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx index a4cb977b1eb5..4db262d6a6de 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Provider } from 'react-redux'; import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import configureStore from '../../../store/store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; diff --git a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx index 7f003343465d..2ecf85057d64 100644 --- a/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx +++ b/ui/pages/bridge/prepare/prepare-bridge-page.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { act } from '@testing-library/react'; -import * as reactRouterUtils from 'react-router-dom-v5-compat'; +import * as reactRouterUtils from 'react-router-dom'; import { userEvent } from '@testing-library/user-event'; import { toEvmCaipChainId } from '@metamask/multichain-network-controller'; import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx index 83635ad436fc..48f704b3fc01 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { RequestStatus } from '@metamask/bridge-controller'; import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { mockNetworkState } from '../../../../test/stub/networks'; diff --git a/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx b/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx index 6c8a1fe9913f..f582e58dc1e6 100644 --- a/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx +++ b/ui/pages/bridge/quotes/multichain-bridge-quote-card.test.tsx @@ -5,7 +5,7 @@ import { formatChainIdToCaip, } from '@metamask/bridge-controller'; import { zeroAddress } from 'ethereumjs-util'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; import { CHAIN_IDS } from '../../../../shared/constants/network'; diff --git a/ui/pages/bridge/transaction-details/transaction-details.test.tsx b/ui/pages/bridge/transaction-details/transaction-details.test.tsx index 10800ba2839c..2147f28eca76 100644 --- a/ui/pages/bridge/transaction-details/transaction-details.test.tsx +++ b/ui/pages/bridge/transaction-details/transaction-details.test.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import type { Location as RouterLocation } from 'react-router-dom-v5-compat'; +import type { Location as RouterLocation } from 'react-router-dom'; import { EthAccountType, EthScope } from '@metamask/keyring-api'; import { TransactionStatus } from '@metamask/transaction-controller'; import type { BridgeHistoryItem } from '@metamask/bridge-status-controller'; import { StatusTypes } from '@metamask/bridge-controller'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockBridgeTxData from '../../../../test/data/bridge/mock-bridge-transaction-details.json'; import { createBridgeMockStore } from '../../../../test/data/bridge/mock-bridge-store'; import { mockNetworkState } from '../../../../test/stub/networks'; diff --git a/ui/pages/bridge/transaction-details/transaction-details.tsx b/ui/pages/bridge/transaction-details/transaction-details.tsx index 806daba6ad54..c6d15844dc20 100644 --- a/ui/pages/bridge/transaction-details/transaction-details.tsx +++ b/ui/pages/bridge/transaction-details/transaction-details.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; -import type { Location as RouterLocation } from 'react-router-dom-v5-compat'; +import type { Location as RouterLocation } from 'react-router-dom'; import { TransactionStatus, TransactionType, diff --git a/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js b/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js index 925c17db5362..0c589e57c930 100644 --- a/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js +++ b/ui/pages/confirm-add-suggested-nft/confirm-add-suggested-nft.js @@ -1,7 +1,6 @@ import React, { useCallback, useContext, useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { providerErrors, serializeError } from '@metamask/rpc-errors'; import { getTokenTrackerLink } from '@metamask/etherscan-link'; import classnames from 'classnames'; @@ -64,17 +63,11 @@ import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; import { Nav } from '../confirmations/components/confirm/nav'; import { hideAppHeader } from '../routes/utils'; -const ConfirmAddSuggestedNFT = ({ - navigate: routeNavigate, - location: routeLocation, -} = {}) => { +const ConfirmAddSuggestedNFT = () => { const t = useContext(I18nContext); const dispatch = useDispatch(); - const hookNavigate = useNavigate(); - const hookLocation = useLocation(); - // Use navigate/location from props (v5 route) if available, otherwise fall back to hooks (v6) - const navigate = routeNavigate || hookNavigate; - const location = routeLocation || hookLocation; + const navigate = useNavigate(); + const location = useLocation(); const hasAppHeader = location?.pathname ? !hideAppHeader({ location }) : true; @@ -195,7 +188,7 @@ const ConfirmAddSuggestedNFT = ({ }; addImageUrlToSuggestedNFTs(); - }, [suggestedNfts]); // rerender when suggestedNfts changes + }, [suggestedNfts, ipfsGateway]); // rerender when suggestedNfts or ipfsGateway changes return ( ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, useLocation: () => mockUseLocation(), })); diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js index d42de2739eb5..a7510204108b 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.js @@ -1,7 +1,6 @@ import React, { useCallback, useContext, useEffect, useMemo } from 'react'; -import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import classnames from 'classnames'; import { providerErrors, serializeError } from '@metamask/rpc-errors'; import { @@ -84,16 +83,11 @@ function hasDuplicateSymbolAndDiffAddress(suggestedTokens, tokens) { return Boolean(duplicate); } -const ConfirmAddSuggestedToken = ({ - navigate: routeNavigate, - location: routeLocation, -} = {}) => { +const ConfirmAddSuggestedToken = () => { const t = useContext(I18nContext); const dispatch = useDispatch(); - const hookNavigate = useNavigate(); - const hookLocation = useLocation(); - const navigate = routeNavigate || hookNavigate; - const location = routeLocation || hookLocation; + const navigate = useNavigate(); + const location = useLocation(); const hasAppHeader = location?.pathname ? !hideAppHeader({ location }) : true; @@ -242,15 +236,4 @@ const ConfirmAddSuggestedToken = ({ ); }; -ConfirmAddSuggestedToken.propTypes = { - navigate: PropTypes.func, - location: PropTypes.shape({ - pathname: PropTypes.string, - search: PropTypes.string, - hash: PropTypes.string, - state: PropTypes.object, - key: PropTypes.string, - }), -}; - export default ConfirmAddSuggestedToken; diff --git a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js index 93029fee6dd1..590288d48e30 100644 --- a/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js +++ b/ui/pages/confirm-add-suggested-token/confirm-add-suggested-token.test.js @@ -16,8 +16,8 @@ import ConfirmAddSuggestedToken from '.'; const mockNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, useLocation: () => mockUseLocation(), })); diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js index 321b34c7c4e8..948de0d2ba3c 100644 --- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js +++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.js @@ -5,7 +5,7 @@ import copyToClipboard from 'copy-to-clipboard'; import classnames from 'classnames'; import log from 'loglevel'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { cloneDeep } from 'lodash'; import AccountListItem from '../../components/app/account-list-item'; diff --git a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js index ef90aab03576..c6af76e65844 100644 --- a/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js +++ b/ui/pages/confirm-decrypt-message/confirm-decrypt-message.component.test.js @@ -16,9 +16,9 @@ import ConfirmDecryptMessage from './confirm-decrypt-message.component'; const messageIdMock = '12345'; -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useParams: () => ({ id: messageIdMock, }), diff --git a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js index c85f904c80ca..2f7fdcefcc19 100644 --- a/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js +++ b/ui/pages/confirm-encryption-public-key/confirm-encryption-public-key.stories.js @@ -1,6 +1,5 @@ import React from 'react'; import { Provider } from 'react-redux'; -import { action } from '@storybook/addon-actions'; import configureStore from '../../store/store'; import testData from '../../../.storybook/test-data'; import ConfirmEncryptionPublicKey from './confirm-encryption-public-key.component'; @@ -33,9 +32,9 @@ export default { type: 'number', }, }, - history: { + navigate: { control: { - type: 'object', + type: 'function', }, }, requesterAddress: { @@ -66,9 +65,6 @@ export default { }, args: { fromAccount: Object.values(metamask.internalAccounts.accounts)[0], - history: { - push: action('history.push()'), - }, requesterAddress: confirmTransaction.txData.txParams.from, txData: confirmTransaction.txData, subjectMetadata: metamask.subjectMetadata, diff --git a/ui/pages/confirmations/components/UI/asset/asset.test.tsx b/ui/pages/confirmations/components/UI/asset/asset.test.tsx index 0dc78c5c6901..f5c1c331a98c 100644 --- a/ui/pages/confirmations/components/UI/asset/asset.test.tsx +++ b/ui/pages/confirmations/components/UI/asset/asset.test.tsx @@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react'; import { BtcAccountType } from '@metamask/keyring-api'; import createMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { useNftImageUrl } from '../../../hooks/useNftImageUrl'; import { AssetStandard } from '../../../types/send'; import { Asset } from './asset'; diff --git a/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx b/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx index 501db761222b..38d0ed94f702 100644 --- a/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx +++ b/ui/pages/confirmations/components/UI/send-hero/send-hero.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import mockDefaultState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { Asset, AssetStandard } from '../../../types/send'; import { SendHero } from './send-hero'; diff --git a/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js b/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js index 13e2637ecb96..d3638791b15e 100644 --- a/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js +++ b/ui/pages/confirmations/components/advanced-gas-controls/advanced-gas-controls.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import AdvancedGasControls from './advanced-gas-controls.component'; 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 07c7fc8faaab..5f93e476b2a3 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 @@ -5,7 +5,7 @@ import { EditGasModes, GasEstimateTypes, } from '../../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../../test/data/mock-state.json'; import * as Actions from '../../../../../store/actions'; 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 066b428d6ad5..a66c4b05f777 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 @@ -2,7 +2,7 @@ import React from 'react'; import { act, fireEvent, screen } from '@testing-library/react'; import { GasEstimateTypes } from '../../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../../test/data/mock-state.json'; import { MAX_GAS_LIMIT_DEC } from '../../../send-legacy/send.constants'; 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 6aacf0cc1a26..d24c57efc852 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,6 +1,6 @@ import React from 'react'; import { act } from '@testing-library/react'; -import { renderWithProvider, screen } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import AdvancedGasFeeInputSubtext from './advanced-gas-fee-input-subtext'; @@ -37,127 +37,127 @@ const renderComponent = async ({ props = {}, state = {} } = {}) => { describe('AdvancedGasFeeInputSubtext', () => { describe('when "latest" is non-nullish', () => { it('should render the latest fee if given a fee', async () => { - await renderComponent({ + const { getByText } = await renderComponent({ props: { latest: '123.12345', }, }); - expect(screen.getByText('123.12 GWEI')).toBeInTheDocument(); + expect(getByText('123.12 GWEI')).toBeInTheDocument(); }); it('should render the latest fee range if given a fee range', async () => { - await renderComponent({ + const { getByText } = await renderComponent({ props: { latest: ['123.456', '456.789'], }, }); - expect(screen.getByText('123.46 - 456.79 GWEI')).toBeInTheDocument(); + expect(getByText('123.46 - 456.79 GWEI')).toBeInTheDocument(); }); it('should render a fee trend arrow image if given "up" as the trend', async () => { - await renderComponent({ + const { getByTitle } = await renderComponent({ props: { latest: '123.12345', trend: 'up', }, }); - expect(screen.getByTitle('up arrow')).toBeInTheDocument(); + expect(getByTitle('up arrow')).toBeInTheDocument(); }); it('should render a fee trend arrow image if given "down" as the trend', async () => { - await renderComponent({ + const { getByTitle } = await renderComponent({ props: { latest: '123.12345', trend: 'down', }, }); - expect(screen.getByTitle('down arrow')).toBeInTheDocument(); + expect(getByTitle('down arrow')).toBeInTheDocument(); }); it('should render a fee trend arrow image if given "level" as the trend', async () => { - await renderComponent({ + const { getByTitle } = await renderComponent({ props: { latest: '123.12345', trend: 'level', }, }); - expect(screen.getByTitle('level arrow')).toBeInTheDocument(); + expect(getByTitle('level arrow')).toBeInTheDocument(); }); 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(); - await renderComponent({ + const { queryByTestId } = await renderComponent({ props: { latest: '123.12345', trend: 'whatever', }, }); - expect(screen.queryByTestId('fee-arrow')).not.toBeInTheDocument(); + expect(queryByTestId('fee-arrow')).not.toBeInTheDocument(); }); it('should not render a fee trend arrow image if given a nullish trend', async () => { - await renderComponent({ + const { queryByTestId } = await renderComponent({ props: { latest: '123.12345', trend: null, }, }); - expect(screen.queryByTestId('fee-arrow')).not.toBeInTheDocument(); + expect(queryByTestId('fee-arrow')).not.toBeInTheDocument(); }); }); describe('when "latest" is nullish', () => { it('should not render the container for the latest fee', async () => { - await renderComponent({ + const { queryByTestId } = await renderComponent({ props: { latest: null, }, }); - expect(screen.queryByTestId('latest')).not.toBeInTheDocument(); + expect(queryByTestId('latest')).not.toBeInTheDocument(); }); }); describe('when "historical" is not nullish', () => { it('should render the historical fee if given a fee', async () => { - await renderComponent({ + const { getByText } = await renderComponent({ props: { historical: '123.12345', }, }); - expect(screen.getByText('123.12 GWEI')).toBeInTheDocument(); + expect(getByText('123.12 GWEI')).toBeInTheDocument(); }); it('should render the historical fee range if given a fee range', async () => { - await renderComponent({ + const { getByText } = await renderComponent({ props: { historical: ['123.456', '456.789'], }, }); - expect(screen.getByText('123.46 - 456.79 GWEI')).toBeInTheDocument(); + expect(getByText('123.46 - 456.79 GWEI')).toBeInTheDocument(); }); }); describe('when "historical" is nullish', () => { it('should not render the container for the historical fee', async () => { - await renderComponent({ + const { queryByTestId } = await renderComponent({ props: { historical: null, }, }); - expect(screen.queryByTestId('historical')).not.toBeInTheDocument(); + expect(queryByTestId('historical')).not.toBeInTheDocument(); }); }); }); 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 18c244d31885..f302ea5c4e4e 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 @@ -5,7 +5,7 @@ import { EditGasModes, GasEstimateTypes, } from '../../../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../../../test/data/mock-state.json'; import { GasFeeContextProvider } from '../../../../../../contexts/gasFee'; 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 94dd3edf5609..02f2b38fab01 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 @@ -5,7 +5,7 @@ import { EditGasModes, GasEstimateTypes, } from '../../../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../../../test/data/mock-state.json'; import { GasFeeContextProvider } from '../../../../../../contexts/gasFee'; 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 ca20b4a8eece..5257661ff455 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 @@ -2,7 +2,7 @@ import React from 'react'; import { act, fireEvent, screen } from '@testing-library/react'; import { GasEstimateTypes } from '../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../test/data/mock-state.json'; import { MAX_GAS_LIMIT_DEC } from '../../send-legacy/send.constants'; diff --git a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx index 28325efbcf6a..628af4051ea8 100644 --- a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx +++ b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx @@ -97,9 +97,9 @@ jest.mock('../../../hooks/useConfirmSendNavigation', () => ({ const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/pages/confirmations/components/confirm/footer/footer.tsx b/ui/pages/confirmations/components/confirm/footer/footer.tsx index 928e2ed471f3..ff190af1c70d 100644 --- a/ui/pages/confirmations/components/confirm/footer/footer.tsx +++ b/ui/pages/confirmations/components/confirm/footer/footer.tsx @@ -5,7 +5,7 @@ import { import React, { useCallback, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { PRODUCT_TYPES } from '@metamask/subscription-controller'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics'; import { isCorrectDeveloperTransactionType } from '../../../../../../shared/lib/confirmation.utils'; import { ConfirmAlertModal } from '../../../../../components/app/alert-system/confirm-alert-modal'; diff --git a/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx b/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx index af5f0f1df703..deba263e5ab1 100644 --- a/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx +++ b/ui/pages/confirmations/components/confirm/footer/origin-throttle-modal.test.tsx @@ -4,7 +4,7 @@ import { screen, fireEvent } from '@testing-library/react'; import '@testing-library/jest-dom'; import { I18nContext } from '../../../../../contexts/i18n'; import { useOriginThrottling } from '../../../hooks/useOriginThrottling'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../../test/data/mock-state.json'; import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics'; import OriginThrottleModal from './origin-throttle-modal'; diff --git a/ui/pages/confirmations/components/confirm/header/header.test.tsx b/ui/pages/confirmations/components/confirm/header/header.test.tsx index 1af8c6e2772b..9eea986f3959 100644 --- a/ui/pages/confirmations/components/confirm/header/header.test.tsx +++ b/ui/pages/confirmations/components/confirm/header/header.test.tsx @@ -11,8 +11,8 @@ import { renderWithConfirmContextProvider } from '../../../../../../test/lib/con import configureStore from '../../../../../store/store'; import Header from './header'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => jest.fn(), })); diff --git a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx index 7b39d48759cc..ee44a815d774 100644 --- a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx +++ b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.test.tsx @@ -20,8 +20,8 @@ jest.mock('../../../hooks/useRedesignedSendFlow', () => ({ useRedesignedSendFlow: jest.fn().mockReturnValue({ enabled: false }), })); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => jest.fn(), })); diff --git a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx index 0f8142ba542c..a6d17557c578 100644 --- a/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx +++ b/ui/pages/confirmations/components/confirm/header/wallet-initiated-header.tsx @@ -4,7 +4,7 @@ import { } from '@metamask/transaction-controller'; import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { MetaMetricsEventLocation } from '../../../../../../shared/constants/metametrics'; import { AssetType } from '../../../../../../shared/constants/transaction'; import { diff --git a/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts b/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts index 2749da270bed..f13b74ed724d 100644 --- a/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts +++ b/ui/pages/confirmations/components/confirm/info/approve/hooks/use-is-nft.test.ts @@ -5,7 +5,7 @@ import { genUnapprovedContractInteractionConfirmation, } from '../../../../../../../../test/data/confirmations/contract-interaction'; import mockState from '../../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../../test/lib/render-helpers-navigate'; import { getTokenStandardAndDetailsByChain } from '../../../../../../../store/actions'; import { useIsNFT } from './use-is-nft'; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts index 4c7a53f8b041..4cc8243b18eb 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useEIP1559TxFees.test.ts @@ -4,7 +4,7 @@ import { genUnapprovedContractInteractionConfirmation, } from '../../../../../../../test/data/confirmations/contract-interaction'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { useEIP1559TxFees } from './useEIP1559TxFees'; describe('useEIP1559TxFees', () => { diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts index dd986ed1b4dd..d4f98b87e95f 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts @@ -1,5 +1,5 @@ import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { useFourByte } from './useFourByte'; const DATA_MOCK = '0xd0e30db0'; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts index 95c8f8a5a63d..cf621dc240df 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.test.ts @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react-hooks'; import { TransactionType } from '@metamask/transaction-controller'; -import { useSearchParams } from 'react-router-dom-v5-compat'; +import { useSearchParams } from 'react-router-dom'; import { merge } from 'lodash'; import { updateEditableParams } from '../../../../../../store/actions'; @@ -13,8 +13,8 @@ import { import { useMaxValueRefresher } from './useMaxValueRefresher'; import { useSupportsEIP1559 } from './useSupportsEIP1559'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]), })); diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts index c5d966cb8fe8..54a6265e9e7b 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useMaxValueRefresher.ts @@ -5,7 +5,7 @@ import { type TransactionMeta, } from '@metamask/transaction-controller'; import { Hex } from '@metamask/utils'; -import { useSearchParams } from 'react-router-dom-v5-compat'; +import { useSearchParams } from 'react-router-dom'; import { getCrossChainMetaMaskCachedBalances, diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts index 018bb34703fa..5ba35f0340d1 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useNestedTransactionLabels.test.ts @@ -1,5 +1,5 @@ import { BatchTransactionParams } from '@metamask/transaction-controller'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../../../test/data/mock-state.json'; import { useNestedTransactionLabels } from './useNestedTransactionLabels'; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts index 378526b96262..26657e56d94b 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useSupportsEIP1559.test.ts @@ -7,7 +7,7 @@ import { genUnapprovedContractInteractionConfirmation, } from '../../../../../../../test/data/confirmations/contract-interaction'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { useSupportsEIP1559 } from './useSupportsEIP1559'; describe('useSupportsEIP1559', () => { diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts index c16049de9fbf..2d58032a822a 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useTokenDetails.test.ts @@ -2,7 +2,7 @@ import { TransactionMeta } from '@metamask/transaction-controller'; import { useSelector } from 'react-redux'; import { genUnapprovedTokenTransferConfirmation } from '../../../../../../../test/data/confirmations/token-transfer'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { selectERC20TokensByChain } from '../../../../../../selectors'; import { useTokenDetails } from './useTokenDetails'; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts index 5531aeccff52..089fef260ccb 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/useTransactionGasFeeEstimate.test.ts @@ -4,7 +4,7 @@ import { genUnapprovedContractInteractionConfirmation, } from '../../../../../../../test/data/confirmations/contract-interaction'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { useGasFeeEstimates } from '../../../../../../hooks/useGasFeeEstimates'; import { useTransactionGasFeeEstimate } from './useTransactionGasFeeEstimate'; diff --git a/ui/pages/confirmations/components/confirm/info/info.test.tsx b/ui/pages/confirmations/components/confirm/info/info.test.tsx index a5dda92e7016..748b26157c64 100644 --- a/ui/pages/confirmations/components/confirm/info/info.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/info.test.tsx @@ -1,7 +1,7 @@ import { screen, waitFor } from '@testing-library/react'; import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { useParams } from 'react-router-dom-v5-compat'; +import { useParams } from 'react-router-dom'; import { getMockAddEthereumChainConfirmState, getMockApproveConfirmState, @@ -58,8 +58,8 @@ jest.mock('../../../../../../shared/modules/environment', () => ({ isGatorPermissionsFeatureEnabled: jest.fn().mockReturnValue(true), })); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useParams: jest.fn(), })); diff --git a/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx b/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx index 3af59bbf7cdd..3168e55b1997 100644 --- a/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/native-transfer/native-transfer.test.tsx @@ -9,8 +9,8 @@ jest.mock('../../../simulation-details/useBalanceChanges', () => ({ useBalanceChanges: jest.fn(() => ({ pending: false, value: [] })), })); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/' }), useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]), })); diff --git a/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx b/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx index aefbc806de9f..4f4d031d7c6c 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/edit-gas-icon/edit-gas-icon-button.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import mockState from '../../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers-navigate'; import { EditGasIconButton } from './edit-gas-icon-button'; describe('', () => { diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx index 966e15f496ce..a00c7080bebf 100644 --- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/account-details.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper'; import { tEn } from '../../../../../../../test/lib/i18n-helpers'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { AccountDetails } from './account-details'; jest.mock('../../../../../../components/app/confirm/info/row/address', () => ({ diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx index 7d449a3aac5f..ea6e1ac12acf 100644 --- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/estimated-changes.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper'; import { tEn } from '../../../../../../../test/lib/i18n-helpers'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { EstimatedChanges } from './estimated-changes'; jest.mock('../../../../../../components/app/name/name', () => ({ diff --git a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx index 9a915cb55ba1..201def2853c8 100644 --- a/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/shield-subscription-approve/subscription-details.test.tsx @@ -6,7 +6,7 @@ import { } from '@metamask/subscription-controller'; import { getMockConfirmState } from '../../../../../../../test/data/confirmations/helper'; import { tEn } from '../../../../../../../test/lib/i18n-helpers'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { SubscriptionDetails } from './subscription-details'; const mockProductPrice: ProductPrice = { diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx index 74a5bb1894b0..b693f752a67f 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/native-value-display/native-value-display.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers-navigate'; import NativeValueDisplay from './native-value-display'; describe('NativeValueDisplay', () => { diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx index aaa5225dc37e..b9beadb31fbc 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign-v4-simulation/value-display/value-display.test.tsx @@ -3,7 +3,7 @@ import { act } from 'react-dom/test-utils'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../../../../../contexts/metametrics'; import PermitSimulationValueDisplay from './value-display'; diff --git a/ui/pages/confirmations/components/confirm/nav/nav.test.tsx b/ui/pages/confirmations/components/confirm/nav/nav.test.tsx index 8d72d9502b3a..8b530e2fafe7 100644 --- a/ui/pages/confirmations/components/confirm/nav/nav.test.tsx +++ b/ui/pages/confirmations/components/confirm/nav/nav.test.tsx @@ -17,9 +17,9 @@ jest.mock('react-redux', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx b/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx index 35dafe552cb7..90e69f4d2b71 100644 --- a/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx +++ b/ui/pages/confirmations/components/confirm/row/dataTree.test.tsx @@ -5,7 +5,7 @@ import { permitSignatureMsg, } from '../../../../../../test/data/confirmations/typed_sign'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { DataTree } from './dataTree'; diff --git a/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx b/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx index e01a42782033..95ee7e04f0f8 100644 --- a/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx +++ b/ui/pages/confirmations/components/confirm/row/typed-sign-data-v1/typedSignDataV1.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { unapprovedTypedSignMsgV1 } from '../../../../../../../test/data/confirmations/typed_sign'; import { TypedSignDataV1Type } from '../../../../types/confirm'; import { ConfirmInfoRowTypedSignDataV1 } from './typedSignDataV1'; diff --git a/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx b/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx index 0d7b6d7e0979..0fa84334b063 100644 --- a/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx +++ b/ui/pages/confirmations/components/confirm/row/typed-sign-data/typedSignData.test.tsx @@ -4,7 +4,7 @@ import { unapprovedTypedSignMsgV4, } from '../../../../../../../test/data/confirmations/typed_sign'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../../store/store'; import { ConfirmInfoRowTypedSignData } from './typedSignData'; diff --git a/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx index 35f167231a5c..28380d2ac67e 100644 --- a/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx +++ b/ui/pages/confirmations/components/confirm/smart-account-tab/account-network/account-network.test.tsx @@ -3,7 +3,7 @@ import { Hex } from '@metamask/utils'; import { fireEvent } from '@testing-library/dom'; import mockState from '../../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../../store/store'; import { EIP7702NetworkConfiguration } from '../../../../hooks/useBatchAuthorizationRequests'; import { AccountNetwork } from './account-network'; diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx index 349e85c312b0..d6b93f3dd9f0 100644 --- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx +++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.test.tsx @@ -7,9 +7,9 @@ import { renderWithConfirmContextProvider } from '../../../../../../test/lib/con import { SmartAccountUpdateSuccess } from './smart-account-update-success'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx index 06c6a62121ed..456e1ecfc55a 100644 --- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx +++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update-success.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import ZENDESK_URLS from '../../../../../helpers/constants/zendesk-url'; import { diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx index 1d9a478c4e3f..adac87a9b468 100644 --- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx +++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.test.tsx @@ -10,9 +10,9 @@ import { setSmartAccountOptIn } from '../../../../../store/actions'; import { SmartAccountUpdate } from './smart-account-update'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx index 884c237c65ab..036780652b78 100644 --- a/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx +++ b/ui/pages/confirmations/components/confirm/smart-account-update/smart-account-update.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, diff --git a/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js b/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js index c59a1e134dc4..9d177ab5da04 100644 --- a/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js +++ b/ui/pages/confirmations/components/edit-gas-display/edit-gas-display.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import EditGasDisplay from '.'; 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 55b27e3d4234..42bdf9e93a2e 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 @@ -9,7 +9,7 @@ import { } from '../../../../../shared/constants/gas'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../test/data/mock-state.json'; import configureStore from '../../../../store/store'; 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 1781314edbc6..4b990e2c5d01 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,6 +1,6 @@ import React from 'react'; import { act, fireEvent, screen } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; import configureStore from '../../../../store/store'; import mockState from '../../../../../test/data/mock-state.json'; 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 4d74e34be902..3f05286bd675 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 @@ -7,7 +7,7 @@ import { TransactionType, } from '@metamask/transaction-controller'; import { EditGasModes } from '../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; 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 95bd45506003..aa8ba6ce34d3 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 @@ -5,7 +5,7 @@ import { EditGasModes, PriorityLevels, } from '../../../../../../shared/constants/gas'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { GasFeeContextProvider } from '../../../../../contexts/gasFee'; 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 558190bb7dd3..71a40db9e57d 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,7 +1,7 @@ import React from 'react'; import { act } from '@testing-library/react'; import configureStore from '../../../../../store/store'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { GasFeeContextProvider } from '../../../../../contexts/gasFee'; import { mockNetworkState } from '../../../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../../../shared/constants/network'; diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js index 125495d09c83..2605f1ae9d0c 100644 --- a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js +++ b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/network-statistics.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { renderWithProvider, screen } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import { GasFeeContext } from '../../../../../contexts/gasFee'; import NetworkStatistics from './network-statistics'; @@ -16,53 +16,49 @@ const renderComponent = ({ gasFeeContext = {}, state = {} } = {}) => { describe('NetworkStatistics', () => { it('should render the latest base fee rounded to no decimal places', () => { - renderComponent({ + const { getByText } = renderComponent({ gasFeeContext: { gasFeeEstimates: { estimatedBaseFee: '50.0112', }, }, }); - expect(screen.getByText('50 GWEI')).toBeInTheDocument(); + expect(getByText('50 GWEI')).toBeInTheDocument(); }); it('should not render the latest base fee if it is not present', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: { estimatedBaseFee: null, }, }, }); - expect( - screen.queryByTestId('formatted-latest-base-fee'), - ).not.toBeInTheDocument(); + expect(queryByTestId('formatted-latest-base-fee')).not.toBeInTheDocument(); }); it('should not render the latest base fee if no gas fee estimates are available', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: null, }, }); - expect( - screen.queryByTestId('formatted-latest-base-fee'), - ).not.toBeInTheDocument(); + expect(queryByTestId('formatted-latest-base-fee')).not.toBeInTheDocument(); }); it('should render the latest priority fee range, with the low end of the range rounded to 1 decimal place and the high end rounded to no decimal places', () => { - renderComponent({ + const { getByText } = renderComponent({ gasFeeContext: { gasFeeEstimates: { latestPriorityFeeRange: ['1.100001668', '2.5634234'], }, }, }); - expect(screen.getByText('1.1 - 3 GWEI')).toBeInTheDocument(); + expect(getByText('1.1 - 3 GWEI')).toBeInTheDocument(); }); it('should not render the latest priority fee range if it is not present', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: { latestPriorityFeeRange: null, @@ -70,49 +66,49 @@ describe('NetworkStatistics', () => { }, }); expect( - screen.queryByTestId('formatted-latest-priority-fee-range'), + queryByTestId('formatted-latest-priority-fee-range'), ).not.toBeInTheDocument(); }); it('should not render the latest priority fee range if no gas fee estimates are available', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: null, }, }); expect( - screen.queryByTestId('formatted-latest-priority-fee-range'), + queryByTestId('formatted-latest-priority-fee-range'), ).not.toBeInTheDocument(); }); it('should render the network status slider', () => { - renderComponent({ + const { getByText } = renderComponent({ gasFeeContext: { gasFeeEstimates: { networkCongestion: 0.5, }, }, }); - expect(screen.getByText('Stable')).toBeInTheDocument(); + expect(getByText('Stable')).toBeInTheDocument(); }); it('should not render the network status slider if the network congestion is not available', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: { networkCongestion: null, }, }, }); - expect(screen.queryByTestId('status-slider-label')).not.toBeInTheDocument(); + expect(queryByTestId('status-slider-label')).not.toBeInTheDocument(); }); it('should not render the network status slider if no gas fee estimates are available', () => { - renderComponent({ + const { queryByTestId } = renderComponent({ gasFeeContext: { gasFeeEstimates: null, }, }); - expect(screen.queryByTestId('status-slider-label')).not.toBeInTheDocument(); + expect(queryByTestId('status-slider-label')).not.toBeInTheDocument(); }); }); diff --git a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js index 4811469a667b..04fdf348bdd7 100644 --- a/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js +++ b/ui/pages/confirmations/components/edit-gas-fee-popover/network-statistics/status-slider/status-slider.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../../test/lib/render-helpers-navigate'; import { GasFeeContext } from '../../../../../../contexts/gasFee'; import configureStore from '../../../../../../store/store'; 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 99f7812a4978..3e0d544b163b 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 @@ -2,7 +2,7 @@ import React from 'react'; import { act, screen } from '@testing-library/react'; import configureStore from 'redux-mock-store'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { mockNetworkState } from '../../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; import FeeDetailsComponent from './fee-details-component'; 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 3e45b4c87722..b895e7c2adf7 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 @@ -5,7 +5,7 @@ import { GasEstimateTypes } from '../../../../../shared/constants/gas'; import mockEstimates from '../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../test/data/mock-state.json'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { getSelectedInternalAccountFromMockState } from '../../../../../test/jest/mocks'; diff --git a/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js b/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js index 5252fd8df6da..6469ea8347f0 100644 --- a/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js +++ b/ui/pages/confirmations/components/gas-timing/gas-timing.component.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { waitFor } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { GasEstimateTypes } from '../../../../../shared/constants/gas'; import mockState from '../../../../../test/data/mock-state.json'; diff --git a/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js b/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js index 42f28d3f980b..23176b4c2508 100644 --- a/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js +++ b/ui/pages/confirmations/components/multilayer-fee-message/multi-layer-fee-message.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { toHex } from '@metamask/controller-utils'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import MultilayerFeeMessage from './multi-layer-fee-message'; diff --git a/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx b/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx index b85ff48214fa..3cbdf63bd935 100644 --- a/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx +++ b/ui/pages/confirmations/components/send/amount-recipient/amount-recipient.test.tsx @@ -19,8 +19,8 @@ import { AmountRecipient } from './amount-recipient'; const MOCK_ADDRESS = '0xdB055877e6c13b6A6B25aBcAA29B393777dD0a73'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]), })); diff --git a/ui/pages/confirmations/components/send/amount/amount.test.tsx b/ui/pages/confirmations/components/send/amount/amount.test.tsx index 8acf541b6c54..2db1c5eff672 100644 --- a/ui/pages/confirmations/components/send/amount/amount.test.tsx +++ b/ui/pages/confirmations/components/send/amount/amount.test.tsx @@ -9,7 +9,7 @@ import { SOLANA_ASSET, } from '../../../../../../test/data/send/assets'; import { Numeric } from '../../../../../../shared/modules/Numeric'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import * as AmountSelectionMetrics from '../../../hooks/send/metrics/useAmountSelectionMetrics'; import * as BalanceFunctions from '../../../hooks/send/useBalance'; diff --git a/ui/pages/confirmations/components/send/header/header.test.tsx b/ui/pages/confirmations/components/send/header/header.test.tsx index 865e5abe3d59..915c8cc14ad7 100644 --- a/ui/pages/confirmations/components/send/header/header.test.tsx +++ b/ui/pages/confirmations/components/send/header/header.test.tsx @@ -7,8 +7,8 @@ import configureStore from '../../../../../store/store'; import { Header } from './header'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: jest diff --git a/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx b/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx index 09dedbe4a68c..a0d4f75ef148 100644 --- a/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx +++ b/ui/pages/confirmations/components/send/hex-data/hex-data.test.tsx @@ -7,7 +7,7 @@ import { EVM_NATIVE_ASSET, MOCK_NFT1155, } from '../../../../../../test/data/send/assets'; -import { renderWithProvider } from '../../../../../../test/jest'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../../store/store'; import * as SendContext from '../../../context/send'; import { HexData } from './hex-data'; diff --git a/ui/pages/confirmations/components/send/loader/loader.test.tsx b/ui/pages/confirmations/components/send/loader/loader.test.tsx index c825fc6e4181..2ca9cf3626da 100644 --- a/ui/pages/confirmations/components/send/loader/loader.test.tsx +++ b/ui/pages/confirmations/components/send/loader/loader.test.tsx @@ -10,9 +10,9 @@ import { CONFIRMATION_V_NEXT_ROUTE } from '../../../../../helpers/constants/rout import { Loader } from './loader'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/components/send/loader/loader.tsx b/ui/pages/confirmations/components/send/loader/loader.tsx index 260858f7ea67..94aab8b149b2 100644 --- a/ui/pages/confirmations/components/send/loader/loader.tsx +++ b/ui/pages/confirmations/components/send/loader/loader.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { diff --git a/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx b/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx index 58b5cb25e125..c3f01b2020f3 100644 --- a/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx +++ b/ui/pages/confirmations/components/send/recipient-input/recipient-input.test.tsx @@ -3,7 +3,7 @@ import { fireEvent } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useRecipientSelectionMetrics } from '../../../hooks/send/metrics/useRecipientSelectionMetrics'; import { useSendContext } from '../../../context/send'; diff --git a/ui/pages/confirmations/components/send/recipient/recipient.test.tsx b/ui/pages/confirmations/components/send/recipient/recipient.test.tsx index 12af8303871a..84b886d070c0 100644 --- a/ui/pages/confirmations/components/send/recipient/recipient.test.tsx +++ b/ui/pages/confirmations/components/send/recipient/recipient.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { fireEvent } from '@testing-library/react'; import configureStore from '../../../../../store/store'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useRecipientSelectionMetrics } from '../../../hooks/send/metrics/useRecipientSelectionMetrics'; import { useSendContext } from '../../../context/send'; diff --git a/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx b/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx index f6593346ca3f..954e7aad37e3 100644 --- a/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx +++ b/ui/pages/confirmations/components/simulation-details/asset-pill.test.tsx @@ -4,7 +4,7 @@ import { NameType } from '@metamask/name-controller'; import { Hex } from '@metamask/utils'; import { TokenStandard } from '../../../../../shared/constants/transaction'; import Name from '../../../../components/app/name'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; import { AvatarNetwork } from '../../../../components/component-library/avatar-network'; diff --git a/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx b/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx index 6dd575f202d5..c3f2cd0697c3 100644 --- a/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx +++ b/ui/pages/confirmations/components/simulation-details/fiat-display.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { screen } from '@testing-library/react'; import configureStore from 'redux-mock-store'; import { merge } from 'lodash'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { mockNetworkState } from '../../../../../test/stub/networks'; import { CHAIN_IDS } from '../../../../../shared/constants/network'; diff --git a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx index febc51d93fb3..7e8259ccbf56 100644 --- a/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx +++ b/ui/pages/confirmations/components/simulation-details/simulation-details.test.tsx @@ -12,7 +12,7 @@ import configureStore from 'redux-mock-store'; import { cloneDeep } from 'lodash'; import { TokenStandard } from '../../../../../shared/constants/transaction'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { AlertMetricsProvider } from '../../../../components/app/alert-system/contexts/alertMetricsContext'; import { BalanceChangeList } from './balance-change-list'; import { SimulationDetails, StaticRow } from './simulation-details'; diff --git a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js index a99935e4fb42..2c803d6a33c5 100644 --- a/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js +++ b/ui/pages/confirmations/components/simulation-error-message/simulation-error-message.test.js @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import SimulationErrorMessage from './simulation-error-message'; describe('Simulation Error Message', () => { diff --git a/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx b/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx index 773a4d5d2928..6b30a51dd5c7 100644 --- a/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx +++ b/ui/pages/confirmations/components/smart-transactions-banner-alert/smart-transactions-banner-alert.test.tsx @@ -4,7 +4,7 @@ import { screen } from '@testing-library/react'; import { TransactionType } from '@metamask/transaction-controller'; import { ConfirmContext, ConfirmContextType } from '../../context/confirm'; import type { Confirmation, SignatureRequestType } from '../../types/confirm'; -import { renderWithProvider } from '../../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../../store/store'; import { AlertTypes } from '../../../../../shared/constants/alerts'; import { setAlertEnabledness } from '../../../../store/actions'; diff --git a/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx b/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx index 6fcf1b499944..00cd2f8e728f 100644 --- a/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx +++ b/ui/pages/confirmations/components/snap-account-error-message/SnapAccountErrorMessage.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureStore from '../../../../store/store'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import SnapAccountErrorMessage from './SnapAccountErrorMessage'; const store = configureStore({ diff --git a/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx b/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx index 10a690bd2f27..33c07ebf93e5 100644 --- a/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx +++ b/ui/pages/confirmations/components/snap-account-success-message/SnapAccountSuccessMessage.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureStore from '../../../../store/store'; // Use mock-send-state to have some identites being populated import mockState from '../../../../../test/data/mock-send-state.json'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import SnapAccountSuccessMessage from './SnapAccountSuccessMessage'; const store = configureStore(mockState); 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 26a03506737c..e91848a7a594 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 @@ -5,7 +5,7 @@ import { TransactionEnvelopeType } from '@metamask/transaction-controller'; import { GasEstimateTypes } from '../../../../../shared/constants/gas'; import { GasFeeContextProvider } from '../../../../contexts/gasFee'; -import { renderWithProvider } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockEstimates from '../../../../../test/data/mock-estimates.json'; import mockState from '../../../../../test/data/mock-state.json'; import configureStore from '../../../../store/store'; diff --git a/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js index 920930ffb739..1535a6080734 100644 --- a/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js +++ b/ui/pages/confirmations/confirm-transaction-switch/confirm-transaction-switch.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate } from 'react-router-dom'; import Loading from '../../../components/ui/loading-screen'; import { CONFIRM_TRANSACTION_ROUTE, diff --git a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js index 681385d5d335..df7943ef3e8a 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-token-transaction-switch.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Routes, Route } from 'react-router-dom-v5-compat'; +import { Routes, Route } from 'react-router-dom'; import ConfirmTransactionSwitch from '../confirm-transaction-switch'; export default function ConfirmTokenTransactionSwitch() { diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js index 25b3220d7730..23738b9ae68e 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.component.js @@ -1,13 +1,6 @@ import React, { useCallback, useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { - Routes, - Route, - useNavigate, - useParams, - useLocation, -} from 'react-router-dom-v5-compat'; +import { Routes, Route, useNavigate, useParams } from 'react-router-dom'; import { ENVIRONMENT_TYPE_NOTIFICATION, ORIGIN_METAMASK, @@ -22,11 +15,11 @@ import { getMostRecentOverviewPage } from '../../../ducks/history/history'; import { getSendTo } from '../../../ducks/send'; import { getSelectedNetworkClientId } from '../../../../shared/modules/selectors/networks'; import { - CONFIRM_TRANSACTION_ROUTE, DECRYPT_MESSAGE_REQUEST_PATH, DEFAULT_ROUTE, ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, } from '../../../helpers/constants/routes'; +import { toRelativeRoutePath } from '../../routes/utils'; import { isTokenMethodAction } from '../../../helpers/utils/transactions.util'; import usePolling from '../../../hooks/usePolling'; import { usePrevious } from '../../../hooks/usePrevious'; @@ -54,20 +47,12 @@ import { useAsyncResult } from '../../../hooks/useAsync'; import { TraceName } from '../../../../shared/lib/trace'; import ConfirmTokenTransactionSwitch from './confirm-token-transaction-switch'; -const ConfirmTransaction = ({ - params: routeParams, - location: routeLocation, -} = {}) => { +const ConfirmTransaction = () => { const dispatch = useDispatch(); const navigate = useNavigate(); const urlParams = useParams(); - const hookLocation = useLocation(); - - // Use params from props (v5 route) if available, otherwise fall back to useParams (v6) - const { id: paramsTransactionId } = routeParams || urlParams; - // Use location from props (v5 route) if available, otherwise fall back to useLocation (v6) - const location = routeLocation || hookLocation; + const { id: paramsTransactionId } = urlParams; const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage); const sendTo = useSelector(getSendTo); @@ -216,13 +201,13 @@ const ConfirmTransaction = ({ // support URLs of /confirm-transaction or /confirm-transaction/ if (isValidTransactionId) { return ( - + } /> } /> } /> @@ -233,17 +218,4 @@ const ConfirmTransaction = ({ return ; }; -ConfirmTransaction.propTypes = { - params: PropTypes.shape({ - id: PropTypes.string, - }), - location: PropTypes.shape({ - pathname: PropTypes.string, - search: PropTypes.string, - hash: PropTypes.string, - state: PropTypes.object, - key: PropTypes.string, - }), -}; - export default ConfirmTransaction; diff --git a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js index 4834cb4c895a..b8be113b9490 100644 --- a/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js +++ b/ui/pages/confirmations/confirm-transaction/confirm-transaction.test.js @@ -1,11 +1,19 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; +import { Provider } from 'react-redux'; +import { render } from '@testing-library/react'; +import { MemoryRouter, Routes, Route } from 'react-router-dom'; import * as ConfirmTransactionDucks from '../../../ducks/confirm-transaction/confirm-transaction.duck'; import * as Actions from '../../../store/actions'; import _mockState from '../../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { + renderWithProvider, + I18nProvider, +} from '../../../../test/lib/render-helpers-navigate'; +import { LegacyI18nProvider } from '../../../contexts/i18n'; import { setBackgroundConnection } from '../../../store/background-connection'; +import * as en from '../../../../app/_locales/en/messages.json'; import { CONFIRM_TRANSACTION_ROUTE, @@ -47,14 +55,17 @@ jest.mock( setTransactionToConfirm: jest.fn().mockImplementation((txId) => { return { type: 'mock-set-transaction-to-confirm', value: txId }; }), + clearConfirmTransaction: jest.fn().mockImplementation(() => { + return { type: 'mock-clear-confirm-transaction' }; + }), }), ); const mockUseNavigate = jest.fn(); const mockUseSearchParams = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useSearchParams: () => mockUseSearchParams(), }; @@ -129,11 +140,37 @@ describe('Confirmation Transaction Page', () => { [ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, '.mock-confirm-encryption-public-key'], ].forEach(([componentPath, mockClassNameMatch]) => { it(`should render "${componentPath}" route`, () => { - const mockStore = configureMockStore(middleware)(mockState); - const { container } = renderWithProvider( - , - mockStore, - `${CONFIRM_TRANSACTION_ROUTE}/${mockUnapprovedTx.id}${componentPath}`, + // Use string ID to match what useParams() returns + const txId = String(mockUnapprovedTx.id); + // Update the state to use string ID for consistency + const stateWithStringId = { + ...mockState, + metamask: { + ...mockState.metamask, + transactions: mockState.metamask.transactions.map((tx) => ({ + ...tx, + id: String(tx.id), + })), + }, + }; + const mockStore = configureMockStore(middleware)(stateWithStringId); + const fullPath = `${CONFIRM_TRANSACTION_ROUTE}/${txId}${componentPath}`; + // Wrap in Routes with parent route to properly handle nested routing + const { container } = render( + + + + + + } + /> + + + + + , ); expect(container.querySelector(mockClassNameMatch)).toBeInTheDocument(); diff --git a/ui/pages/confirmations/confirm/confirm.test.tsx b/ui/pages/confirmations/confirm/confirm.test.tsx index 1de0e9f11560..902fd40d5404 100644 --- a/ui/pages/confirmations/confirm/confirm.test.tsx +++ b/ui/pages/confirmations/confirm/confirm.test.tsx @@ -35,8 +35,8 @@ jest.mock('../hooks/gas/useIsGaslessLoading', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { - const actual = jest.requireActual('react-router-dom-v5-compat'); +jest.mock('react-router-dom', () => { + const actual = jest.requireActual('react-router-dom'); return { ...actual, useNavigate: () => mockUseNavigate, diff --git a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts index d56e7f7da0a9..9043c25a8187 100644 --- a/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts +++ b/ui/pages/confirmations/confirmation/alerts/useTemplateConfirmationAlerts.test.ts @@ -2,7 +2,7 @@ import { ApprovalRequest } from '@metamask/approval-controller'; import { useDispatch } from 'react-redux'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts'; import * as UpdateEthereumChainAlerts from './useUpdateEthereumChainAlerts'; diff --git a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts index 37fb5afba54d..2327fbcbf2dc 100644 --- a/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts +++ b/ui/pages/confirmations/confirmation/alerts/useUpdateEthereumChainAlerts.test.ts @@ -3,7 +3,7 @@ import { ApprovalType } from '@metamask/controller-utils'; import mockState from '../../../../../test/data/mock-state.json'; import { getMockPersonalSignConfirmState } from '../../../../../test/data/confirmations/helper'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as AlertActions from '../../../../ducks/confirm-alerts/confirm-alerts'; import { useUpdateEthereumChainAlerts } from './useUpdateEthereumChainAlerts'; diff --git a/ui/pages/confirmations/confirmation/confirmation.js b/ui/pages/confirmations/confirmation/confirmation.js index 3c6b72af4943..ae4186cbf91b 100644 --- a/ui/pages/confirmations/confirmation/confirmation.js +++ b/ui/pages/confirmations/confirmation/confirmation.js @@ -9,7 +9,7 @@ import React, { } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { isEqual } from 'lodash'; import { produce } from 'immer'; import log from 'loglevel'; @@ -225,7 +225,6 @@ function Header({ confirmation, isSnapCustomUIDialog, onCancel }) { export default function ConfirmationPage({ redirectToHomeOnZeroConfirmations = true, - params: routeParams, }) { const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); @@ -245,8 +244,7 @@ export default function ConfirmationPage({ ); const [approvalFlowLoadingText, setApprovalFlowLoadingText] = useState(null); - const urlParams = useParams(); - const { id } = routeParams || urlParams; + const { id } = useParams(); const pendingRoutedConfirmation = pendingConfirmations.find( (confirmation) => confirmation.id === id, @@ -617,7 +615,4 @@ export default function ConfirmationPage({ ConfirmationPage.propTypes = { redirectToHomeOnZeroConfirmations: PropTypes.bool, - params: PropTypes.shape({ - id: PropTypes.string, - }), }; diff --git a/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js b/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js index b7d7d1572049..17941099d620 100644 --- a/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js +++ b/ui/pages/confirmations/confirmation/templates/add-ethereum-chain.js @@ -228,7 +228,7 @@ function getState(pendingApproval) { return {}; } -function getValues(pendingApproval, t, actions, history, data) { +function getValues(pendingApproval, t, actions, navigate, data) { const originIsMetaMask = pendingApproval.origin === 'metamask'; const customRpcUrl = pendingApproval.requestData.rpcUrl; @@ -409,7 +409,7 @@ function getValues(pendingApproval, t, actions, history, data) { locationPath === ONBOARDING_PRIVACY_SETTINGS_ROUTE; if (!isOnboardingRoute) { - history.push(DEFAULT_ROUTE); + navigate(DEFAULT_ROUTE); } } return []; diff --git a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js index 0b2b4aefbf40..addf06eb5ecf 100644 --- a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js +++ b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.js @@ -10,13 +10,13 @@ import { * @param {object} pendingApproval - The pending confirmation object. * @param {Function} t - Translation function. * @param {object} actions - Object containing safe actions that the template can invoke. - * @param {object} _history - The application's history object (not used in this function). + * @param {object} _navigate - The application's navigate function (not used in this function). * @param {object} _data - The data object passed into the template from the confirmation page (not * used in this function). * @param {object} contexts - Context objects passed into the template from the confirmation page. * @returns {object} An object containing templated values for the confirmation page. */ -function getValues(pendingApproval, t, actions, _history, _data, contexts) { +function getValues(pendingApproval, t, actions, _navigate, _data, contexts) { const { origin: snapId, snapName, requestData } = pendingApproval; const { snapSuggestedAccountName } = requestData; const { trackEvent } = contexts; diff --git a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js index e1c0269c71b8..7d3ea2db0aec 100644 --- a/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js +++ b/ui/pages/confirmations/confirmation/templates/create-named-snap-account.test.js @@ -85,9 +85,9 @@ const mockBaseStore = { }; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/confirmation/templates/create-snap-account.js b/ui/pages/confirmations/confirmation/templates/create-snap-account.js index 3ff9892f90c2..e3699510475c 100644 --- a/ui/pages/confirmations/confirmation/templates/create-snap-account.js +++ b/ui/pages/confirmations/confirmation/templates/create-snap-account.js @@ -4,7 +4,7 @@ import { MetaMetricsEventAccountType, } from '../../../../../shared/constants/metametrics'; -function getValues(pendingApproval, t, actions, _history, _data, contexts) { +function getValues(pendingApproval, t, actions, _navigate, _data, contexts) { const { origin: snapId, snapName } = pendingApproval; const { trackEvent } = contexts; diff --git a/ui/pages/confirmations/confirmation/templates/remove-snap-account.js b/ui/pages/confirmations/confirmation/templates/remove-snap-account.js index f7f0324f5889..4c5e64f8712a 100644 --- a/ui/pages/confirmations/confirmation/templates/remove-snap-account.js +++ b/ui/pages/confirmations/confirmation/templates/remove-snap-account.js @@ -4,7 +4,7 @@ import { MetaMetricsEventAccountType, } from '../../../../../shared/constants/metametrics'; -function getValues(pendingApproval, t, actions, _history, _data, contexts) { +function getValues(pendingApproval, t, actions, _navigate, _data, contexts) { const { origin: snapId, snapName } = pendingApproval; const { publicAddress } = pendingApproval.requestData; const { trackEvent } = contexts; diff --git a/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js b/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js index 0143e26310ae..1d3ec6d2645a 100644 --- a/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js +++ b/ui/pages/confirmations/confirmation/templates/smart-transaction-status-page.js @@ -1,5 +1,5 @@ // eslint-disable-next-line no-unused-vars -function getValues(pendingApproval, t, actions, _history) { +function getValues(pendingApproval, t, actions, _navigate) { const { id, requestState } = pendingApproval; return { content: [ diff --git a/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js b/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js index b987eff014ad..4356560ee73e 100644 --- a/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js +++ b/ui/pages/confirmations/confirmation/templates/snap-account-redirect.js @@ -4,7 +4,7 @@ import { MetaMetricsEventAccountType, } from '../../../../../shared/constants/metametrics'; -function getValues(pendingApproval, t, actions, _history, _data, contexts) { +function getValues(pendingApproval, t, actions, _navigate, _data, contexts) { const { origin: snapId, snapName } = pendingApproval; const { url, message, isBlockedUrl } = pendingApproval.requestData; const { trackEvent } = contexts; diff --git a/ui/pages/confirmations/context/confirm/index.tsx b/ui/pages/confirmations/context/confirm/index.tsx index f74e270ee6b9..19871e35c2f4 100644 --- a/ui/pages/confirmations/context/confirm/index.tsx +++ b/ui/pages/confirmations/context/confirm/index.tsx @@ -27,7 +27,7 @@ export const ConfirmContextProvider: React.FC<{ const [isScrollToBottomCompleted, setIsScrollToBottomCompleted] = useState(true); const { currentConfirmation } = useCurrentConfirmation(confirmationId); - useSyncConfirmPath(currentConfirmation, confirmationId); + useSyncConfirmPath(currentConfirmation); const value = useMemo( () => ({ diff --git a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts index 62c9178ea302..c076d5124095 100644 --- a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts +++ b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.test.ts @@ -19,9 +19,9 @@ jest.mock('../transactions/useEnableShieldCoverageChecks', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts index 1d982ea1a464..d6a92df76f73 100644 --- a/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts +++ b/ui/pages/confirmations/hooks/alerts/useShieldCoverageAlert.ts @@ -2,7 +2,7 @@ import { SignatureRequest } from '@metamask/signature-controller'; import { TransactionMeta } from '@metamask/transaction-controller'; import { useCallback, useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { CoverageStatus } from '@metamask/shield-controller'; import { RowAlertKey } from '../../../../components/app/confirm/info/row/constants'; import { Alert } from '../../../../ducks/confirm-alerts/confirm-alerts'; diff --git a/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx index 275cd68aba14..b7155fea2aea 100644 --- a/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx +++ b/ui/pages/confirmations/hooks/send/metrics/useAmountSelectionMetrics.test.tsx @@ -1,7 +1,7 @@ import React, { ReactChildren } from 'react'; import mockState from '../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { useAmountSelectionMetrics } from './useAmountSelectionMetrics'; diff --git a/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx index 0db6739c8d2f..609f707e9d00 100644 --- a/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx +++ b/ui/pages/confirmations/hooks/send/metrics/useAssetSelectionMetrics.test.tsx @@ -8,7 +8,7 @@ import { MOCK_NFT1155, SOLANA_NATIVE_ASSET, } from '../../../../../../test/data/send/assets'; -import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { AssetFilterMethod, diff --git a/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx b/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx index 323642bba844..7511097c5a0f 100644 --- a/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx +++ b/ui/pages/confirmations/hooks/send/metrics/useRecipientSelectionMetrics.test.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import React, { ReactChildren } from 'react'; import mockTestState from '../../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../../test/lib/render-helpers-navigate'; import { MetaMetricsContext } from '../../../../../contexts/metametrics'; import { RecipientInputMethod } from '../../../context/send-metrics'; diff --git a/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts b/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts index 7e1de3c33862..3e05f923e2d6 100644 --- a/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts +++ b/ui/pages/confirmations/hooks/send/useAccountAddressSeedIconMap.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import * as accountTreeSelectors from '../../../../selectors/multichain-accounts/account-tree'; import { AccountGroupWithInternalAccounts } from '../../../../selectors/multichain-accounts/account-tree.types'; diff --git a/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts b/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts index cedc4b8e1b5d..26aadc00f58c 100644 --- a/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts +++ b/ui/pages/confirmations/hooks/send/useAccountRecipients.test.ts @@ -1,7 +1,7 @@ import { BtcAccountType } from '@metamask/keyring-api'; import { cloneDeep } from 'lodash'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { ConsolidatedWallets } from '../../../../selectors/multichain-accounts/account-tree.types'; import * as accountTreeSelectors from '../../../../selectors/multichain-accounts/account-tree'; diff --git a/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts b/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts index 5f69babb2256..f68cdb39a522 100644 --- a/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts +++ b/ui/pages/confirmations/hooks/send/useAmountValidation.test.ts @@ -3,7 +3,7 @@ import { waitFor } from '@testing-library/react'; import { Numeric } from '../../../../../shared/modules/Numeric'; import mockState from '../../../../../test/data/mock-state.json'; import { EVM_NATIVE_ASSET } from '../../../../../test/data/send/assets'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { Asset, AssetStandard } from '../../types/send'; import * as SendContext from '../../context/send'; import { diff --git a/ui/pages/confirmations/hooks/send/useBalance.test.ts b/ui/pages/confirmations/hooks/send/useBalance.test.ts index 530c69bbca0b..40e08fb8bbc6 100644 --- a/ui/pages/confirmations/hooks/send/useBalance.test.ts +++ b/ui/pages/confirmations/hooks/send/useBalance.test.ts @@ -6,7 +6,7 @@ import { MOCK_NFT1155, } from '../../../../../test/data/send/assets'; import { Numeric } from '../../../../../shared/modules/Numeric'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as SendContext from '../../context/send'; import { useBalance } from './useBalance'; diff --git a/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts b/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts index b069cb6fca4a..53e2515adcdf 100644 --- a/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts +++ b/ui/pages/confirmations/hooks/send/useContactRecipients.test.ts @@ -1,5 +1,5 @@ import { isAddress as isEvmAddress } from 'ethers/lib/utils'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import * as selectors from '../../../../selectors'; import * as SendContext from '../../context/send'; diff --git a/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts b/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts index d66e88f503e3..45338a73ec70 100644 --- a/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts +++ b/ui/pages/confirmations/hooks/send/useCurrencyConversions.test.ts @@ -7,7 +7,7 @@ import { MOCK_NFT1155, MOCK_NFT721, } from '../../../../../test/data/send/assets'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as SendContext from '../../context/send'; import { useCurrencyConversions } from './useCurrencyConversions'; diff --git a/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts b/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts index 91933ac7e66b..d59e65ac59dd 100644 --- a/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts +++ b/ui/pages/confirmations/hooks/send/useMaxAmount.test.ts @@ -7,7 +7,7 @@ import { SOLANA_ASSET, } from '../../../../../test/data/send/assets'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as SendContext from '../../context/send'; import { useMaxAmount } from './useMaxAmount'; import { useBalance } from './useBalance'; diff --git a/ui/pages/confirmations/hooks/send/useNameValidation.test.ts b/ui/pages/confirmations/hooks/send/useNameValidation.test.ts index 91a95ce995d8..cba407d3dfbd 100644 --- a/ui/pages/confirmations/hooks/send/useNameValidation.test.ts +++ b/ui/pages/confirmations/hooks/send/useNameValidation.test.ts @@ -1,7 +1,7 @@ import { AddressResolution } from '@metamask/snaps-sdk'; import mockState from '../../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { lookupDomainName } from '../../../../ducks/domains'; // eslint-disable-next-line import/no-namespace import * as SnapNameResolution from '../../../../hooks/snaps/useSnapNameResolution'; diff --git a/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts b/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts index 6a5bac09313b..49eefe8af051 100644 --- a/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts +++ b/ui/pages/confirmations/hooks/send/useNavigateSendPage.test.ts @@ -5,8 +5,8 @@ import { SendPages } from '../../constants/send'; import { useNavigateSendPage } from './useNavigateSendPage'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: jest diff --git a/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts b/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts index 98be7fb7623c..f6919c3482bb 100644 --- a/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts +++ b/ui/pages/confirmations/hooks/send/useNavigateSendPage.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { useNavigate, useSearchParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import { SEND_ROUTE, diff --git a/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts b/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts index 4d31718a86b2..dc81582ecb9e 100644 --- a/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts +++ b/ui/pages/confirmations/hooks/send/useRecipientValidation.test.ts @@ -6,7 +6,7 @@ import { EVM_ASSET, SOLANA_ASSET, } from '../../../../../test/data/send/assets'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { useSendContext } from '../../context/send'; import * as SendValidationUtils from '../../utils/sendValidations'; diff --git a/ui/pages/confirmations/hooks/send/useRecipients.test.ts b/ui/pages/confirmations/hooks/send/useRecipients.test.ts index 4f330d81a13f..bd2bad279bbb 100644 --- a/ui/pages/confirmations/hooks/send/useRecipients.test.ts +++ b/ui/pages/confirmations/hooks/send/useRecipients.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { type Recipient, useRecipients } from './useRecipients'; import * as useContactRecipientsModule from './useContactRecipients'; diff --git a/ui/pages/confirmations/hooks/send/useSendActions.test.ts b/ui/pages/confirmations/hooks/send/useSendActions.test.ts index 9e7c354f0723..c6fe536d8af3 100644 --- a/ui/pages/confirmations/hooks/send/useSendActions.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendActions.test.ts @@ -21,9 +21,9 @@ jest.mock('../../../../store/actions', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/hooks/send/useSendActions.ts b/ui/pages/confirmations/hooks/send/useSendActions.ts index bcd0da87de67..bc6d60995f80 100644 --- a/ui/pages/confirmations/hooks/send/useSendActions.ts +++ b/ui/pages/confirmations/hooks/send/useSendActions.ts @@ -2,7 +2,7 @@ import { CaipAssetType, Hex } from '@metamask/utils'; import { InternalAccount } from '@metamask/keyring-internal-api'; import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { CONFIRM_TRANSACTION_ROUTE, diff --git a/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts b/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts index bfe7767a6051..c6221b257c90 100644 --- a/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendAssetFilter.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { type Asset } from '../../types/send'; import { useSendAssetFilter } from './useSendAssetFilter'; diff --git a/ui/pages/confirmations/hooks/send/useSendAssets.test.ts b/ui/pages/confirmations/hooks/send/useSendAssets.test.ts index 16dbda7939f8..e9efd34d9ee7 100644 --- a/ui/pages/confirmations/hooks/send/useSendAssets.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendAssets.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { type Asset } from '../../types/send'; import { useSendAssets } from './useSendAssets'; diff --git a/ui/pages/confirmations/hooks/send/useSendNfts.test.ts b/ui/pages/confirmations/hooks/send/useSendNfts.test.ts index a4ab2708bd1d..e0743475d2c9 100644 --- a/ui/pages/confirmations/hooks/send/useSendNfts.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendNfts.test.ts @@ -1,7 +1,7 @@ import { waitFor } from '@testing-library/react'; import { useSelector } from 'react-redux'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { getAccountGroupWithInternalAccounts, diff --git a/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts b/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts index 74d947243528..259b88ced830 100644 --- a/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendQueryParams.test.ts @@ -1,6 +1,6 @@ import { DefaultRootState, useSelector } from 'react-redux'; -import { useSearchParams } from 'react-router-dom-v5-compat'; -import { SetURLSearchParams } from 'react-router-dom-v5-compat/dist/react-router-dom'; +import { useSearchParams } from 'react-router-dom'; +import type { SetURLSearchParams } from 'react-router-dom'; import mockState from '../../../../../test/data/mock-state.json'; import { EVM_ASSET, MOCK_NFT1155 } from '../../../../../test/data/send/assets'; @@ -12,8 +12,8 @@ import * as SendContext from '../../context/send'; import { useSendQueryParams } from './useSendQueryParams'; import { useSendNfts } from './useSendNfts'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: jest.fn().mockReturnValue([{ get: () => null }]), })); diff --git a/ui/pages/confirmations/hooks/send/useSendQueryParams.ts b/ui/pages/confirmations/hooks/send/useSendQueryParams.ts index 0f9d1f01ec3b..9c83c5f30130 100644 --- a/ui/pages/confirmations/hooks/send/useSendQueryParams.ts +++ b/ui/pages/confirmations/hooks/send/useSendQueryParams.ts @@ -1,10 +1,6 @@ import { Hex } from '@metamask/utils'; import { useEffect, useMemo } from 'react'; -import { - useNavigate, - useLocation, - useSearchParams, -} from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation, useSearchParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { SEND_ROUTE } from '../../../../helpers/constants/routes'; diff --git a/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts b/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts index 0ff2ae647fea..7c0cd63569ee 100644 --- a/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendRecipientFilter.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { type Recipient } from './useRecipients'; import { useSendRecipientFilter } from './useSendRecipientFilter'; diff --git a/ui/pages/confirmations/hooks/send/useSendTokens.test.ts b/ui/pages/confirmations/hooks/send/useSendTokens.test.ts index 53b38c425a95..2a9d1d297627 100644 --- a/ui/pages/confirmations/hooks/send/useSendTokens.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendTokens.test.ts @@ -1,6 +1,6 @@ import { useSelector } from 'react-redux'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../../test/data/mock-state.json'; import { getAssetsBySelectedAccountGroup } from '../../../../selectors/assets'; import * as useFiatFormatterModule from '../../../../hooks/useFiatFormatter'; diff --git a/ui/pages/confirmations/hooks/send/useSendType.test.ts b/ui/pages/confirmations/hooks/send/useSendType.test.ts index c5b2b16741b6..4ebe3a5ba653 100644 --- a/ui/pages/confirmations/hooks/send/useSendType.test.ts +++ b/ui/pages/confirmations/hooks/send/useSendType.test.ts @@ -6,12 +6,12 @@ import { SOLANA_ASSET, SOLANA_NATIVE_ASSET, } from '../../../../../test/data/send/assets'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as SendContext from '../../context/send'; import { useSendType } from './useSendType'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/send/asset' }), useSearchParams: () => [{ get: () => null }], })); diff --git a/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts b/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts index 65d936a4c870..f841fdc45b9d 100644 --- a/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts +++ b/ui/pages/confirmations/hooks/send/useSnapAmountOnInput.test.ts @@ -1,7 +1,7 @@ import { InternalAccount } from '@metamask/keyring-internal-api'; import { CaipAssetType } from '@metamask/utils'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import * as SendContext from '../../context/send'; import * as MultichainSnaps from '../../utils/multichain-snaps'; import { useSnapAmountOnInput } from './useSnapAmountOnInput'; diff --git a/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts b/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts index ea6f4fdf9554..e81e8e24c757 100644 --- a/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts +++ b/ui/pages/confirmations/hooks/transactions/useEnableShieldCoverageChecks.test.ts @@ -2,7 +2,7 @@ import { PRODUCT_TYPES, SUBSCRIPTION_STATUSES, } from '@metamask/subscription-controller'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { useEnableShieldCoverageChecks } from './useEnableShieldCoverageChecks'; jest.mock('../../../../hooks/subscription/useSubscription', () => ({ diff --git a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts index dbccbbee6e1b..c82009d61330 100644 --- a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts +++ b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.test.ts @@ -2,12 +2,12 @@ import { TransactionMeta, TransactionType, } from '@metamask/transaction-controller'; -import { renderHookWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { PREVIOUS_ROUTE } from '../../../../helpers/constants/routes'; import { useShieldConfirm } from './useShieldConfirm'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: jest.fn(), })); @@ -16,7 +16,7 @@ const mockNavigate = jest.fn(); describe('useShieldConfirm', () => { beforeEach(() => { jest.resetAllMocks(); - const { useNavigate } = jest.requireMock('react-router-dom-v5-compat'); + const { useNavigate } = jest.requireMock('react-router-dom'); useNavigate.mockReturnValue(mockNavigate); }); diff --git a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts index d566cbfc48ed..1704fd55a3ce 100644 --- a/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts +++ b/ui/pages/confirmations/hooks/transactions/useShieldConfirm.ts @@ -3,7 +3,7 @@ import { TransactionType, } from '@metamask/transaction-controller'; import { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { TRANSACTION_SHIELD_ROUTE, PREVIOUS_ROUTE, diff --git a/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts b/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts index 6b5d7bc5f4fe..5ef4b00e0f4b 100644 --- a/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts +++ b/ui/pages/confirmations/hooks/transactions/useTransactionConfirm.test.ts @@ -28,9 +28,9 @@ jest.mock('../../../../store/actions', () => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts b/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts index cdef3e73e4d9..9fc95f91834a 100644 --- a/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts +++ b/ui/pages/confirmations/hooks/useBatchAuthorizationRequests.test.ts @@ -1,7 +1,7 @@ import { TransactionStatus } from '@metamask/transaction-controller'; import { getMockConfirmStateForTransaction } from '../../../../test/data/confirmations/helper'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { Confirmation } from '../types/confirm'; import { useBatchAuthorizationRequests } from './useBatchAuthorizationRequests'; diff --git a/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts b/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts index 91beed49c39b..159744819d31 100644 --- a/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts +++ b/ui/pages/confirmations/hooks/useChainNetworkNameAndImage.test.ts @@ -1,5 +1,5 @@ import mockState from '../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useChainNetworkNameAndImageMap } from './useChainNetworkNameAndImage'; function renderHook() { diff --git a/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts b/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts index 49efb582baf9..01148df46aee 100644 --- a/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts +++ b/ui/pages/confirmations/hooks/useConfirmSendNavigation.test.ts @@ -7,9 +7,9 @@ import { useConfirmSendNavigation } from './useConfirmSendNavigation'; const mockUseRedesignedSendFlow = jest.mocked(useRedesignedSendFlow); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts b/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts index 084a3ac8114c..9d3c488e4a74 100644 --- a/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts +++ b/ui/pages/confirmations/hooks/useConfirmSendNavigation.ts @@ -3,7 +3,7 @@ import { TransactionType, } from '@metamask/transaction-controller'; import { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useConfirmContext } from '../context/confirm'; import { PREVIOUS_ROUTE } from '../../../helpers/constants/routes'; diff --git a/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts b/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts index a278bffcb34b..7cb940b3695f 100644 --- a/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts +++ b/ui/pages/confirmations/hooks/useConfirmationAlertActions.test.ts @@ -1,4 +1,4 @@ -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { AlertActionKey } from '../../../components/app/confirm/info/row/constants'; import { useTransactionModalContext } from '../../../contexts/transaction-modal'; diff --git a/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts b/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts index 983b21a61541..452b0e19cf42 100644 --- a/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts +++ b/ui/pages/confirmations/hooks/useConfirmationAlerts.test.ts @@ -3,9 +3,9 @@ import mockState from '../../../../test/data/mock-state.json'; import useConfirmationAlerts from './useConfirmationAlerts'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts b/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts index 3a67f2587780..8e6bdb4130bb 100644 --- a/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts +++ b/ui/pages/confirmations/hooks/useConfirmationNavigation.test.ts @@ -17,9 +17,9 @@ import { useConfirmationNavigation } from './useConfirmationNavigation'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/pages/confirmations/hooks/useConfirmationNavigation.ts b/ui/pages/confirmations/hooks/useConfirmationNavigation.ts index c3150999918e..8dfc30c9415f 100644 --- a/ui/pages/confirmations/hooks/useConfirmationNavigation.ts +++ b/ui/pages/confirmations/hooks/useConfirmationNavigation.ts @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { ApprovalType } from '@metamask/controller-utils'; import { isEqual } from 'lodash'; import { ApprovalRequest } from '@metamask/approval-controller'; diff --git a/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts b/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts index 4f66a2ad4743..87e6f8439670 100644 --- a/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts +++ b/ui/pages/confirmations/hooks/useCurrentConfirmation.test.ts @@ -23,9 +23,9 @@ const MESSAGE_MOCK = { }; const mockUseParams = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useParams: () => mockUseParams(), }; }); diff --git a/ui/pages/confirmations/hooks/useCurrentConfirmation.ts b/ui/pages/confirmations/hooks/useCurrentConfirmation.ts index 5fd4fb9cec31..21aa93c8882b 100644 --- a/ui/pages/confirmations/hooks/useCurrentConfirmation.ts +++ b/ui/pages/confirmations/hooks/useCurrentConfirmation.ts @@ -2,7 +2,7 @@ import { ApprovalType } from '@metamask/controller-utils'; import { TransactionMeta } from '@metamask/transaction-controller'; import { useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { useParams } from 'react-router-dom-v5-compat'; +import { useParams } from 'react-router-dom'; import { ApprovalsMetaMaskState, getUnapprovedTransaction, diff --git a/ui/pages/confirmations/hooks/useEIP7702Account.test.ts b/ui/pages/confirmations/hooks/useEIP7702Account.test.ts index 20f29286afa2..a3fa54661d43 100644 --- a/ui/pages/confirmations/hooks/useEIP7702Account.test.ts +++ b/ui/pages/confirmations/hooks/useEIP7702Account.test.ts @@ -9,7 +9,7 @@ import { getCode, } from '../../../store/actions'; import { EIP_7702_REVOKE_ADDRESS } from '../../../../shared/lib/eip7702-utils'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useConfirmationNavigation } from './useConfirmationNavigation'; import { useEIP7702Account } from './useEIP7702Account'; diff --git a/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts b/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts index 3c098917140a..d78b0d72e409 100644 --- a/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts +++ b/ui/pages/confirmations/hooks/useEIP7702Networks.test.ts @@ -1,5 +1,5 @@ import { waitFor } from '@testing-library/react'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { useEIP7702Networks, EIP7702NetworkConfiguration, diff --git a/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts b/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts index ac890f7e2050..0d59c3cbecf0 100644 --- a/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts +++ b/ui/pages/confirmations/hooks/useRedesignedSendFlow.test.ts @@ -1,5 +1,5 @@ import mockState from '../../../../test/data/mock-state.json'; -import { renderHookWithProvider } from '../../../../test/lib/render-helpers'; +import { renderHookWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { getRemoteFeatureFlags } from '../../../selectors/remote-feature-flags'; import { useRedesignedSendFlow } from './useRedesignedSendFlow'; diff --git a/ui/pages/confirmations/hooks/useRouting.js b/ui/pages/confirmations/hooks/useRouting.js index 3dc238d31c7e..c66d7869585e 100644 --- a/ui/pages/confirmations/hooks/useRouting.js +++ b/ui/pages/confirmations/hooks/useRouting.js @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { getMostRecentOverviewPage } from '../../../ducks/history/history'; diff --git a/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts index 19bd2d8795b8..a058a5ef1bb7 100644 --- a/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts +++ b/ui/pages/confirmations/hooks/useSyncConfirmPath.test.ts @@ -7,9 +7,9 @@ import useSyncConfirmPath from './useSyncConfirmPath'; const mockUseNavigate = jest.fn(); const mockUseParams = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), useLocation: () => mockUseLocation(), @@ -30,8 +30,15 @@ const STATE_MOCK = { }; describe('useSyncConfirmPath', () => { + const originalLocation = window.location; + beforeEach(() => { jest.clearAllMocks(); + // Mock window.location since the hook reads from global location + Object.defineProperty(window, 'location', { + value: { pathname: '/confirm-transaction' }, + writable: true, + }); // Default mock: on confirmation route with no params mockUseLocation.mockReturnValue({ pathname: '/confirm-transaction', @@ -42,6 +49,13 @@ describe('useSyncConfirmPath', () => { mockUseParams.mockReturnValue({}); }); + afterEach(() => { + Object.defineProperty(window, 'location', { + value: originalLocation, + writable: true, + }); + }); + it('should execute correctly', () => { const result = renderHookWithConfirmContextProvider( () => useSyncConfirmPath(unapprovedPersonalSignMsg), diff --git a/ui/pages/confirmations/hooks/useSyncConfirmPath.ts b/ui/pages/confirmations/hooks/useSyncConfirmPath.ts index d4de723a9bab..d7e075250b65 100644 --- a/ui/pages/confirmations/hooks/useSyncConfirmPath.ts +++ b/ui/pages/confirmations/hooks/useSyncConfirmPath.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useParams, useLocation } from 'react-router-dom-v5-compat'; +import { useParams } from 'react-router-dom'; import { CONFIRM_TRANSACTION_ROUTE, @@ -8,17 +8,10 @@ import { import { Confirmation } from '../types/confirm'; import { useConfirmationNavigation } from './useConfirmationNavigation'; -const useSyncConfirmPath = ( - currentConfirmation?: Confirmation, - routeParamId?: string, -) => { +const useSyncConfirmPath = (currentConfirmation?: Confirmation) => { const { navigateToId } = useConfirmationNavigation(); - const location = useLocation(); - - // Use routeParamId from props if available (passed from v5 Route), - // otherwise fall back to useParams() for v5-compat Routes - const urlParams = useParams<{ id: string }>(); - const paramId = routeParamId || urlParams.id; + const { id: paramId } = useParams<{ id: string }>(); + const confirmationId = currentConfirmation?.id; useEffect(() => { // Only sync path if we're on a confirmation route @@ -35,11 +28,11 @@ const useSyncConfirmPath = ( // This ensures /confirm-transaction always becomes /confirm-transaction/ // which is critical for popup/notification windows and "X of Y" navigation if (!paramId && currentConfirmation) { - navigateToId(currentConfirmation.id); + navigateToId(confirmationId); } // Note: confirmations is intentionally excluded from dependencies // navigateToId is memoized with useCallback and is sufficient for tracking changes - }, [paramId, currentConfirmation, navigateToId, location.pathname]); + }, [paramId, currentConfirmation, navigateToId, confirmationId]); }; export default useSyncConfirmPath; diff --git a/ui/pages/confirmations/send/send-inner.test.tsx b/ui/pages/confirmations/send/send-inner.test.tsx index c9225e13810a..16d474f173f9 100644 --- a/ui/pages/confirmations/send/send-inner.test.tsx +++ b/ui/pages/confirmations/send/send-inner.test.tsx @@ -7,8 +7,8 @@ import * as SendContext from '../context/send'; import { SendPages } from '../constants/send'; import { SendInner } from './send-inner'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '' }), useSearchParams: () => [{ get: () => null }], })); diff --git a/ui/pages/confirmations/utils/send.ts b/ui/pages/confirmations/utils/send.ts index 4c05f6694fd7..176360283a76 100644 --- a/ui/pages/confirmations/utils/send.ts +++ b/ui/pages/confirmations/utils/send.ts @@ -5,7 +5,7 @@ import { TransactionType, } from '@metamask/transaction-controller'; import { addHexPrefix } from 'ethereumjs-util'; -import { NavigateFunction } from 'react-router-dom-v5-compat'; +import { NavigateFunction } from 'react-router-dom'; import { Numeric, NumericBase } from '../../../../shared/modules/Numeric'; import { diff --git a/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx b/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx index 5d4c9540ab07..84bf3ee92b2e 100644 --- a/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx +++ b/ui/pages/core/hyperliquid-referral-consent/hyperliquid-referral-consent.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent, screen } from '@testing-library/react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import { HyperliquidReferralConsent } from './hyperliquid-referral-consent'; diff --git a/ui/pages/create-account/connect-hardware/index.test.tsx b/ui/pages/create-account/connect-hardware/index.test.tsx index 14a489d5d706..e94c3256c4d7 100644 --- a/ui/pages/create-account/connect-hardware/index.test.tsx +++ b/ui/pages/create-account/connect-hardware/index.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, waitFor } from '@testing-library/react'; import thunk from 'redux-thunk'; import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { @@ -48,11 +48,9 @@ jest.mock('../../../ducks/history/history', () => ({ .mockImplementation(() => MOCK_RECENT_PAGE), })); -// Mock React Router v5-compat hooks that withRouterHooks uses const mockUseNavigate = jest.fn(); - -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ pathname: '/test' }), useParams: () => ({}), diff --git a/ui/pages/create-account/create-account.component.js b/ui/pages/create-account/create-account.component.js index 145a74ac1a69..99f3b5bab84d 100644 --- a/ui/pages/create-account/create-account.component.js +++ b/ui/pages/create-account/create-account.component.js @@ -1,17 +1,13 @@ import React from 'react'; -import { Routes, Route } from 'react-router-dom-v5-compat'; +import { Routes, Route } from 'react-router-dom'; import { Box } from '../../components/component-library'; -import { CONNECT_HARDWARE_ROUTE } from '../../helpers/constants/routes'; import ConnectHardwareForm from './connect-hardware'; export default function CreateAccountPage() { return ( - } - /> + } /> ); diff --git a/ui/pages/deep-link/deep-link.tsx b/ui/pages/deep-link/deep-link.tsx index 6c1c7c892c54..a790426d6ae6 100644 --- a/ui/pages/deep-link/deep-link.tsx +++ b/ui/pages/deep-link/deep-link.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import type { Location as RouterLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import log from 'loglevel'; import { useDispatch, useSelector } from 'react-redux'; import { @@ -160,11 +160,8 @@ async function updateStateFromUrl( } } -type DeepLinkProps = { - location: RouterLocation; -}; - -export const DeepLink = ({ location }: DeepLinkProps) => { +export const DeepLink = () => { + const location = useLocation(); const t = useI18nContext() as TranslateFunction; const dispatch = useDispatch(); // it's technically not possible for a natural flow to reach this page diff --git a/ui/pages/defi/components/defi-details-list.test.tsx b/ui/pages/defi/components/defi-details-list.test.tsx index c7cce1096d5b..e173bfe99f75 100644 --- a/ui/pages/defi/components/defi-details-list.test.tsx +++ b/ui/pages/defi/components/defi-details-list.test.tsx @@ -11,9 +11,9 @@ const mockUseParams = jest .mockReturnValue({ chainId: CHAIN_IDS.MAINNET, protocolId: 'aave' }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), }; diff --git a/ui/pages/defi/components/defi-details-page.test.tsx b/ui/pages/defi/components/defi-details-page.test.tsx index 7b2d72092fd8..8db95125bec8 100644 --- a/ui/pages/defi/components/defi-details-page.test.tsx +++ b/ui/pages/defi/components/defi-details-page.test.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Route, Routes } from 'react-router-dom'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { CHAIN_IDS } from '../../../../shared/constants/network'; @@ -6,12 +7,11 @@ import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate import mockState from '../../../../test/data/mock-state.json'; import DeFiPage from './defi-details-page'; -const mockNavigate = jest.fn(); - describe('DeFiDetailsPage', () => { const mockStore = { ...mockState, metamask: { + ...mockState.metamask, allDeFiPositions: { [mockState.metamask.selectedAddress]: { '0x1': { @@ -64,7 +64,6 @@ describe('DeFiDetailsPage', () => { }, }, }, - ...mockState.metamask, }, }; @@ -81,11 +80,11 @@ describe('DeFiDetailsPage', () => { it('renders defi asset page', () => { const { container } = renderWithProvider( - , + + } /> + , store, + `/defi/${CHAIN_IDS.MAINNET}/aave`, ); expect(container).toMatchSnapshot(); diff --git a/ui/pages/defi/components/defi-details-page.tsx b/ui/pages/defi/components/defi-details-page.tsx index bd6597203ad4..29dc1f311485 100644 --- a/ui/pages/defi/components/defi-details-page.tsx +++ b/ui/pages/defi/components/defi-details-page.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate, useNavigate, useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { Display, @@ -45,14 +45,10 @@ const useExtractUnderlyingTokens = ( ); }, [positions]); -type DeFiPageProps = { - navigate: (to: string | number) => void; - params: { chainId: string; protocolId: string }; -}; - -const DeFiPage = ({ navigate, params }: DeFiPageProps) => { +const DeFiPage = () => { const { formatCurrencyWithMinThreshold } = useFormatters(); - const { chainId, protocolId } = params; + const { chainId, protocolId } = useParams(); + const navigate = useNavigate(); const defiPositions = useSelector(getDefiPositions); const selectedAccount = useSelector(getSelectedAccount); @@ -61,9 +57,11 @@ const DeFiPage = ({ navigate, params }: DeFiPageProps) => { // TODO: Get value in user's preferred currency const protocolPosition = - defiPositions[selectedAccount.address]?.[ - chainId as keyof (typeof defiPositions)[string] - ]?.protocols[protocolId]; + chainId && protocolId + ? defiPositions[selectedAccount.address]?.[ + chainId as keyof (typeof defiPositions)[string] + ]?.protocols[protocolId] + : undefined; const extractedTokens = useMemo(() => { return Object.keys(protocolPosition?.positionTypes || {}).reduce( diff --git a/ui/pages/error-page/error-component.test.tsx b/ui/pages/error-page/error-component.test.tsx index 239ba038f445..378cb52f0454 100644 --- a/ui/pages/error-page/error-component.test.tsx +++ b/ui/pages/error-page/error-component.test.tsx @@ -5,7 +5,7 @@ import browser from 'webextension-polyfill'; import { fireEvent } from '@testing-library/react'; import thunk from 'redux-thunk'; import configureMockState from 'redux-mock-store'; -import { renderWithProvider } from '../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { useI18nContext } from '../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../contexts/metametrics'; import { getParticipateInMetaMetrics } from '../../selectors'; diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index b82c984a260f..7349be2138ce 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate } from 'react-router-dom'; import { Text, TextVariant, TextColor } from '@metamask/design-system-react'; import { COHORT_NAMES } from '@metamask/subscription-controller'; import { diff --git a/ui/pages/home/home.component.stories.tsx b/ui/pages/home/home.component.stories.tsx index 751cd0a8e9ae..e2a3431749ff 100644 --- a/ui/pages/home/home.component.stories.tsx +++ b/ui/pages/home/home.component.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StoryObj, Meta } from '@storybook/react'; import { Provider } from 'react-redux'; -import { MemoryRouter } from 'react-router-dom-v5-compat'; +import { MemoryRouter } from 'react-router-dom'; import Home from './home.component'; import mockState from '../../../test/data/mock-state.json'; import configureStore from '../../store/store'; diff --git a/ui/pages/home/home.container.js b/ui/pages/home/home.container.js index 0842ddb51fcb..f8a2e1576375 100644 --- a/ui/pages/home/home.container.js +++ b/ui/pages/home/home.container.js @@ -2,7 +2,6 @@ import React from 'react'; import { compose } from 'redux'; import { connect } from 'react-redux'; import withRouterHooks from '../../helpers/higher-order-components/with-router-hooks/with-router-hooks'; -import { useNavState } from '../../contexts/navigation-state'; import { useShieldSubscriptionContext } from '../../contexts/shield/shield-subscription'; import { activeTabHasPermissions, @@ -88,7 +87,6 @@ import { getRedirectAfterDefaultPage, clearRedirectAfterDefaultPage, } from '../../ducks/history/history'; - import Home from './home.component'; const mapStateToProps = (state) => { @@ -250,18 +248,12 @@ const mapDispatchToProps = (dispatch) => { // Strip unused 'match' prop from withRouter // It causes cascading, unnecessary re-renders -// Also inject navState from NavigationStateContext for v5-compat navigation // eslint-disable-next-line react/prop-types const HomeWithRouter = ({ match: _match, ...props }) => { - const navState = useNavState(); const { evaluateCohortEligibility } = useShieldSubscriptionContext(); return ( - + ); }; diff --git a/ui/pages/index.js b/ui/pages/index.js index 0f0c2b1d934d..6c24d69ffdf3 100644 --- a/ui/pages/index.js +++ b/ui/pages/index.js @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { Provider } from 'react-redux'; import { HashRouter } from 'react-router-dom'; -import { CompatRouter } from 'react-router-dom-v5-compat'; import { captureException } from '../../shared/lib/sentry'; import { I18nProvider, LegacyI18nProvider } from '../contexts/i18n'; import { @@ -13,7 +12,6 @@ import { MetamaskNotificationsProvider } from '../contexts/metamask-notification import { AssetPollingProvider } from '../contexts/assetPolling'; import { MetamaskIdentityProvider } from '../contexts/identity'; import { ShieldSubscriptionProvider } from '../contexts/shield/shield-subscription'; -import { NavigationStateProvider } from '../contexts/navigation-state'; import RiveWasmProvider from '../contexts/rive-wasm'; import ErrorPage from './error-page/error-page.component'; @@ -48,30 +46,26 @@ class Index extends PureComponent { return ( - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + ); diff --git a/ui/pages/keychains/reveal-seed.js b/ui/pages/keychains/reveal-seed.js index f16f3ec13989..69e34db1274a 100644 --- a/ui/pages/keychains/reveal-seed.js +++ b/ui/pages/keychains/reveal-seed.js @@ -2,6 +2,7 @@ import qrCode from 'qrcode-generator'; import React, { useContext, useEffect, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import { useDispatch, useSelector } from 'react-redux'; +import { useNavigate } from 'react-router-dom'; import { getErrorMessage } from '../../../shared/modules/error'; import { MetaMetricsEventCategory, @@ -38,15 +39,16 @@ import { import ZENDESK_URLS from '../../helpers/constants/zendesk-url'; import { useI18nContext } from '../../hooks/useI18nContext'; import { requestRevealSeedWords } from '../../store/actions'; -import { getHDEntropyIndex } from '../../selectors/selectors'; +import { getHDEntropyIndex } from '../../selectors'; import { endTrace, trace, TraceName } from '../../../shared/lib/trace'; import { PREVIOUS_ROUTE } from '../../helpers/constants/routes'; const PASSWORD_PROMPT_SCREEN = 'PASSWORD_PROMPT_SCREEN'; const REVEAL_SEED_SCREEN = 'REVEAL_SEED_SCREEN'; -function RevealSeedPage({ navigate, keyringId }) { +function RevealSeedPage({ keyringId }) { const dispatch = useDispatch(); + const navigate = useNavigate(); const t = useI18nContext(); const trackEvent = useContext(MetaMetricsContext); const hdEntropyIndex = useSelector(getHDEntropyIndex); @@ -410,7 +412,6 @@ function RevealSeedPage({ navigate, keyringId }) { } RevealSeedPage.propTypes = { - navigate: PropTypes.func.isRequired, keyringId: PropTypes.string, }; diff --git a/ui/pages/multi-srp/import-srp/import-srp.test.tsx b/ui/pages/multi-srp/import-srp/import-srp.test.tsx index 2eadb7e00e5e..cae8a42e289f 100644 --- a/ui/pages/multi-srp/import-srp/import-srp.test.tsx +++ b/ui/pages/multi-srp/import-srp/import-srp.test.tsx @@ -32,8 +32,8 @@ jest.mock('../../../components/app/toast-master/utils', () => ({ })); const mockNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, })); diff --git a/ui/pages/multi-srp/import-srp/import-srp.tsx b/ui/pages/multi-srp/import-srp/import-srp.tsx index a260344a97fb..30634b9af802 100644 --- a/ui/pages/multi-srp/import-srp/import-srp.tsx +++ b/ui/pages/multi-srp/import-srp/import-srp.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { hideWarning, diff --git a/ui/pages/multichain-accounts/account-list/account-list.test.tsx b/ui/pages/multichain-accounts/account-list/account-list.test.tsx index fb86119d473f..1a399040bd6a 100644 --- a/ui/pages/multichain-accounts/account-list/account-list.test.tsx +++ b/ui/pages/multichain-accounts/account-list/account-list.test.tsx @@ -8,9 +8,9 @@ import mockState from '../../../../test/data/mock-state.json'; import { AccountList } from './account-list'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/multichain-accounts/account-list/account-list.tsx b/ui/pages/multichain-accounts/account-list/account-list.tsx index 7963d78f1605..5a39f7def98e 100644 --- a/ui/pages/multichain-accounts/account-list/account-list.tsx +++ b/ui/pages/multichain-accounts/account-list/account-list.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useState } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { diff --git a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx index 445ab6858cc4..3b3ab5667a89 100644 --- a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx +++ b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.test.tsx @@ -9,8 +9,8 @@ import { AddWalletPage } from './add-wallet-page'; const mockNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, })); diff --git a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx index 8e8fd6015ca2..cb8ba3987208 100644 --- a/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx +++ b/ui/pages/multichain-accounts/add-wallet-page/add-wallet-page.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { ButtonIcon, ButtonIconSize, diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx index 6160ff243af0..525b547c708e 100644 --- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx +++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.stories.tsx @@ -1,7 +1,7 @@ import React, { ReactNode } from 'react'; import { StoryObj, Meta } from '@storybook/react'; import { Provider } from 'react-redux'; -import { MemoryRouter, Route } from 'react-router-dom-v5-compat'; +import { MemoryRouter, Route } from 'react-router-dom'; import configureStore from 'redux-mock-store'; import { AccountGroupId } from '@metamask/account-api'; import { MultichainAccountAddressListPage } from './multichain-account-address-list-page'; diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx index 406a57971af5..58a22ca8f4c0 100644 --- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx +++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.test.tsx @@ -17,9 +17,9 @@ const MOCK_GROUP_NAME = 'Account 1'; const mockUseNavigate = jest.fn(); const mockUseParams = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), useLocation: () => mockUseLocation(), diff --git a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx index be7e1708eae3..82503756153a 100644 --- a/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx +++ b/ui/pages/multichain-accounts/multichain-account-address-list-page/multichain-account-address-list-page.tsx @@ -1,10 +1,6 @@ import React, { useState, useCallback } from 'react'; -import { - useNavigate, - useLocation, - useParams, -} from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation, useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { CaipChainId } from '@metamask/utils'; import { diff --git a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx index 5456b4bbf14b..c2bcb9c0bbfe 100644 --- a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx +++ b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.test.tsx @@ -18,9 +18,9 @@ const accountNameInputDataTestId = 'account-name-input'; const mockUseNavigate = jest.fn(); const mockUseParams = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), }; diff --git a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx index 2db1840ef3ff..6896e825264e 100644 --- a/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx +++ b/ui/pages/multichain-accounts/multichain-account-details-page/multichain-account-details-page.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useContext, useEffect, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { AccountGroupId, AccountWalletType } from '@metamask/account-api'; import classnames from 'classnames'; @@ -53,17 +53,12 @@ import { } from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -export const MultichainAccountDetailsPage = ({ - id: idProp, -}: { id?: string } = {}) => { +export const MultichainAccountDetailsPage = () => { const t = useI18nContext(); const navigate = useNavigate(); const dispatch = useDispatch(); const trackEvent = useContext(MetaMetricsContext); - const { id: idFromParams } = useParams(); - - // Use prop if provided (from createV5CompatRoute), otherwise fall back to hook - const id = idProp || idFromParams; + const { id } = useParams(); const accountGroupId = decodeURIComponent(id ?? '') as AccountGroupId; const multichainAccount = useSelector((state) => diff --git a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx index 763ac33da7a3..4c3b6694dec7 100644 --- a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx +++ b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.test.tsx @@ -13,8 +13,8 @@ const backButtonTestId = 'multichain-account-address-list-page-back-button'; // Use actual group IDs from mock-state.json const MOCK_GROUP_ID = 'entropy:01JKAF3DSGM3AB87EM9N0K41AJ/0' as AccountGroupId; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, useParams: () => mockUseParams(), })); diff --git a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx index 1af5beb0244c..30aacc4bd1a3 100644 --- a/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx +++ b/ui/pages/multichain-accounts/multichain-account-private-key-list-page/multichain-account-private-key-list-page.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { Box, BoxFlexDirection, diff --git a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx index 202066ffa64e..95ba0f3157b7 100644 --- a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx +++ b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.test.tsx @@ -10,8 +10,8 @@ const mockUseParams = jest.fn(); const MOCK_ADDRESS = '0x1234567890abcdef1234567890abcdef12345678'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockNavigate, useParams: () => mockUseParams(), })); diff --git a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx index f9966bf34ec7..b0df1dd79388 100644 --- a/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx +++ b/ui/pages/multichain-accounts/smart-account-page/smart-account-page.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { Box, BoxFlexDirection, @@ -17,18 +17,10 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { SmartContractAccountToggleSection } from '../../../components/multichain-accounts/smart-contract-account-toggle-section'; import { PREVIOUS_ROUTE } from '../../../helpers/constants/routes'; -type SmartAccountPageProps = { - params?: { address: string }; -}; - -export const SmartAccountPage = ({ - params: propsParams, -}: SmartAccountPageProps = {}) => { +export const SmartAccountPage = () => { const t = useI18nContext(); const navigate = useNavigate(); - const hookParams = useParams<{ address: string }>(); - - const { address } = propsParams || hookParams; + const { address } = useParams<{ address: string }>(); const decodedAddress = address ? decodeURIComponent(address) : null; diff --git a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx index c3d26059ddf8..c3cceb50ea48 100644 --- a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx +++ b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.test.tsx @@ -12,9 +12,9 @@ const mockUseParams = jest.fn().mockImplementation(() => ({ })); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useParams: () => mockUseParams(), }; diff --git a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx index ab4b3e06800f..e5652ebf2b0d 100644 --- a/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx +++ b/ui/pages/multichain-accounts/wallet-details-page/wallet-details-page.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useMemo } from 'react'; -import { useNavigate, useParams } from 'react-router-dom-v5-compat'; +import { useNavigate, useParams } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { AccountGroupId, diff --git a/ui/pages/nonevm-balance-check/index.tsx b/ui/pages/nonevm-balance-check/index.tsx index 27d5454afb55..996b65c58fb7 100644 --- a/ui/pages/nonevm-balance-check/index.tsx +++ b/ui/pages/nonevm-balance-check/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { CaipChainId } from '@metamask/utils'; import { InternalAccount } from '@metamask/keyring-internal-api'; -import type { Location as HistoryLocation } from 'history'; +import { useLocation } from 'react-router-dom'; import { Box, Modal, @@ -65,12 +65,9 @@ const getBuyUrl = ( return buyUrl.toString(); }; -type NonEvmBalanceCheckProps = { - location: HistoryLocation; -}; - -export const NonEvmBalanceCheck = ({ location }: NonEvmBalanceCheckProps) => { +export const NonEvmBalanceCheck = () => { const dispatch = useDispatch(); + const location = useLocation(); const metaMetricsId = useSelector(getMetaMetricsId); const isMetaMetricsEnabled = useSelector(getParticipateInMetaMetrics); const isMarketingEnabled = useSelector(getDataCollectionForMarketing); diff --git a/ui/pages/notification-details/notification-details.tsx b/ui/pages/notification-details/notification-details.tsx index 8f108ae74a0c..3ba9d90ceb29 100644 --- a/ui/pages/notification-details/notification-details.tsx +++ b/ui/pages/notification-details/notification-details.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { TRIGGER_TYPES, type INotification, @@ -26,10 +26,9 @@ import { NotificationDetailsHeader } from './notification-details-header/notific import { NotificationDetailsBody } from './notification-details-body/notification-details-body'; import { NotificationDetailsFooter } from './notification-details-footer/notification-details-footer'; -function useNotificationByPath(propsParams?: { uuid: string }) { +function useNotificationByPath() { const { pathname } = useLocation(); - // If params are provided as props, use them; otherwise extract from pathname - const id = propsParams?.uuid || getExtractIdentifier(pathname); + const id = getExtractIdentifier(pathname); const notification = useSelector(getMetamaskNotificationById(id)); return { @@ -60,25 +59,11 @@ function useEffectOnNotificationView(notificationData?: INotification) { }, []); } -type NotificationDetailsProps = { - params?: { uuid: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; -}; - // TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 // eslint-disable-next-line @typescript-eslint/naming-convention -export default function NotificationDetails({ - params, - navigate: navigateProp, -}: NotificationDetailsProps = {}) { - const navigateHook = useNavigate(); - const navigate = (navigateProp || navigateHook) as NonNullable< - typeof navigateProp - >; - const { notification } = useNotificationByPath(params); +export default function NotificationDetails() { + const navigate = useNavigate(); + const { notification } = useNotificationByPath(); useEffectOnNotificationView(notification); // No Notification diff --git a/ui/pages/notifications-settings/notifications-settings.tsx b/ui/pages/notifications-settings/notifications-settings.tsx index 79ba1a4221c1..b2205a921b4c 100644 --- a/ui/pages/notifications-settings/notifications-settings.tsx +++ b/ui/pages/notifications-settings/notifications-settings.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useI18nContext } from '../../hooks/useI18nContext'; import { NOTIFICATIONS_ROUTE, diff --git a/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx b/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx index 412b8046165c..d4ad28822d2a 100644 --- a/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx +++ b/ui/pages/notifications/notification-components/snap/snap-footer-button.test.tsx @@ -2,16 +2,16 @@ import React from 'react'; import { processNotification } from '@metamask/notification-services-controller/notification-services'; import { fireEvent, waitFor } from '@testing-library/react'; import { createMockSnapNotification } from '@metamask/notification-services-controller/notification-services/mocks'; -import { renderWithProvider } from '../../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes'; import { SnapFooterButton } from './snap-footer-button'; import { DetailedViewData, SnapNotification } from './types'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); @@ -80,8 +80,8 @@ describe('SnapFooterButton', () => { // Confirm Leave await waitFor(() => { - const leaveModalTitle = getByText('[leaveMetaMask]'); - const leaveModalButton = getByText('[visitSite]'); + const leaveModalTitle = getByText('Leave MetaMask?'); + const leaveModalButton = getByText('Visit site'); expect(leaveModalTitle).toBeInTheDocument(); expect(leaveModalButton).toBeInTheDocument(); }); diff --git a/ui/pages/notifications/notification-components/snap/snap.tsx b/ui/pages/notifications/notification-components/snap/snap.tsx index 9cf50bc5c26d..d37462b9697f 100644 --- a/ui/pages/notifications/notification-components/snap/snap.tsx +++ b/ui/pages/notifications/notification-components/snap/snap.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { TRIGGER_TYPES } from '@metamask/notification-services-controller/notification-services'; import { NotificationDetailTitle, diff --git a/ui/pages/notifications/notifications-list-item.tsx b/ui/pages/notifications/notifications-list-item.tsx index 9a2d8fc48e30..169aea12da7c 100644 --- a/ui/pages/notifications/notifications-list-item.tsx +++ b/ui/pages/notifications/notifications-list-item.tsx @@ -1,5 +1,5 @@ import React, { useContext, useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { hasProperty } from '@metamask/utils'; import type { INotification } from '@metamask/notification-services-controller/notification-services'; import { MetaMetricsContext } from '../../contexts/metametrics'; diff --git a/ui/pages/notifications/notifications.tsx b/ui/pages/notifications/notifications.tsx index 8d0ad050e441..db1bf47f606c 100644 --- a/ui/pages/notifications/notifications.tsx +++ b/ui/pages/notifications/notifications.tsx @@ -1,6 +1,6 @@ import React, { useState, useMemo, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { type INotification, TRIGGER_TYPES, diff --git a/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx b/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx index 159c8d6d6ace..d304f710a794 100644 --- a/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx +++ b/ui/pages/onboarding-flow/account-exist/account-exist.test.tsx @@ -14,9 +14,9 @@ import AccountExist from './account-exist'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/account-exist/account-exist.tsx b/ui/pages/onboarding-flow/account-exist/account-exist.tsx index 2bf6d58c22f8..cb14fdc23507 100644 --- a/ui/pages/onboarding-flow/account-exist/account-exist.tsx +++ b/ui/pages/onboarding-flow/account-exist/account-exist.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useContext } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Button, diff --git a/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx b/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx index d792d5024388..72268ec44ad6 100644 --- a/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx +++ b/ui/pages/onboarding-flow/account-not-found/account-not-found.test.tsx @@ -14,9 +14,9 @@ import AccountNotFound from './account-not-found'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx b/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx index 62364e8b055f..a4bc0115480c 100644 --- a/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx +++ b/ui/pages/onboarding-flow/account-not-found/account-not-found.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useContext } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Button, diff --git a/ui/pages/onboarding-flow/create-password/create-password.test.tsx b/ui/pages/onboarding-flow/create-password/create-password.test.tsx index 61079d9fd768..dc9b8ad57724 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.test.tsx +++ b/ui/pages/onboarding-flow/create-password/create-password.test.tsx @@ -16,9 +16,9 @@ import CreatePassword from './create-password'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/create-password/create-password.tsx b/ui/pages/onboarding-flow/create-password/create-password.tsx index b1714fc61bd7..4ed594ea6d7c 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.tsx +++ b/ui/pages/onboarding-flow/create-password/create-password.tsx @@ -1,5 +1,5 @@ import React, { useState, useContext, useEffect, useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx index c0409f381896..3785aeab6098 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.test.tsx @@ -12,9 +12,9 @@ import CreationSuccessful from './creation-successful'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ search: '' }), }; diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx b/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx index 70d7b2ceb366..99ff452c5796 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useContext } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import browser from 'webextension-polyfill'; import { diff --git a/ui/pages/onboarding-flow/download-app/download-app.test.tsx b/ui/pages/onboarding-flow/download-app/download-app.test.tsx index c909b96423e6..5eeb83bede95 100644 --- a/ui/pages/onboarding-flow/download-app/download-app.test.tsx +++ b/ui/pages/onboarding-flow/download-app/download-app.test.tsx @@ -12,9 +12,9 @@ import DownloadApp from './download-app'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/download-app/download-app.tsx b/ui/pages/onboarding-flow/download-app/download-app.tsx index 441d90e49fb9..e922f22dd7c9 100644 --- a/ui/pages/onboarding-flow/download-app/download-app.tsx +++ b/ui/pages/onboarding-flow/download-app/download-app.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx b/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx index 76fce9d7983b..753d32151ba5 100644 --- a/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx +++ b/ui/pages/onboarding-flow/import-srp/import-srp.test.tsx @@ -14,9 +14,9 @@ import ImportSrp from './import-srp'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/import-srp/import-srp.tsx b/ui/pages/onboarding-flow/import-srp/import-srp.tsx index 8459358b5262..87ea5445c66e 100644 --- a/ui/pages/onboarding-flow/import-srp/import-srp.tsx +++ b/ui/pages/onboarding-flow/import-srp/import-srp.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useContext, useCallback } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { isValidMnemonic } from '@ethersproject/hdnode'; import { diff --git a/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx b/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx index 70531915f436..5994202bc99f 100644 --- a/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx +++ b/ui/pages/onboarding-flow/metametrics/metametrics.test.tsx @@ -21,9 +21,9 @@ import OnboardingMetametrics from './metametrics'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: jest.fn(() => ({ search: '' })), }; diff --git a/ui/pages/onboarding-flow/metametrics/metametrics.tsx b/ui/pages/onboarding-flow/metametrics/metametrics.tsx index 67f2e7e6a467..90ea8e5b28bf 100644 --- a/ui/pages/onboarding-flow/metametrics/metametrics.tsx +++ b/ui/pages/onboarding-flow/metametrics/metametrics.tsx @@ -1,6 +1,6 @@ import React, { useContext, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import log from 'loglevel'; import { diff --git a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx index f3de687426bf..c42a26b5995c 100644 --- a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx +++ b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.test.tsx @@ -2,7 +2,7 @@ import { fireEvent } from '@testing-library/react'; import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; -import type { Location as RouterLocation } from 'react-router-dom-v5-compat'; +import type { Location as RouterLocation } from 'react-router-dom'; import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { ONBOARDING_COMPLETION_ROUTE } from '../../../helpers/constants/routes'; import OnboardingAppHeader from './onboarding-app-header'; diff --git a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx index 77ab28f9682f..45e514c2bc47 100644 --- a/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx +++ b/ui/pages/onboarding-flow/onboarding-app-header/onboarding-app-header.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import type { Location as RouterLocation } from 'react-router-dom-v5-compat'; +import type { Location as RouterLocation } from 'react-router-dom'; import classnames from 'classnames'; import MetaFoxLogo from '../../../components/ui/metafox-logo'; import { useI18nContext } from '../../../hooks/useI18nContext'; diff --git a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx index 8459e97fe15b..9ff9c75d0df6 100644 --- a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx +++ b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import PropTypes from 'prop-types'; -import { useLocation } from 'react-router-dom-v5-compat'; +import { useLocation } from 'react-router-dom'; import { DEFAULT_ROUTE, ONBOARDING_COMPLETION_ROUTE, diff --git a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx index 650a95cf00af..b1115debdeba 100644 --- a/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx +++ b/ui/pages/onboarding-flow/onboarding-flow-switch/onboarding-flow-switch.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate } from 'react-router-dom'; import { DEFAULT_ROUTE, ONBOARDING_COMPLETION_ROUTE, diff --git a/ui/pages/onboarding-flow/onboarding-flow.test.tsx b/ui/pages/onboarding-flow/onboarding-flow.test.tsx index 8624a6d37ff5..e079c7c80fa8 100644 --- a/ui/pages/onboarding-flow/onboarding-flow.test.tsx +++ b/ui/pages/onboarding-flow/onboarding-flow.test.tsx @@ -2,6 +2,7 @@ import { fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; +import { Routes, Route } from 'react-router-dom'; import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { ONBOARDING_EXPERIMENTAL_AREA, @@ -28,14 +29,20 @@ import { FirstTimeFlowType } from '../../../shared/constants/onboarding'; import OnboardingFlow from './onboarding-flow'; const mockUseNavigate = jest.fn(); -const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, - useLocation: () => mockUseLocation(), })); +// Wrapper component that provides proper route context for nested Routes +// OnboardingFlow uses relative paths expecting to be mounted at /onboarding/* +const OnboardingFlowWithRouteContext = () => ( + + } /> + +); + // Mock Rive animation components jest.mock('./welcome/fox-appear-animation', () => ({ // eslint-disable-next-line @typescript-eslint/naming-convention @@ -127,16 +134,6 @@ describe('Onboarding Flow', () => { const store = configureMockStore([thunk])(mockState); - beforeEach(() => { - mockUseLocation.mockReturnValue({ - key: 'test-key', - pathname: ONBOARDING_ROUTE, - search: '', - hash: '', - state: null, - }); - }); - afterEach(() => { jest.resetAllMocks(); }); @@ -173,7 +170,11 @@ describe('Onboarding Flow', () => { completedOnboardingState, ); - renderWithProvider(, completedOnboardingStore, '/other'); + renderWithProvider( + , + completedOnboardingStore, + ONBOARDING_ROUTE, + ); expect(mockUseNavigate).toHaveBeenCalledWith(DEFAULT_ROUTE); }); @@ -181,7 +182,7 @@ describe('Onboarding Flow', () => { describe('Create Password', () => { it('should render create password', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_CREATE_PASSWORD_ROUTE, ); @@ -192,7 +193,7 @@ describe('Onboarding Flow', () => { it('should call createNewVaultAndGetSeedPhrase when creating a new wallet password', async () => { const { queryByTestId, queryByText } = renderWithProvider( - , + , configureMockStore([thunk])({ ...mockState, metamask: { @@ -228,7 +229,11 @@ describe('Onboarding Flow', () => { }); it('should redirect to reveal recovery phrase when going to review recovery phrase without srp', () => { - renderWithProvider(, store, ONBOARDING_REVIEW_SRP_ROUTE); + renderWithProvider( + , + store, + ONBOARDING_REVIEW_SRP_ROUTE, + ); expect(mockUseNavigate).toHaveBeenCalledWith( { @@ -240,7 +245,11 @@ describe('Onboarding Flow', () => { }); it('should redirect to reveal recovery phrase when going to confirm recovery phrase without srp', () => { - renderWithProvider(, store, ONBOARDING_CONFIRM_SRP_ROUTE); + renderWithProvider( + , + store, + ONBOARDING_CONFIRM_SRP_ROUTE, + ); expect(mockUseNavigate).toHaveBeenCalledWith( `${ONBOARDING_REVEAL_SRP_ROUTE}`, @@ -250,7 +259,7 @@ describe('Onboarding Flow', () => { it('should render import seed phrase', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_IMPORT_WITH_SRP_ROUTE, ); @@ -262,7 +271,7 @@ describe('Onboarding Flow', () => { describe('Unlock Screen', () => { it('should render unlock page', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_UNLOCK_ROUTE, ); @@ -273,7 +282,7 @@ describe('Onboarding Flow', () => { it('should call unlockAndGetSeedPhrase when unlocking with a password', async () => { const { getByLabelText, getByText } = renderWithProvider( - , + , configureMockStore([thunk])({ ...mockState, metamask: { @@ -296,7 +305,7 @@ describe('Onboarding Flow', () => { it('should render privacy settings', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_PRIVACY_SETTINGS_ROUTE, ); @@ -307,7 +316,7 @@ describe('Onboarding Flow', () => { it('should render onboarding creation/completion successful', async () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_COMPLETION_ROUTE, ); @@ -319,15 +328,8 @@ describe('Onboarding Flow', () => { }); it('should render onboarding Login page screen', async () => { - mockUseLocation.mockReturnValue({ - key: 'test-key', - pathname: ONBOARDING_WELCOME_ROUTE, - search: '', - hash: '', - state: null, - }); const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_WELCOME_ROUTE, ); @@ -335,13 +337,11 @@ describe('Onboarding Flow', () => { await waitFor(() => { expect(queryByTestId('get-started')).toBeInTheDocument(); }); - - jest.clearAllMocks(); }); it('should render onboarding metametrics screen', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_METAMETRICS, ); @@ -352,7 +352,7 @@ describe('Onboarding Flow', () => { it('should render onboarding experimental screen', () => { const { queryByTestId } = renderWithProvider( - , + , store, ONBOARDING_EXPERIMENTAL_AREA, ); diff --git a/ui/pages/onboarding-flow/onboarding-flow.tsx b/ui/pages/onboarding-flow/onboarding-flow.tsx index 1a5c0bd13371..c2ae47ef65b7 100644 --- a/ui/pages/onboarding-flow/onboarding-flow.tsx +++ b/ui/pages/onboarding-flow/onboarding-flow.tsx @@ -1,12 +1,5 @@ import React, { useEffect, useState, useContext, useMemo } from 'react'; -import { - Routes as Switch, - Route, - useNavigate, - useLocation, - type NavigateFunction, - type Location as RouterLocation, -} from 'react-router-dom-v5-compat'; +import { Routes, Route, useNavigate, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import classnames from 'classnames'; import Unlock from '../unlock-page'; @@ -20,6 +13,7 @@ import { ONBOARDING_UNLOCK_ROUTE, ONBOARDING_WELCOME_ROUTE, DEFAULT_ROUTE, + ONBOARDING_ROUTE, ONBOARDING_PRIVACY_SETTINGS_ROUTE, ONBOARDING_COMPLETION_ROUTE, ONBOARDING_IMPORT_WITH_SRP_ROUTE, @@ -31,6 +25,7 @@ import { ONBOARDING_REVEAL_SRP_ROUTE, ONBOARDING_DOWNLOAD_APP_ROUTE, } from '../../helpers/constants/routes'; +import { toRelativeRoutePath } from '../routes/utils'; import { getCompletedOnboarding, getIsPrimarySeedPhraseBackedUp, @@ -90,27 +85,18 @@ import AccountNotFound from './account-not-found/account-not-found'; import RevealRecoveryPhrase from './recovery-phrase/reveal-recovery-phrase'; import OnboardingDownloadApp from './download-app/download-app'; -type OnboardingFlowProps = { - navigate?: NavigateFunction; - location?: RouterLocation; -}; +// Helper to convert onboarding paths to relative paths for nested route matching +const toRelativePath = (path: string) => + toRelativeRoutePath(path, ONBOARDING_ROUTE); -// TODO: Fix in https://github.com/MetaMask/metamask-extension/issues/31860 // eslint-disable-next-line @typescript-eslint/naming-convention -export default function OnboardingFlow({ - navigate: navigateProp, - location: locationProp, -}: OnboardingFlowProps) { +export default function OnboardingFlow() { const [secretRecoveryPhrase, setSecretRecoveryPhrase] = useState(''); const [isLoading, setIsLoading] = useState(false); const dispatch = useDispatch(); - const hookLocation = useLocation(); - const hookNavigate = useNavigate(); - - // Use passed props if they exist, otherwise fall back to hooks - const location = locationProp ?? hookLocation; - const navigate = navigateProp ?? hookNavigate; + const location = useLocation(); const { pathname, search } = location; + const navigate = useNavigate(); const completedOnboarding: boolean = useSelector(getCompletedOnboarding); const openedWithSidepanel = useSelector(getOpenedWithSidepanel); const nextRoute = useSelector(getFirstTimeFlowTypeRouteAfterUnlock); @@ -303,14 +289,17 @@ export default function OnboardingFlow({ marginInline="auto" borderColor={BorderColor.borderMuted} > - - } /> + + } + /> } /> } /> - } + path={toRelativePath(ONBOARDING_UNLOCK_ROUTE)} + element={} /> } /> } /> } /> } /> } /> } /> { ///: BEGIN:ONLY_INCLUDE_IF(build-flask) } } /> { ///: END:ONLY_INCLUDE_IF } } /> - + {isLoading && } diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.js index 16902cfaed45..95c8c60b73f0 100644 --- a/ui/pages/onboarding-flow/pin-extension/pin-extension.js +++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.js @@ -1,5 +1,5 @@ import React, { useState, useContext, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import { Carousel } from 'react-responsive-carousel'; import classnames from 'classnames'; diff --git a/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js index e26e401a39cd..ff8d1794f73f 100644 --- a/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js +++ b/ui/pages/onboarding-flow/pin-extension/pin-extension.test.js @@ -32,9 +32,9 @@ jest.mock('react-redux', () => ({ const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx index 0d140747a65c..5c0a34435050 100644 --- a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx +++ b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.tsx @@ -1,6 +1,6 @@ import React, { useContext, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import classnames from 'classnames'; import log from 'loglevel'; // TODO: Remove restricted import diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx index 4014e01146ec..9400f78646f6 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx +++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.test.tsx @@ -21,9 +21,9 @@ jest.mock('../../../store/actions.ts', () => ({ const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx index 56b82e34c3c2..13eaa9046118 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx +++ b/ui/pages/onboarding-flow/recovery-phrase/confirm-recovery-phrase.tsx @@ -5,7 +5,7 @@ import React, { useMemo, useState, } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { diff --git a/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx index 4128d24e089c..6a3e9a71fa78 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx +++ b/ui/pages/onboarding-flow/recovery-phrase/reveal-recovery-phrase.tsx @@ -1,5 +1,5 @@ import React, { FormEvent, useCallback, useState } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { Text, diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx index 7d7560b755bf..8c5c2001fa42 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx +++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.test.tsx @@ -11,9 +11,9 @@ import RecoveryPhrase from './review-recovery-phrase'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx index 797be07d3c47..7625479cc5b1 100644 --- a/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx +++ b/ui/pages/onboarding-flow/recovery-phrase/review-recovery-phrase.tsx @@ -1,5 +1,5 @@ import React, { useState, useContext, useCallback, useEffect } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { useI18nContext } from '../../../hooks/useI18nContext'; diff --git a/ui/pages/onboarding-flow/welcome/welcome-login.tsx b/ui/pages/onboarding-flow/welcome/welcome-login.tsx index b287e5070201..ca201d1d3e0a 100644 --- a/ui/pages/onboarding-flow/welcome/welcome-login.tsx +++ b/ui/pages/onboarding-flow/welcome/welcome-login.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { useSearchParams, useNavigate } from 'react-router-dom-v5-compat'; +import { useSearchParams, useNavigate } from 'react-router-dom'; import { Box, Button, diff --git a/ui/pages/onboarding-flow/welcome/welcome.test.tsx b/ui/pages/onboarding-flow/welcome/welcome.test.tsx index 3a2d42c2c486..dd1e04a0e9de 100644 --- a/ui/pages/onboarding-flow/welcome/welcome.test.tsx +++ b/ui/pages/onboarding-flow/welcome/welcome.test.tsx @@ -18,9 +18,9 @@ import Welcome from './welcome'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/onboarding-flow/welcome/welcome.tsx b/ui/pages/onboarding-flow/welcome/welcome.tsx index a0bbb3c1e7e4..29d0758d6497 100644 --- a/ui/pages/onboarding-flow/welcome/welcome.tsx +++ b/ui/pages/onboarding-flow/welcome/welcome.tsx @@ -8,7 +8,7 @@ import React, { type ComponentType, } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box } from '../../../components/component-library'; import { ONBOARDING_COMPLETION_ROUTE, diff --git a/ui/pages/permissions-connect/index.js b/ui/pages/permissions-connect/index.js index 263242e1a869..4f5c6c661105 100644 --- a/ui/pages/permissions-connect/index.js +++ b/ui/pages/permissions-connect/index.js @@ -1 +1 @@ -export { default } from './permissions-connect.container'; +export { default } from './permissions-connect'; diff --git a/ui/pages/permissions-connect/permissions-connect.component.js b/ui/pages/permissions-connect/permissions-connect.component.js deleted file mode 100644 index 75103cc0ab1d..000000000000 --- a/ui/pages/permissions-connect/permissions-connect.component.js +++ /dev/null @@ -1,620 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { Routes, Route } from 'react-router-dom-v5-compat'; -import { providerErrors, serializeError } from '@metamask/rpc-errors'; -import { SubjectType } from '@metamask/permission-controller'; -import { isSnapId } from '@metamask/snaps-utils'; -import { - getAllNamespacesFromCaip25CaveatValue, - getAllScopesFromCaip25CaveatValue, - getEthAccounts, - getPermittedEthChainIds, -} from '@metamask/chain-agnostic-permission'; -import { - KnownCaipNamespace, - parseCaipAccountId, - parseCaipChainId, -} from '@metamask/utils'; -import { getRelativeLocationForNestedRoutes } from '../routes/utils'; -// TODO: Remove restricted import -// eslint-disable-next-line import/no-restricted-paths -import { isEthAddress } from '../../../app/scripts/lib/multichain/address'; -import { MILLISECOND } from '../../../shared/constants/time'; -import { - DEFAULT_ROUTE, - CONNECT_CONFIRM_PERMISSIONS_ROUTE, - CONNECT_SNAPS_CONNECT_ROUTE, - CONNECT_SNAP_INSTALL_ROUTE, - CONNECT_SNAP_UPDATE_ROUTE, - CONNECT_SNAP_RESULT_ROUTE, -} from '../../helpers/constants/routes'; -import PermissionPageContainer from '../../components/app/permission-page-container'; -import { Box } from '../../components/component-library'; -import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header/snap-authorship-header'; -import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper'; -import { MultichainAccountsConnectPage } from '../multichain-accounts/multichain-accounts-connect-page/multichain-accounts-connect-page'; -import { supportsChainIds } from '../../hooks/useAccountGroupsForPermissions'; -import { getCaip25AccountIdsFromAccountGroupAndScope } from '../../../shared/lib/multichain/scope-utils'; -import { MultichainEditAccountsPageWrapper } from '../../components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper'; -import ChooseAccount from './choose-account'; -import PermissionsRedirect from './redirect'; -import SnapsConnect from './snaps/snaps-connect'; -import SnapInstall from './snaps/snap-install'; -import SnapUpdate from './snaps/snap-update'; -import SnapResult from './snaps/snap-result'; -import { ConnectPage } from './connect-page/connect-page'; -import { getCaip25CaveatValueFromPermissions } from './connect-page/utils'; - -const APPROVE_TIMEOUT = MILLISECOND * 1200; - -function getDefaultSelectedAccounts(currentAddress, permissions) { - const requestedCaip25CaveatValue = - getCaip25CaveatValueFromPermissions(permissions); - const requestedAccounts = getEthAccounts(requestedCaip25CaveatValue); - - if (requestedAccounts.length > 0) { - return new Set( - requestedAccounts - .map((address) => address.toLowerCase()) - // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`) - .filter(isEthAddress), - ); - } - - // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`) - return new Set(isEthAddress(currentAddress) ? [currentAddress] : []); -} - -function getRequestedChainIds(permissions) { - const requestedCaip25CaveatValue = - getCaip25CaveatValueFromPermissions(permissions); - return getPermittedEthChainIds(requestedCaip25CaveatValue); -} - -export default class PermissionConnect extends Component { - static propTypes = { - approvePermissionsRequest: PropTypes.func.isRequired, - rejectPermissionsRequest: PropTypes.func.isRequired, - getRequestAccountTabIds: PropTypes.func.isRequired, - accounts: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - address: PropTypes.string.isRequired, - metadata: PropTypes.shape({ - name: PropTypes.string.isRequired, - snap: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string, - enabled: PropTypes.bool, - }), - keyring: PropTypes.shape({ - type: PropTypes.string.isRequired, - }).isRequired, - }).isRequired, - addressLabel: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - balance: PropTypes.string.isRequired, - }), - ).isRequired, - accountGroups: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - accounts: PropTypes.arrayOf(PropTypes.object.isRequired), - }), - ).isRequired, - currentAddress: PropTypes.string.isRequired, - origin: PropTypes.string, - showNewAccountModal: PropTypes.func.isRequired, - newAccountNumber: PropTypes.number.isRequired, - nativeCurrency: PropTypes.string, - permissionsRequest: PropTypes.object, - addressLastConnectedMap: PropTypes.object.isRequired, - lastConnectedInfo: PropTypes.object.isRequired, - permissionsRequestId: PropTypes.string, - navigate: PropTypes.func.isRequired, - location: PropTypes.object.isRequired, - connectPath: PropTypes.string.isRequired, - confirmPermissionPath: PropTypes.string.isRequired, - requestType: PropTypes.string.isRequired, - snapsConnectPath: PropTypes.string.isRequired, - snapInstallPath: PropTypes.string.isRequired, - snapUpdatePath: PropTypes.string.isRequired, - snapResultPath: PropTypes.string.isRequired, - requestState: PropTypes.object.isRequired, - approvePendingApproval: PropTypes.func.isRequired, - rejectPendingApproval: PropTypes.func.isRequired, - setSnapsInstallPrivacyWarningShownStatus: PropTypes.func.isRequired, - snapsInstallPrivacyWarningShown: PropTypes.bool.isRequired, - hideTopBar: PropTypes.bool, - targetSubjectMetadata: PropTypes.shape({ - extensionId: PropTypes.string, - iconUrl: PropTypes.string, - name: PropTypes.string, - origin: PropTypes.string, - subjectType: PropTypes.string, - }), - isRequestingAccounts: PropTypes.bool.isRequired, - }; - - static defaultProps = { - origin: '', - nativeCurrency: '', - permissionsRequest: undefined, - permissionsRequestId: '', - }; - - static contextTypes = { - t: PropTypes.func, - }; - - state = { - redirecting: false, - selectedAccountAddresses: getDefaultSelectedAccounts( - this.props.currentAddress, - this.props.permissionsRequest?.permissions, - ), - permissionsApproved: null, - origin: this.props.origin, - targetSubjectMetadata: this.props.targetSubjectMetadata || {}, - snapsInstallPrivacyWarningShown: this.props.snapsInstallPrivacyWarningShown, - }; - - componentDidMount() { - const { - connectPath, - confirmPermissionPath, - snapsConnectPath, - snapInstallPath, - snapUpdatePath, - snapResultPath, - requestType, - getRequestAccountTabIds, - permissionsRequest, - navigate, - location, - isRequestingAccounts, - } = this.props; - getRequestAccountTabIds(); - - if (!permissionsRequest) { - navigate(DEFAULT_ROUTE, { replace: true }); - return; - } - if (location.pathname === connectPath && !isRequestingAccounts) { - switch (requestType) { - case 'wallet_installSnap': - navigate(snapInstallPath, { replace: true }); - break; - case 'wallet_updateSnap': - navigate(snapUpdatePath, { replace: true }); - break; - case 'wallet_installSnapResult': - navigate(snapResultPath, { replace: true }); - break; - case 'wallet_connectSnaps': - navigate(snapsConnectPath, { replace: true }); - break; - default: - navigate(confirmPermissionPath, { replace: true }); - } - } - } - - componentDidUpdate(prevProps) { - const { permissionsRequest, lastConnectedInfo, targetSubjectMetadata } = - this.props; - const { redirecting, origin } = this.state; - - // We cache the last known good targetSubjectMetadata since it may be null when the approval is cleared - if ( - targetSubjectMetadata?.origin && - prevProps.targetSubjectMetadata?.origin !== targetSubjectMetadata?.origin - ) { - this.setState({ targetSubjectMetadata }); - } - - if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) { - const accountsLastApprovedTime = - lastConnectedInfo[origin]?.lastApproved || 0; - const initialAccountsLastApprovedTime = - prevProps.lastConnectedInfo[origin]?.lastApproved || 0; - - const approved = - accountsLastApprovedTime > initialAccountsLastApprovedTime; - this.redirect(approved); - } - } - - selectAccounts = (addresses) => { - const { - confirmPermissionPath, - requestType, - snapsConnectPath, - snapInstallPath, - snapUpdatePath, - snapResultPath, - navigate, - } = this.props; - this.setState( - { - selectedAccountAddresses: addresses, - }, - () => { - switch (requestType) { - case 'wallet_installSnap': - navigate(snapInstallPath); - break; - case 'wallet_updateSnap': - navigate(snapUpdatePath); - break; - case 'wallet_installSnapResult': - navigate(snapResultPath); - break; - case 'wallet_connectSnaps': - navigate(snapsConnectPath, { replace: true }); - break; - default: - navigate(confirmPermissionPath); - } - }, - ); - }; - - redirect(approved) { - const { navigate, permissionsRequest } = this.props; - - let shouldRedirect = true; - - const isRequestingSnap = - permissionsRequest?.permissions && - Object.keys(permissionsRequest.permissions).includes('wallet_snap'); - - shouldRedirect = !isRequestingSnap; - - this.setState({ - redirecting: shouldRedirect, - permissionsApproved: approved, - }); - - if (shouldRedirect && approved) { - setTimeout(() => navigate(DEFAULT_ROUTE), APPROVE_TIMEOUT); - return; - } - navigate(DEFAULT_ROUTE); - } - - cancelPermissionsRequest = async (requestId) => { - const { rejectPermissionsRequest } = this.props; - - if (requestId) { - await rejectPermissionsRequest(requestId); - this.redirect(false); - } - }; - - goBack() { - const { navigate, connectPath } = this.props; - navigate(connectPath); - } - - renderSnapChooseAccountState1 = () => { - const { - accounts, - nativeCurrency, - showNewAccountModal, - newAccountNumber, - addressLastConnectedMap, - permissionsRequestId, - targetSubjectMetadata, - } = this.props; - const { selectedAccountAddresses } = this.state; - - return ( - this.selectAccounts(addresses)} - selectNewAccountViaModal={(handleAccountClick) => { - showNewAccountModal({ - onCreateNewAccount: (address) => handleAccountClick(address), - newAccountNumber, - }); - }} - addressLastConnectedMap={addressLastConnectedMap} - cancelPermissionsRequest={(requestId) => - this.cancelPermissionsRequest(requestId) - } - permissionsRequestId={permissionsRequestId} - selectedAccountAddresses={selectedAccountAddresses} - targetSubjectMetadata={targetSubjectMetadata} - /> - ); - }; - - renderSnapChooseAccountState2 = () => { - const { permissionsRequestId, accountGroups, permissionsRequest } = - this.props; - const { t } = this.context; - const requestedCaip25CaveatValue = getCaip25CaveatValueFromPermissions( - permissionsRequest?.permissions, - ); - - const caipChainIdsToUse = []; - - const requestedCaipChainIds = getAllScopesFromCaip25CaveatValue( - requestedCaip25CaveatValue, - ).filter((chainId) => { - const { namespace } = parseCaipChainId(chainId); - return namespace !== KnownCaipNamespace.Wallet; - }); - const requestedNamespaces = getAllNamespacesFromCaip25CaveatValue( - requestedCaip25CaveatValue, - ); - - if (requestedCaipChainIds.length > 0) { - requestedCaipChainIds.forEach((chainId) => { - caipChainIdsToUse.push(chainId); - }); - } - - if (requestedNamespaces.includes(KnownCaipNamespace.Eip155)) { - caipChainIdsToUse.push(`${KnownCaipNamespace.Eip155}:0`); - } - - return ( - { - const filteredAccountGroups = accountGroups.filter( - (group) => - accountGroupIds.includes(group.id) && - supportsChainIds(group, caipChainIdsToUse), - ); - const addresses = getCaip25AccountIdsFromAccountGroupAndScope( - filteredAccountGroups, - caipChainIdsToUse, - ).map( - (caip25AccountId) => parseCaipAccountId(caip25AccountId).address, - ); - this.selectAccounts(new Set(addresses)); - }} - onClose={() => this.cancelPermissionsRequest(permissionsRequestId)} - /> - ); - }; - - renderConnectPageState1 = () => { - const connectPageProps = { - rejectPermissionsRequest: (requestId) => - this.cancelPermissionsRequest(requestId), - activeTabOrigin: this.state.origin, - request: this.props.permissionsRequest || {}, - permissionsRequestId: this.props.permissionsRequestId, - approveConnection: this.approveConnection, - targetSubjectMetadata: this.props.targetSubjectMetadata, - }; - - return ; - }; - - renderConnectPageState2 = () => { - const connectPageProps = { - rejectPermissionsRequest: (requestId) => - this.cancelPermissionsRequest(requestId), - activeTabOrigin: this.state.origin, - request: this.props.permissionsRequest || {}, - permissionsRequestId: this.props.permissionsRequestId, - approveConnection: this.approveConnection, - targetSubjectMetadata: this.props.targetSubjectMetadata, - }; - - return ; - }; - - renderTopBar(permissionsRequestId) { - const { targetSubjectMetadata } = this.state; - const handleCancelFromHeader = () => { - this.cancelPermissionsRequest(permissionsRequestId); - }; - return ( - - {targetSubjectMetadata.subjectType === SubjectType.Snap && ( - - )} - - ); - } - - approveConnection = (...args) => { - const { approvePermissionsRequest } = this.props; - approvePermissionsRequest(...args); - this.redirect(true); - }; - - render() { - const { - accounts, - permissionsRequest, - permissionsRequestId, - connectPath, - hideTopBar, - targetSubjectMetadata, - requestState, - approvePendingApproval, - rejectPendingApproval, - setSnapsInstallPrivacyWarningShownStatus, - approvePermissionsRequest, - navigate, - location, - } = this.props; - const { - selectedAccountAddresses, - permissionsApproved, - redirecting, - snapsInstallPrivacyWarningShown, - } = this.state; - - const isRequestingSnap = isSnapId(permissionsRequest?.metadata?.origin); - - // Create a relative location for nested v5-compat Routes - const relativeLocation = getRelativeLocationForNestedRoutes( - location, - connectPath, - ); - - return ( -
- {!hideTopBar && this.renderTopBar(permissionsRequestId)} - {redirecting && permissionsApproved ? ( - - ) : ( - - { - if (isRequestingSnap) { - return ( - - ); - } - return ( - - ); - })()} - /> - { - approvePermissionsRequest(...args); - this.redirect(true); - }} - rejectPermissionsRequest={(requestId) => - this.cancelPermissionsRequest(requestId) - } - selectedAccounts={accounts.filter((account) => - selectedAccountAddresses.has(account.address), - )} - requestedChainIds={getRequestedChainIds( - permissionsRequest?.permissions, - )} - targetSubjectMetadata={targetSubjectMetadata} - navigate={navigate} - connectPath={connectPath} - snapsInstallPrivacyWarningShown={ - snapsInstallPrivacyWarningShown - } - setSnapsInstallPrivacyWarningShownStatus={ - setSnapsInstallPrivacyWarningShownStatus - } - /> - } - /> - - this.cancelPermissionsRequest(requestId) - } - targetSubjectMetadata={targetSubjectMetadata} - snapsInstallPrivacyWarningShown={ - snapsInstallPrivacyWarningShown - } - setSnapsInstallPrivacyWarningShownStatus={ - setSnapsInstallPrivacyWarningShownStatus - } - /> - } - /> - { - approvePendingApproval(requestId, { - ...permissionsRequest, - permissions: requestState.permissions, - approvedAccounts: [...selectedAccountAddresses], - }); - this.setState({ permissionsApproved: true }); - }} - rejectSnapInstall={(requestId) => { - rejectPendingApproval( - requestId, - serializeError(providerErrors.userRejectedRequest()), - ); - this.setState({ permissionsApproved: true }); - }} - targetSubjectMetadata={targetSubjectMetadata} - /> - } - /> - { - approvePendingApproval(requestId, { - ...permissionsRequest, - permissions: requestState.permissions, - approvedAccounts: [...selectedAccountAddresses], - }); - this.setState({ permissionsApproved: true }); - }} - rejectSnapUpdate={(requestId) => { - rejectPendingApproval( - requestId, - serializeError(providerErrors.userRejectedRequest()), - ); - this.setState({ permissionsApproved: false }); - }} - targetSubjectMetadata={targetSubjectMetadata} - /> - } - /> - { - approvePendingApproval(requestId); - this.setState({ permissionsApproved: true }); - }} - targetSubjectMetadata={targetSubjectMetadata} - /> - } - /> - - )} -
- ); - } -} diff --git a/ui/pages/permissions-connect/permissions-connect.container.js b/ui/pages/permissions-connect/permissions-connect.container.js deleted file mode 100644 index e65244439f31..000000000000 --- a/ui/pages/permissions-connect/permissions-connect.container.js +++ /dev/null @@ -1,195 +0,0 @@ -import { SubjectType } from '@metamask/permission-controller'; -import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/snaps-rpc-methods'; -import { connect } from 'react-redux'; -import { isEvmAccountType } from '@metamask/keyring-api'; -import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission'; -import { - getAccountsWithLabels, - getLastConnectedInfo, - getPermissionsRequests, - getSelectedInternalAccount, - getSnapInstallOrUpdateRequests, - getRequestState, - getSnapsInstallPrivacyWarningShown, - getRequestType, - getTargetSubjectMetadata, -} from '../../selectors'; -import { getNativeCurrency } from '../../ducks/metamask/metamask'; - -import { formatDate, getURLHostName } from '../../helpers/utils/util'; -import { - approvePermissionsRequest, - rejectPermissionsRequest, - showModal, - getRequestAccountTabIds, - resolvePendingApproval, - rejectPendingApproval, - setSnapsInstallPrivacyWarningShownStatus, -} from '../../store/actions'; -import { - CONNECT_ROUTE, - CONNECT_CONFIRM_PERMISSIONS_ROUTE, - CONNECT_SNAPS_CONNECT_ROUTE, - CONNECT_SNAP_INSTALL_ROUTE, - CONNECT_SNAP_UPDATE_ROUTE, - CONNECT_SNAP_RESULT_ROUTE, -} from '../../helpers/constants/routes'; -import { getAccountGroupWithInternalAccounts } from '../../selectors/multichain-accounts/account-tree'; -import PermissionApproval from './permissions-connect.component'; - -const mapStateToProps = (state, ownProps) => { - const { - match: { - params: { id: permissionsRequestId }, - }, - location: { pathname }, - } = ownProps; - let permissionsRequests = getPermissionsRequests(state); - permissionsRequests = [ - ...permissionsRequests, - ...getSnapInstallOrUpdateRequests(state), - ]; - const { address: currentAddress } = getSelectedInternalAccount(state); - - const permissionsRequest = permissionsRequests.find( - (req) => req.metadata.id === permissionsRequestId, - ); - - const { metadata = {}, diff = {} } = permissionsRequest || {}; - const { origin } = metadata; - const nativeCurrency = getNativeCurrency(state); - - const isRequestApprovalPermittedChains = Boolean(diff?.permissionDiffMap); - const isRequestingAccounts = Boolean( - permissionsRequest?.permissions?.[Caip25EndowmentPermissionName] && - !isRequestApprovalPermittedChains, - ); - - const targetSubjectMetadata = getTargetSubjectMetadata(state, origin) ?? { - name: getURLHostName(origin) || origin, - origin, - iconUrl: null, - extensionId: null, - subjectType: SubjectType.Unknown, - }; - - let requestType = getRequestType(state, permissionsRequestId); - - // We want to only assign the wallet_connectSnaps request type (i.e. only show - // SnapsConnect) if and only if we get a singular wallet_snap permission request. - // Any other request gets pushed to the normal permission connect flow. - if ( - permissionsRequest && - Object.keys(permissionsRequest.permissions || {}).length === 1 && - permissionsRequest.permissions?.[WALLET_SNAP_PERMISSION_KEY] - ) { - requestType = 'wallet_connectSnaps'; - } - - const requestState = getRequestState(state, permissionsRequestId) || {}; - - // We only consider EVM accounts. - // Connections with non-EVM accounts (Bitcoin only for now) are used implicitly and handled by the Bitcoin Snap itself. - const accountsWithLabels = getAccountsWithLabels(state).filter((account) => - isEvmAccountType(account.type), - ); - - const lastConnectedInfo = getLastConnectedInfo(state) || {}; - const addressLastConnectedMap = lastConnectedInfo[origin]?.accounts || {}; - - Object.keys(addressLastConnectedMap).forEach((key) => { - addressLastConnectedMap[key] = formatDate( - addressLastConnectedMap[key], - 'yyyy-MM-dd', - ); - }); - - const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}`; - const confirmPermissionPath = `${connectPath}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}`; - const snapsConnectPath = `${connectPath}${CONNECT_SNAPS_CONNECT_ROUTE}`; - const snapInstallPath = `${connectPath}${CONNECT_SNAP_INSTALL_ROUTE}`; - const snapUpdatePath = `${connectPath}${CONNECT_SNAP_UPDATE_ROUTE}`; - const snapResultPath = `${connectPath}${CONNECT_SNAP_RESULT_ROUTE}`; - - const isSnapInstallOrUpdateOrResult = - pathname === snapInstallPath || - pathname === snapUpdatePath || - pathname === snapResultPath; - - let totalPages = 1 + isRequestingAccounts; - totalPages += isSnapInstallOrUpdateOrResult; - totalPages = totalPages.toString(); - - let page = ''; - if (pathname === connectPath) { - page = '1'; - } else if (pathname === confirmPermissionPath) { - page = isRequestingAccounts ? '2' : '1'; - } else if (isSnapInstallOrUpdateOrResult) { - page = isRequestingAccounts ? '3' : '2'; - } else if (pathname === snapsConnectPath) { - page = 1; - } else { - throw new Error('Incorrect path for permissions-connect component'); - } - - return { - isRequestingAccounts, - requestType, - snapsConnectPath, - snapInstallPath, - snapUpdatePath, - snapResultPath, - confirmPermissionPath, - requestState, - hideTopBar: isSnapInstallOrUpdateOrResult, - snapsInstallPrivacyWarningShown: getSnapsInstallPrivacyWarningShown(state), - permissionsRequest, - permissionsRequestId, - accounts: accountsWithLabels, - accountGroups: getAccountGroupWithInternalAccounts(state), - currentAddress, - origin, - newAccountNumber: accountsWithLabels.length + 1, - nativeCurrency, - addressLastConnectedMap, - lastConnectedInfo, - connectPath, - totalPages, - page, - targetSubjectMetadata, - }; -}; - -const mapDispatchToProps = (dispatch) => { - return { - approvePermissionsRequest: (request) => - dispatch(approvePermissionsRequest(request)), - rejectPermissionsRequest: (requestId) => - dispatch(rejectPermissionsRequest(requestId)), - approvePendingApproval: (id, value) => - dispatch(resolvePendingApproval(id, value)), - rejectPendingApproval: (id, error) => - dispatch(rejectPendingApproval(id, error)), - setSnapsInstallPrivacyWarningShownStatus: (shown) => { - dispatch(setSnapsInstallPrivacyWarningShownStatus(shown)); - }, - showNewAccountModal: ({ onCreateNewAccount, newAccountNumber }) => { - return dispatch( - showModal({ - name: 'NEW_ACCOUNT', - onCreateNewAccount, - newAccountNumber, - }), - ); - }, - getRequestAccountTabIds: () => dispatch(getRequestAccountTabIds()), - }; -}; - -const PermissionApprovalContainer = connect( - mapStateToProps, - mapDispatchToProps, -)(PermissionApproval); - -export default PermissionApprovalContainer; diff --git a/ui/pages/permissions-connect/permissions-connect.tsx b/ui/pages/permissions-connect/permissions-connect.tsx new file mode 100644 index 000000000000..7e53482418d8 --- /dev/null +++ b/ui/pages/permissions-connect/permissions-connect.tsx @@ -0,0 +1,779 @@ +import React, { + useEffect, + useState, + useCallback, + useRef, + useMemo, +} from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { + useNavigate, + useLocation, + useParams, + Routes, + Route, +} from 'react-router-dom'; +import { providerErrors, serializeError } from '@metamask/rpc-errors'; +import { SubjectType } from '@metamask/permission-controller'; +import { isSnapId } from '@metamask/snaps-utils'; +import { WALLET_SNAP_PERMISSION_KEY } from '@metamask/snaps-rpc-methods'; +import { isEvmAccountType, KeyringAccountType } from '@metamask/keyring-api'; +import { + Caip25EndowmentPermissionName, + getAllNamespacesFromCaip25CaveatValue, + getAllScopesFromCaip25CaveatValue, + getEthAccounts, + getPermittedEthChainIds, +} from '@metamask/chain-agnostic-permission'; +import { + KnownCaipNamespace, + parseCaipAccountId, + parseCaipChainId, +} from '@metamask/utils'; +import { toRelativeRoutePath } from '../routes/utils'; +// TODO: Remove restricted import +// eslint-disable-next-line import/no-restricted-paths +import { isEthAddress } from '../../../app/scripts/lib/multichain/address'; +import { MILLISECOND } from '../../../shared/constants/time'; +import { + DEFAULT_ROUTE, + CONNECT_ROUTE, + CONNECT_CONFIRM_PERMISSIONS_ROUTE, + CONNECT_SNAPS_CONNECT_ROUTE, + CONNECT_SNAP_INSTALL_ROUTE, + CONNECT_SNAP_UPDATE_ROUTE, + CONNECT_SNAP_RESULT_ROUTE, +} from '../../helpers/constants/routes'; +import { + getAccountsWithLabels, + getLastConnectedInfo, + getPermissionsRequests, + getSelectedInternalAccount, + getSnapInstallOrUpdateRequests, + getRequestState, + getSnapsInstallPrivacyWarningShown, + getRequestType, + getTargetSubjectMetadata, +} from '../../selectors'; +import { getNativeCurrency } from '../../ducks/metamask/metamask'; +import { formatDate, getURLHostName } from '../../helpers/utils/util'; +import { + approvePermissionsRequest as approvePermissionsRequestAction, + rejectPermissionsRequest as rejectPermissionsRequestAction, + showModal, + getRequestAccountTabIds as getRequestAccountTabIdsAction, + resolvePendingApproval, + rejectPendingApproval as rejectPendingApprovalAction, + setSnapsInstallPrivacyWarningShownStatus as setSnapsInstallPrivacyWarningShownStatusAction, +} from '../../store/actions'; +import { getAccountGroupWithInternalAccounts } from '../../selectors/multichain-accounts/account-tree'; +import PermissionPageContainer from '../../components/app/permission-page-container'; +import { Box } from '../../components/component-library'; +import SnapAuthorshipHeader from '../../components/app/snaps/snap-authorship-header/snap-authorship-header'; +import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper'; +import { MultichainAccountsConnectPage } from '../multichain-accounts/multichain-accounts-connect-page/multichain-accounts-connect-page'; +import { supportsChainIds } from '../../hooks/useAccountGroupsForPermissions'; +import { getCaip25AccountIdsFromAccountGroupAndScope } from '../../../shared/lib/multichain/scope-utils'; +import { MultichainEditAccountsPageWrapper } from '../../components/multichain-accounts/permissions/multichain-edit-accounts-page/multichain-edit-account-wrapper'; +import { useI18nContext } from '../../hooks/useI18nContext'; +import ChooseAccount from './choose-account'; +import PermissionsRedirect from './redirect'; +import SnapsConnect from './snaps/snaps-connect'; +import SnapInstall from './snaps/snap-install'; +import SnapUpdate from './snaps/snap-update'; +import SnapResult from './snaps/snap-result'; +import { ConnectPage } from './connect-page/connect-page'; +import { + getCaip25CaveatValueFromPermissions, + PermissionsRequest, +} from './connect-page/utils'; + +const APPROVE_TIMEOUT = MILLISECOND * 1200; + +function getDefaultSelectedAccounts( + currentAddress: string, + permissions: PermissionsRequest, +) { + const requestedCaip25CaveatValue = + getCaip25CaveatValueFromPermissions(permissions); + const requestedAccounts = getEthAccounts(requestedCaip25CaveatValue); + + if (requestedAccounts.length > 0) { + return new Set( + requestedAccounts + .map((address) => address.toLowerCase()) + // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`) + .filter(isEthAddress), + ); + } + + // We only consider EVM accounts here (used for `eth_requestAccounts` or `eth_accounts`) + return new Set(isEthAddress(currentAddress) ? [currentAddress] : []); +} + +function getRequestedChainIds(permissions: PermissionsRequest | undefined) { + const requestedCaip25CaveatValue = + getCaip25CaveatValueFromPermissions(permissions); + return getPermittedEthChainIds(requestedCaip25CaveatValue); +} + +// eslint-disable-next-line @typescript-eslint/naming-convention +function PermissionsConnect() { + const dispatch = useDispatch(); + const navigate = useNavigate(); + const location = useLocation(); + const params = useParams(); + const t = useI18nContext(); + + const permissionsRequestId = params.id; + + // Selectors + const { pathname } = location; + let permissionsRequests = useSelector(getPermissionsRequests); + permissionsRequests = [ + ...permissionsRequests, + ...useSelector(getSnapInstallOrUpdateRequests), + ]; + const { address: currentAddress } = useSelector(getSelectedInternalAccount); + + const permissionsRequest = permissionsRequests.find( + (req: Record) => + (req.metadata as Record)?.id === permissionsRequestId, + ) as Record | undefined; + + const { metadata = {}, diff = {} } = permissionsRequest || {}; + const { origin: originFromRequest } = (metadata || {}) as Record< + string, + string + >; + const nativeCurrency = useSelector(getNativeCurrency); + + const isRequestApprovalPermittedChains = Boolean( + (diff as Record)?.permissionDiffMap, + ); + const permissions = permissionsRequest?.permissions as + | Record + | undefined; + const isRequestingAccounts = Boolean( + permissions?.[Caip25EndowmentPermissionName] && + !isRequestApprovalPermittedChains, + ); + + const targetSubjectMetadataFromSelector = useSelector((state) => + getTargetSubjectMetadata(state, originFromRequest), + ); + + const targetSubjectMetadataProp = useMemo( + () => + targetSubjectMetadataFromSelector ?? { + name: getURLHostName(originFromRequest) || originFromRequest, + origin: originFromRequest, + iconUrl: null, + extensionId: null, + subjectType: SubjectType.Unknown, + }, + [targetSubjectMetadataFromSelector, originFromRequest], + ); + + let requestType = useSelector((state) => + getRequestType(state, permissionsRequestId), + ); + + // We want to only assign the wallet_connectSnaps request type (i.e. only show + // SnapsConnect) if and only if we get a singular wallet_snap permission request. + // Any other request gets pushed to the normal permission connect flow. + if ( + permissionsRequest && + Object.keys(permissions || {}).length === 1 && + permissions?.[WALLET_SNAP_PERMISSION_KEY] + ) { + requestType = 'wallet_connectSnaps'; + } + + const requestState = + useSelector((state) => getRequestState(state, permissionsRequestId)) || {}; + + // We only consider EVM accounts. + // Connections with non-EVM accounts (Bitcoin only for now) are used implicitly and handled by the Bitcoin Snap itself. + const accountsWithLabels = useSelector(getAccountsWithLabels).filter( + (account: { type: string }) => + isEvmAccountType(account.type as KeyringAccountType), + ); + + const accountGroups = useSelector(getAccountGroupWithInternalAccounts); + const lastConnectedInfoRaw = useSelector(getLastConnectedInfo); + + const lastConnectedInfo = useMemo( + () => lastConnectedInfoRaw || {}, + [lastConnectedInfoRaw], + ); + + const addressLastConnectedMap = useMemo(() => { + const map = lastConnectedInfo[originFromRequest]?.accounts || {}; + const formattedMap: Record = {}; + Object.keys(map).forEach((key) => { + formattedMap[key] = formatDate(map[key], 'yyyy-MM-dd'); + }); + return formattedMap; + }, [lastConnectedInfo, originFromRequest]); + + const connectPath = `${CONNECT_ROUTE}/${permissionsRequestId}`; + const confirmPermissionPath = `${connectPath}${CONNECT_CONFIRM_PERMISSIONS_ROUTE}`; + const snapsConnectPath = `${connectPath}${CONNECT_SNAPS_CONNECT_ROUTE}`; + const snapInstallPath = `${connectPath}${CONNECT_SNAP_INSTALL_ROUTE}`; + const snapUpdatePath = `${connectPath}${CONNECT_SNAP_UPDATE_ROUTE}`; + const snapResultPath = `${connectPath}${CONNECT_SNAP_RESULT_ROUTE}`; + + const isSnapInstallOrUpdateOrResult = + pathname === snapInstallPath || + pathname === snapUpdatePath || + pathname === snapResultPath; + + const hideTopBar = isSnapInstallOrUpdateOrResult; + const snapsInstallPrivacyWarningShownProp = useSelector( + getSnapsInstallPrivacyWarningShown, + ); + + const newAccountNumber = accountsWithLabels.length + 1; + + // Local state + const [redirecting, setRedirecting] = useState(false); + const [selectedAccountAddresses, setSelectedAccountAddresses] = useState(() => + getDefaultSelectedAccounts( + currentAddress, + permissions as PermissionsRequest, + ), + ); + const [permissionsApproved, setPermissionsApproved] = useState< + boolean | null + >(null); + const [origin] = useState(originFromRequest); + const [targetSubjectMetadata, setTargetSubjectMetadata] = useState( + targetSubjectMetadataProp || {}, + ); + const [snapsInstallPrivacyWarningShown] = useState( + snapsInstallPrivacyWarningShownProp, + ); + + const prevPermissionsRequestRef = useRef( + null, + ); + const prevTargetSubjectMetadataRef = useRef< + typeof targetSubjectMetadataProp | null + >(null); + const prevLastConnectedInfoRef = useRef( + null, + ); + + // Define redirect function before it's used in effects + const redirect = useCallback( + (approved: boolean) => { + let shouldRedirect = true; + + const isRequestingSnap = + permissions && Object.keys(permissions).includes('wallet_snap'); + + shouldRedirect = !isRequestingSnap; + + setRedirecting(shouldRedirect); + setPermissionsApproved(approved); + + // If requesting a snap, don't navigate - wait for the snap install request + if (!shouldRedirect) { + return; + } + + if (approved) { + setTimeout(() => navigate(DEFAULT_ROUTE), APPROVE_TIMEOUT); + return; + } + navigate(DEFAULT_ROUTE); + }, + [permissions, navigate], + ); + + // Handle initial navigation on mount + useEffect(() => { + dispatch(getRequestAccountTabIdsAction()); + + if (!permissionsRequest) { + navigate(DEFAULT_ROUTE, { replace: true }); + return; + } + + if (location.pathname === connectPath && !isRequestingAccounts) { + switch (requestType) { + case 'wallet_installSnap': + navigate(snapInstallPath, { replace: true }); + break; + case 'wallet_updateSnap': + navigate(snapUpdatePath, { replace: true }); + break; + case 'wallet_installSnapResult': + navigate(snapResultPath, { replace: true }); + break; + case 'wallet_connectSnaps': + navigate(snapsConnectPath, { replace: true }); + break; + default: + navigate(confirmPermissionPath, { replace: true }); + } + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + // Cache targetSubjectMetadata when it changes + useEffect(() => { + if ( + targetSubjectMetadataProp?.origin && + prevTargetSubjectMetadataRef.current?.origin !== + targetSubjectMetadataProp?.origin + ) { + setTargetSubjectMetadata(targetSubjectMetadataProp); + } + prevTargetSubjectMetadataRef.current = targetSubjectMetadataProp; + }, [targetSubjectMetadataProp]); + + // Handle redirect on permissions approval/rejection + useEffect(() => { + if ( + !permissionsRequest && + prevPermissionsRequestRef.current && + !redirecting + ) { + const lastConnectedForOrigin = lastConnectedInfo[origin] as + | { lastApproved?: number; accounts?: Record } + | undefined; + const prevLastConnectedForOrigin = prevLastConnectedInfoRef.current?.[ + origin + ] as + | { lastApproved?: number; accounts?: Record } + | undefined; + + const accountsLastApprovedTime = + lastConnectedForOrigin?.lastApproved || 0; + const initialAccountsLastApprovedTime = + prevLastConnectedForOrigin?.lastApproved || 0; + + const approved = + accountsLastApprovedTime > initialAccountsLastApprovedTime; + redirect(approved); + } + prevPermissionsRequestRef.current = permissionsRequest; + prevLastConnectedInfoRef.current = lastConnectedInfo; + }, [permissionsRequest, lastConnectedInfo, redirecting, origin, redirect]); + + const selectAccounts = useCallback( + (addresses: Set) => { + setSelectedAccountAddresses(addresses); + // Navigate after state is updated + setTimeout(() => { + switch (requestType) { + case 'wallet_installSnap': + navigate(snapInstallPath); + break; + case 'wallet_updateSnap': + navigate(snapUpdatePath); + break; + case 'wallet_installSnapResult': + navigate(snapResultPath); + break; + case 'wallet_connectSnaps': + navigate(snapsConnectPath, { replace: true }); + break; + default: + navigate(confirmPermissionPath); + } + }, 0); + }, + [ + requestType, + snapInstallPath, + snapUpdatePath, + snapResultPath, + snapsConnectPath, + confirmPermissionPath, + navigate, + ], + ); + + const cancelPermissionsRequest = useCallback( + async (requestId: string) => { + if (requestId) { + await dispatch(rejectPermissionsRequestAction(requestId)); + redirect(false); + } + }, + [dispatch, redirect], + ); + + const approveConnection = useCallback( + (request: Record) => { + // Cast through unknown to satisfy both local and controller types + dispatch( + approvePermissionsRequestAction( + request as unknown as PermissionsRequest, + ), + ); + redirect(true); + }, + [dispatch, redirect], + ); + + const showNewAccountModal = useCallback( + ({ + onCreateNewAccount, + newAccountNumber: accountNumber, + }: { + onCreateNewAccount: (address: string) => void; + newAccountNumber: number; + }) => { + return dispatch( + showModal({ + name: 'NEW_ACCOUNT', + onCreateNewAccount, + newAccountNumber: accountNumber, + }), + ); + }, + [dispatch], + ); + + const setSnapsInstallPrivacyWarningShownStatus = useCallback( + (shown: boolean) => { + dispatch(setSnapsInstallPrivacyWarningShownStatusAction(shown)); + }, + [dispatch], + ); + + const approvePendingApproval = useCallback( + (id: string, value?: unknown) => + dispatch(resolvePendingApproval(id, value)), + [dispatch], + ); + + const rejectPendingApproval = useCallback( + (id: string, error: unknown) => + dispatch(rejectPendingApprovalAction(id, error)), + [dispatch], + ); + + const renderSnapChooseAccountState1 = useCallback(() => { + return ( + selectAccounts(addresses)} + selectNewAccountViaModal={( + handleAccountClick: (address: string) => void, + ) => { + showNewAccountModal({ + onCreateNewAccount: (address: string) => + handleAccountClick(address), + newAccountNumber, + }); + }} + addressLastConnectedMap={addressLastConnectedMap} + cancelPermissionsRequest={(requestId: string) => + cancelPermissionsRequest(requestId) + } + permissionsRequestId={permissionsRequestId || ''} + selectedAccountAddresses={selectedAccountAddresses} + targetSubjectMetadata={targetSubjectMetadata} + /> + ); + }, [ + accountsWithLabels, + nativeCurrency, + selectAccounts, + showNewAccountModal, + newAccountNumber, + addressLastConnectedMap, + cancelPermissionsRequest, + permissionsRequestId, + selectedAccountAddresses, + targetSubjectMetadata, + ]); + + const renderSnapChooseAccountState2 = useCallback(() => { + const requestedCaip25CaveatValue = getCaip25CaveatValueFromPermissions( + permissions as PermissionsRequest | undefined, + ); + + const caipChainIdsToUse: `${string}:${string}`[] = []; + + const requestedCaipChainIds = getAllScopesFromCaip25CaveatValue( + requestedCaip25CaveatValue, + ).filter((chainId) => { + const { namespace } = parseCaipChainId(chainId); + return namespace !== KnownCaipNamespace.Wallet; + }); + const requestedNamespaces = getAllNamespacesFromCaip25CaveatValue( + requestedCaip25CaveatValue, + ); + + if (requestedCaipChainIds.length > 0) { + requestedCaipChainIds.forEach((chainId) => { + caipChainIdsToUse.push(chainId); + }); + } + + if (requestedNamespaces.includes(KnownCaipNamespace.Eip155)) { + caipChainIdsToUse.push(`${KnownCaipNamespace.Eip155}:0`); + } + + return ( + { + const filteredAccountGroups = accountGroups.filter( + (group) => + accountGroupIds.includes(group.id) && + supportsChainIds(group, caipChainIdsToUse), + ); + const addresses = getCaip25AccountIdsFromAccountGroupAndScope( + filteredAccountGroups, + caipChainIdsToUse, + ).map( + (caip25AccountId) => parseCaipAccountId(caip25AccountId).address, + ); + selectAccounts(new Set(addresses)); + }} + onClose={() => cancelPermissionsRequest(permissionsRequestId || '')} + /> + ); + }, [ + permissions, + accountGroups, + t, + selectAccounts, + cancelPermissionsRequest, + permissionsRequestId, + ]); + + const renderConnectPageState1 = useCallback(() => { + const connectPageProps = { + rejectPermissionsRequest: (requestId: string) => + cancelPermissionsRequest(requestId), + activeTabOrigin: origin, + request: permissionsRequest || {}, + permissionsRequestId: permissionsRequestId || '', + approveConnection, + targetSubjectMetadata, + }; + + return ; + }, [ + cancelPermissionsRequest, + origin, + permissionsRequest, + permissionsRequestId, + approveConnection, + targetSubjectMetadata, + ]); + + const renderConnectPageState2 = useCallback(() => { + const connectPageProps = { + rejectPermissionsRequest: (requestId: string) => + cancelPermissionsRequest(requestId), + activeTabOrigin: origin, + request: permissionsRequest || {}, + permissionsRequestId: permissionsRequestId || '', + approveConnection, + targetSubjectMetadata, + }; + + return ; + }, [ + cancelPermissionsRequest, + origin, + permissionsRequest, + permissionsRequestId, + approveConnection, + targetSubjectMetadata, + ]); + + const renderTopBar = useCallback( + (requestId: string) => { + const handleCancelFromHeader = () => { + cancelPermissionsRequest(requestId); + }; + return ( + + {targetSubjectMetadata.subjectType === SubjectType.Snap && ( + + )} + + ); + }, + [targetSubjectMetadata, cancelPermissionsRequest], + ); + + const isRequestingSnap = isSnapId( + (metadata as Record)?.origin, + ); + + return ( +
+ {!hideTopBar && + permissionsRequestId && + renderTopBar(permissionsRequestId)} + {redirecting && permissionsApproved ? ( + + ) : ( + + { + if (isRequestingSnap) { + return ( + + ); + } + return ( + + ); + })()} + /> + { + dispatch( + approvePermissionsRequestAction( + request as unknown as PermissionsRequest, + ), + ); + redirect(true); + }} + rejectPermissionsRequest={(requestId: string) => + cancelPermissionsRequest(requestId) + } + selectedAccounts={accountsWithLabels.filter( + (account: { address: string }) => + selectedAccountAddresses.has(account.address), + )} + requestedChainIds={getRequestedChainIds( + permissions as PermissionsRequest | undefined, + )} + targetSubjectMetadata={targetSubjectMetadata} + navigate={navigate} + connectPath={connectPath} + snapsInstallPrivacyWarningShown={ + snapsInstallPrivacyWarningShown + } + setSnapsInstallPrivacyWarningShownStatus={ + setSnapsInstallPrivacyWarningShownStatus + } + /> + } + /> + + cancelPermissionsRequest(requestId) + } + targetSubjectMetadata={targetSubjectMetadata} + snapsInstallPrivacyWarningShown={ + snapsInstallPrivacyWarningShown + } + setSnapsInstallPrivacyWarningShownStatus={ + setSnapsInstallPrivacyWarningShownStatus + } + /> + } + /> + { + approvePendingApproval(requestId, { + ...permissionsRequest, + permissions: requestState.permissions, + approvedAccounts: [...selectedAccountAddresses], + }); + setPermissionsApproved(true); + }} + rejectSnapInstall={(requestId) => { + rejectPendingApproval( + requestId, + serializeError(providerErrors.userRejectedRequest()), + ); + setPermissionsApproved(true); + }} + targetSubjectMetadata={targetSubjectMetadata} + /> + } + /> + { + approvePendingApproval(requestId, { + ...permissionsRequest, + permissions: requestState.permissions, + approvedAccounts: [...selectedAccountAddresses], + }); + setPermissionsApproved(true); + }} + rejectSnapUpdate={(requestId) => { + rejectPendingApproval( + requestId, + serializeError(providerErrors.userRejectedRequest()), + ); + setPermissionsApproved(false); + }} + targetSubjectMetadata={targetSubjectMetadata} + /> + } + /> + { + approvePendingApproval(requestId, undefined); + setPermissionsApproved(true); + }} + targetSubjectMetadata={targetSubjectMetadata} + /> + } + /> + + )} +
+ ); +} + +export default PermissionsConnect; diff --git a/ui/pages/remove-snap-account/remove-snap-account.test.tsx b/ui/pages/remove-snap-account/remove-snap-account.test.tsx index 7fa4c0a08f3c..87e986f2f798 100644 --- a/ui/pages/remove-snap-account/remove-snap-account.test.tsx +++ b/ui/pages/remove-snap-account/remove-snap-account.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; import mockState from '../../../test/data/mock-state.json'; import { shortenAddress } from '../../helpers/utils/util'; diff --git a/ui/pages/rewards/index.tsx b/ui/pages/rewards/index.tsx index 7587971f3bf2..2e4f5f186e0a 100644 --- a/ui/pages/rewards/index.tsx +++ b/ui/pages/rewards/index.tsx @@ -1,7 +1,7 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Box } from '@metamask/design-system-react'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import LoadingIndicator from '../../components/ui/loading-indicator'; import { selectRewardsEnabled, @@ -13,23 +13,16 @@ import { setOnboardingReferralCode, } from '../../ducks/rewards'; -type RewardsPageProps = { - navigate: (to: string, options?: { replace?: boolean }) => void; - location: Location; -}; - -const RewardsPage: React.FC = ({ navigate, location }) => { +const RewardsPage: React.FC = () => { const rewardsEnabled = useSelector(selectRewardsEnabled); - const hookLocation = useLocation(); + const location = useLocation(); + const navigate = useNavigate(); const rewardsOnboardingEnabled = useSelector(selectRewardsOnboardingEnabled); const dispatch = useDispatch(); useEffect(() => { if (rewardsEnabled && rewardsOnboardingEnabled) { - const localLocation = location ?? hookLocation; - const params = localLocation - ? new URLSearchParams(localLocation.search) - : new URLSearchParams(); + const params = new URLSearchParams(location.search); const referral = params.get('referral'); if (referral && referral.length > 0) { dispatch(setOnboardingReferralCode(referral)); @@ -41,14 +34,7 @@ const RewardsPage: React.FC = ({ navigate, location }) => { } navigate(DEFAULT_ROUTE, { replace: true }); - }, [ - navigate, - dispatch, - rewardsEnabled, - rewardsOnboardingEnabled, - location, - hookLocation, - ]); + }, [navigate, dispatch, rewardsEnabled, rewardsOnboardingEnabled, location]); return ( diff --git a/ui/pages/routes/confirmation-handler.tsx b/ui/pages/routes/confirmation-handler.tsx index e0bb55b8c7de..bfcf4d5d9437 100644 --- a/ui/pages/routes/confirmation-handler.tsx +++ b/ui/pages/routes/confirmation-handler.tsx @@ -1,6 +1,5 @@ import { useCallback, useEffect } from 'react'; -import { useLocation } from 'react-router-dom'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useLocation, useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { @@ -35,7 +34,6 @@ import { selectHasSwapsQuotes, selectShowAwaitingSwapScreen, } from '../../ducks/swaps/swaps'; -import { useNavState } from '../../contexts/navigation-state'; import { useModalState } from '../../hooks/useModalState'; const EXEMPTED_ROUTES = [ @@ -68,7 +66,6 @@ export const ConfirmationHandler = () => { const navigate = useNavigate(); const location = useLocation(); const { pathname } = location; - const navState = useNavState(); const { closeModals } = useModalState(); const envType = getEnvironmentType(); @@ -81,11 +78,7 @@ export const ConfirmationHandler = () => { const swapsFetchParams = useSelector(getFetchParams); const pendingApprovals = useSelector(selectPendingApprovalsForNavigation); const hasApprovalFlows = useSelector(selectHasApprovalFlows); - - // Read stayOnHomePage from both v5 location.state and v5-compat navState - const stayOnHomePage = - Boolean(location.state?.stayOnHomePage) || - Boolean(navState?.stayOnHomePage); + const stayOnHomePage = Boolean(location.state?.stayOnHomePage); const canRedirect = !isNotification && !stayOnHomePage; diff --git a/ui/pages/routes/routes.component.tsx b/ui/pages/routes/routes.component.tsx index 277d56632950..75deee255982 100644 --- a/ui/pages/routes/routes.component.tsx +++ b/ui/pages/routes/routes.component.tsx @@ -2,23 +2,13 @@ /* eslint-disable import/no-useless-path-segments */ /* eslint-disable import/extensions */ import classnames from 'classnames'; -import React, { Suspense, useCallback, useEffect, useRef } from 'react'; +import React, { Suspense, useEffect, useMemo, useRef } from 'react'; import { useDispatch } from 'react-redux'; -import { - Route, - type RouteComponentProps, - Switch, - useHistory, - useLocation, -} from 'react-router-dom'; -import type { To } from 'react-router-dom-v5-compat'; +import { useRoutes, useLocation, useNavigationType } from 'react-router-dom'; import IdleTimer from 'react-idle-timer'; import type { ApprovalType } from '@metamask/controller-utils'; import { useAppSelector } from '../../store/store'; -import AuthenticatedV5Compat from '../../helpers/higher-order-components/authenticated/authenticated-v5-compat'; -import Initialized from '../../helpers/higher-order-components/initialized'; -import InitializedV5Compat from '../../helpers/higher-order-components/initialized/initialized-v5-compat'; import Loading from '../../components/ui/loading-screen'; import { Modal } from '../../components/app/modals'; import Alert from '../../components/ui/alert'; @@ -150,130 +140,11 @@ import { MultichainReviewPermissions } from '../../components/multichain-account import { State2Wrapper } from '../../components/multichain-accounts/state2-wrapper/state2-wrapper'; import { RootLayout } from '../../layouts/root-layout'; import { LegacyLayout } from '../../layouts/legacy-layout'; -import { RouteWithLayout } from '../../layouts/route-with-layout'; +import { createRouteWithLayout } from '../../layouts/route-with-layout'; import { getConnectingLabel, setTheme } from './utils'; import { ConfirmationHandler } from './confirmation-handler'; import { Modals } from './modals'; -/** - * V5-to-v5-compat navigation function that bridges react-router-dom v5 history - * with v5-compat components expecting the newer navigate API. - * - * Supports two call signatures: - * - Navigate to a route: `navigate(path, options)` - * - Navigate in history: `navigate(delta)` (e.g., -1 to go back) - * - * @example - * // Navigate to a new route - * navigate('/settings', { replace: true }); - * @example - * // Go back in history - * navigate(-1); - */ -type V5CompatNavigate = { - ( - to: To, - options?: { replace?: boolean; state?: Record }, - ): void; - (delta: number): void; -}; - -/** - * Creates a v5-compat navigate function from v5 history - * Used to bridge v5 routes with components expecting v5-compat navigation - * - * @param history - */ -const createV5CompatNavigate = ( - history: RouteComponentProps['history'], -): V5CompatNavigate => { - return ( - to: To | number, - options?: { replace?: boolean; state?: Record }, - ) => { - if (typeof to === 'number') { - history.go(to); - } else if (options?.replace) { - history.replace(to as string, options.state); - } else { - history.push(to as string, options?.state); - } - }; -}; - -/** - * Helper to create v5-compat route wrappers with less boilerplate. - * Handles authentication, navigation, and prop passing for v5-to-v5-compat transition. - * - * NOTE: This is temporary scaffolding for the v5-compat transition. - * It will be removed during the full v6 migration when routes use native v6 patterns. - * - * @param Component - The component to render - * @param options - Configuration options - * @param options.wrapper - Wrapper component (AuthenticatedV5Compat, InitializedV5Compat, or null for none) - * @param options.includeNavigate - Whether to pass navigate prop - * @param options.includeLocation - Whether to pass location prop - * @param options.includeParams - Whether to pass params from route match - * @param options.includeMatch - Whether to pass the entire match object - * @param options.paramsAsProps - Whether to spread params as individual props (default: true) - * @returns Route render function - */ -const createV5CompatRoute = < - TParams extends Record = Record< - string, - string | undefined - >, ->( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - Component: React.ComponentType, - options: { - wrapper?: React.ComponentType<{ children: React.ReactNode }> | null; - includeNavigate?: boolean; - includeLocation?: boolean; - includeParams?: boolean; - includeMatch?: boolean; - paramsAsProps?: boolean; - } = {}, -) => { - const { - wrapper = null, - includeNavigate = false, - includeLocation = false, - includeParams = false, - includeMatch = false, - paramsAsProps = true, - } = options; - - return (props: RouteComponentProps) => { - const { history: v5History, location: v5Location, match } = props; - - const componentProps: Record = {}; - - if (includeNavigate) { - componentProps.navigate = createV5CompatNavigate(v5History); - } - if (includeLocation) { - componentProps.location = v5Location; - } - if (includeMatch) { - componentProps.match = match; - } - if (includeParams) { - if (paramsAsProps) { - Object.assign(componentProps, match.params); - } else { - componentProps.params = match.params; - } - } - - const element = ; - - return wrapper - ? React.createElement(wrapper, { children: element }) - : element; - }; -}; - // TODO: Fix `as unknown as` casting once `mmLazy` is updated to handle named exports, wrapped components, and other React module types. // Casting is preferable over `@ts-expect-error` annotations in this case, // because it doesn't suppress competing error messages e.g. "Cannot find module..." @@ -451,29 +322,20 @@ const ShieldPlan = mmLazy( ); // End Lazy Routes -const MemoizedReviewPermissionsWrapper = React.memo( - (props: { - params?: { origin: string }; - navigate?: ( - to: string | number, - options?: { replace?: boolean; state?: Record }, - ) => void; - }) => ( - } - state2Component={ - MultichainReviewPermissions as React.ComponentType - } - /> - ), -); +const MemoizedReviewPermissionsWrapper = React.memo(() => ( + } + state2Component={ + MultichainReviewPermissions as React.ComponentType + } + /> +)); // eslint-disable-next-line @typescript-eslint/naming-convention -export default function Routes() { +export default function RoutesComponent() { const dispatch = useDispatch(); - const history = useHistory(); const location = useLocation(); + const navType = useNavigationType(); const alertOpen = useAppSelector((state) => state.appState.alertOpen); const alertMessage = useAppSelector((state) => state.appState.alertMessage); @@ -610,17 +472,12 @@ export default function Routes() { } }, [showExtensionInFullSizeView]); + // Track location changes for metrics useEffect(() => { - const unlisten = history.listen((locationObj: Location, action: 'PUSH') => { - if (action === 'PUSH') { - dispatch(pageChanged(locationObj.pathname)); - } - }); - - return () => { - unlisten(); - }; - }, [history, dispatch]); + if (navType === 'PUSH') { + dispatch(pageChanged(location.pathname)); + } + }, [location.pathname, navType, dispatch]); useEffect(() => { setTheme(theme); @@ -632,478 +489,303 @@ export default function Routes() { } }, [currentCurrency, dispatch]); - const renderRoutes = useCallback(() => { - const RestoreVaultComponent = forgottenPassword ? Route : Initialized; + // Define all routes using createRouteWithLayout + const routeConfig = useMemo( + () => [ + createRouteWithLayout({ + path: `${ONBOARDING_ROUTE}/*`, + component: OnboardingFlow, + layout: LegacyLayout, + }), + createRouteWithLayout({ + path: LOCK_ROUTE, + component: Lock, + layout: LegacyLayout, + }), + createRouteWithLayout({ + path: UNLOCK_ROUTE, + component: UnlockPage, + layout: LegacyLayout, + initialized: true, + }), + createRouteWithLayout({ + path: DEEP_LINK_ROUTE, + component: DeepLink, + layout: LegacyLayout, + }), + createRouteWithLayout({ + path: RESTORE_VAULT_ROUTE, + component: RestoreVaultPage, + layout: LegacyLayout, + initialized: !forgottenPassword, + }), + createRouteWithLayout({ + path: SMART_ACCOUNT_UPDATE, + component: SmartAccountUpdate, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${REVEAL_SEED_ROUTE}/:keyringId?`, + component: RevealSeedConfirmation, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: IMPORT_SRP_ROUTE, + component: ImportSrpPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${SETTINGS_ROUTE}/*`, + component: Settings, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: NOTIFICATIONS_SETTINGS_ROUTE, + component: NotificationsSettings, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${NOTIFICATIONS_ROUTE}/:uuid`, + component: NotificationDetails, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: NOTIFICATIONS_ROUTE, + component: Notifications, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: SNAPS_ROUTE, + component: SnapList, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${SNAPS_VIEW_ROUTE}/*`, + component: SnapView, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${SEND_ROUTE}/:page?`, + component: SendPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CONFIRM_TRANSACTION_ROUTE}/:id?/*`, + component: ConfirmTransaction, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${SWAPS_ROUTE}/*`, + component: Swaps, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CROSS_CHAIN_SWAP_TX_DETAILS_ROUTE}/:srcTxMetaId`, + component: CrossChainSwapTxDetails, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CROSS_CHAIN_SWAP_ROUTE}/*`, + component: CrossChainSwap, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE, + component: ConfirmAddSuggestedTokenPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: CONFIRM_ADD_SUGGESTED_NFT_ROUTE, + component: ConfirmAddSuggestedNftPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CONFIRMATION_V_NEXT_ROUTE}/:id?`, + component: ConfirmationPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${NEW_ACCOUNT_ROUTE}/*`, + component: CreateAccountPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CONNECT_ROUTE}/:id/*`, + component: PermissionsConnect, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${ASSET_ROUTE}/image/:asset/:id`, + component: NftFullImage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${ASSET_ROUTE}/:chainId/:asset/:id`, + component: Asset, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${ASSET_ROUTE}/:chainId/:asset/`, + component: Asset, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${ASSET_ROUTE}/:chainId`, + component: Asset, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${DEFI_ROUTE}/:chainId/:protocolId`, + component: DeFiPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${CONNECTIONS}/:origin`, + component: Connections, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: PERMISSIONS, + component: PermissionsPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: GATOR_PERMISSIONS, + component: GatorPermissionsPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${TOKEN_TRANSFER_ROUTE}/:origin`, + component: TokenTransferPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: TOKEN_TRANSFER_ROUTE, + component: TokenTransferPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${REVIEW_GATOR_PERMISSIONS_ROUTE}/:chainId/:permissionGroupName/:origin`, + component: ReviewGatorPermissionsPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${REVIEW_GATOR_PERMISSIONS_ROUTE}/:chainId/:permissionGroupName`, + component: ReviewGatorPermissionsPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${REVIEW_PERMISSIONS}/:origin`, + component: MemoizedReviewPermissionsWrapper, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: ACCOUNT_LIST_PAGE_ROUTE, + component: AccountList, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${MULTICHAIN_ACCOUNT_ADDRESS_LIST_PAGE_ROUTE}/:accountGroupId`, + component: MultichainAccountAddressListPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${MULTICHAIN_ACCOUNT_PRIVATE_KEY_LIST_PAGE_ROUTE}/:accountGroupId`, + component: MultichainAccountPrivateKeyListPage, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: ADD_WALLET_PAGE_ROUTE, + component: AddWalletPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${MULTICHAIN_ACCOUNT_DETAILS_PAGE_ROUTE}/:id`, + component: MultichainAccountDetailsPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${MULTICHAIN_SMART_ACCOUNT_PAGE_ROUTE}/:address`, + component: SmartAccountPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: `${MULTICHAIN_WALLET_DETAILS_PAGE_ROUTE}/:id`, + component: WalletDetailsPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: NONEVM_BALANCE_CHECK_ROUTE, + component: NonEvmBalanceCheck, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: SHIELD_PLAN_ROUTE, + component: ShieldPlan, + layout: LegacyLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: REWARDS_ROUTE, + component: RewardsPage, + layout: RootLayout, + authenticated: true, + }), + createRouteWithLayout({ + path: DEFAULT_ROUTE, + component: Home, + layout: RootLayout, + authenticated: true, + }), + ], + [forgottenPassword], + ); - const routes = ( - - {/* since the loading time is less than 200ms, we decided not to show a spinner fallback or anything */} - - - - - {createV5CompatRoute(UnlockPage, { - wrapper: InitializedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - {createV5CompatRoute(DeepLink, { - includeLocation: true, - })} - - - - - {createV5CompatRoute<{ keyringId?: string }>( - RevealSeedConfirmation, - { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeParams: true, - }, - )} - - - - - - {createV5CompatRoute<{ uuid: string }>(NotificationDetails, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - })} - - - - {createV5CompatRoute(SnapList, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - {createV5CompatRoute(SnapView, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ page?: string }>(SendPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - includeLocation: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ id?: string }>(ConfirmTransaction, { - wrapper: AuthenticatedV5Compat, - includeLocation: true, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute(Swaps, { - wrapper: AuthenticatedV5Compat, - includeLocation: true, - })} - - - {createV5CompatRoute<{ srcTxMetaId: string }>( - CrossChainSwapTxDetails, - { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - includeParams: true, - paramsAsProps: false, // Pass as params object - }, - )} - - - {createV5CompatRoute(CrossChainSwap, { - wrapper: AuthenticatedV5Compat, - includeLocation: true, - })} - - - {createV5CompatRoute(ConfirmAddSuggestedTokenPage, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - {createV5CompatRoute(ConfirmAddSuggestedNftPage, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - {createV5CompatRoute<{ id?: string }>(ConfirmationPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - - {createV5CompatRoute<{ id: string }>(PermissionsConnect, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - includeMatch: true, - })} - - - {createV5CompatRoute<{ asset: string; id: string }>(NftFullImage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ - chainId: string; - asset: string; - id: string; - }>(Asset, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ - chainId: string; - asset: string; - }>(Asset, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ chainId: string }>(Asset, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ - chainId: string; - protocolId: string; - }>(DeFiPage, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ origin: string }>(Connections, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - })} - - - - - {createV5CompatRoute(TokenTransferPage, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ origin: string }>(TokenTransferPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ - chainId: string; - permissionGroupName: string; - }>(ReviewGatorPermissionsPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ - chainId: string; - permissionGroupName: string; - origin: string; - }>(ReviewGatorPermissionsPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ origin: string }>( - MemoizedReviewPermissionsWrapper, - { - wrapper: AuthenticatedV5Compat, - includeParams: true, - includeNavigate: true, - paramsAsProps: false, - }, - )} - - - {createV5CompatRoute(AccountList, { - wrapper: AuthenticatedV5Compat, - })} - - - {createV5CompatRoute<{ accountGroupId: string }>( - MultichainAccountAddressListPage, - { - wrapper: AuthenticatedV5Compat, - includeLocation: true, - includeParams: true, - paramsAsProps: false, - }, - )} - - - {createV5CompatRoute<{ accountGroupId: string }>( - MultichainAccountPrivateKeyListPage, - { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - }, - )} - - - {createV5CompatRoute(AddWalletPage, { - wrapper: AuthenticatedV5Compat, - })} - - - {createV5CompatRoute<{ id: string }>(MultichainAccountDetailsPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: true, - })} - - - {createV5CompatRoute<{ address: string }>(SmartAccountPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - {createV5CompatRoute<{ id: string }>(WalletDetailsPage, { - wrapper: AuthenticatedV5Compat, - includeParams: true, - paramsAsProps: false, - })} - - - - - {createV5CompatRoute(RewardsPage, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - {createV5CompatRoute(Home, { - wrapper: AuthenticatedV5Compat, - includeNavigate: true, - includeLocation: true, - })} - - - - ); + // Use useRoutes hook to render routes - called on every render to track location changes + const routeElements = useRoutes(routeConfig); + + const renderRoutes = () => { + const routes = {routeElements}; if (autoLockTimeLimit > 0) { return ( @@ -1117,7 +799,7 @@ export default function Routes() { } return routes; - }, [autoLockTimeLimit, forgottenPassword, dispatch]); + }; const t = useI18nContext(); @@ -1222,16 +904,8 @@ export default function Routes() { {renderRoutes()} - {isUnlocked ? ( - - ) : null} - {React.createElement( - ToastMaster as React.ComponentType<{ - location: RouteComponentProps['location']; - }>, - { location }, - )} - + {isUnlocked ? : null} +
); diff --git a/ui/pages/routes/utils.js b/ui/pages/routes/utils.js index c2464cbc5982..7e07ed9c688d 100644 --- a/ui/pages/routes/utils.js +++ b/ui/pages/routes/utils.js @@ -1,4 +1,4 @@ -import { matchPath } from 'react-router-dom-v5-compat'; +import { matchPath } from 'react-router-dom'; // eslint-disable-next-line import/no-restricted-paths import { getEnvironmentType } from '../../../app/scripts/lib/util'; import { @@ -382,9 +382,9 @@ export function showAppHeader(props) { } /** - * Creates a relative location object for use with nested react-router-dom-v5-compat Routes. + * Creates a relative location object for use with nested react-router-dom Routes. * - * When using v5-compat and components inside a parent route, + * When using and components inside a parent route, * the child Routes need to match against paths relative to the parent route, * not the full pathname. This function strips the base path prefix from the * location to create a relative location. The resulting pathname is guaranteed @@ -404,7 +404,7 @@ export function showAppHeader(props) { * ); * // relativeLocation.pathname === '/snaps-connect' * @example - * // Usage with v5-compat Routes: + * // Usage with v6 Routes: * * } /> * } /> @@ -425,6 +425,23 @@ export function getRelativeLocationForNestedRoutes(location, basePath) { }; } +/** + * Converts an absolute route path to a relative path for use with nested Routes. + * + * When using nested `` components inside a parent route with `/*`, + * child routes need to use relative paths (without the parent's base path prefix). + * This function strips the base path and leading slash to create a truly relative path. + * + * @param {string} absolutePath - The full absolute path (e.g., '/onboarding/completion') + * @param {string} [basePath] - The base path to remove (e.g., '/onboarding'). Defaults to empty string. + * @returns {string} The relative path suitable for nested Route matching + * (e.g., 'completion' or '/' for the base route) + */ +export function toRelativeRoutePath(absolutePath, basePath = '') { + const relativePath = absolutePath.replace(basePath, '').replace(/^\//u, ''); + return relativePath || '/'; +} + /** * Extracts the transaction ID from a URL pathname. * diff --git a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js index d056d7b272e4..bd486600564e 100644 --- a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js +++ b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js @@ -1,6 +1,6 @@ import React, { useState, useContext } from 'react'; import PropTypes from 'prop-types'; -import { Navigate, useNavigate } from 'react-router-dom-v5-compat'; +import { Navigate, useNavigate } from 'react-router-dom'; import { AvatarAccountSize } from '@metamask/design-system-react'; import TextField from '../../../../components/ui/text-field'; import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'; diff --git a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx index 65d77fbabf8a..266997f050e4 100644 --- a/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx +++ b/ui/pages/settings/contact-list-tab/edit-contact/edit-contact.container.test.tsx @@ -21,8 +21,8 @@ const mockUseParams = jest.fn(); const MOCK_ADDRESS = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; const MOCK_ADDRESS_NAME = 'Address Book Account 1'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), useParams: () => mockUseParams(), diff --git a/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js b/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js index 4611c74a6818..c32f875dc978 100644 --- a/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js +++ b/ui/pages/settings/contact-list-tab/view-contact/view-contact.component.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Navigate } from 'react-router-dom-v5-compat'; +import { Navigate } from 'react-router-dom'; import { AvatarAccountSize } from '@metamask/design-system-react'; import { Button, diff --git a/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx b/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx index c261b7f823ca..f98ed1c42e0e 100644 --- a/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx +++ b/ui/pages/settings/contact-list-tab/view-contact/view-contact.container.test.tsx @@ -20,8 +20,8 @@ const mockUseParams = jest.fn(); const MOCK_ADDRESS = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; const MOCK_ADDRESS_NAME = 'Address Book Account 1'; -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), useParams: () => mockUseParams(), diff --git a/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx b/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx index 6a5abbcc6f8b..4b05e6c62515 100644 --- a/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx +++ b/ui/pages/settings/developer-options-tab/backup-and-sync.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render, fireEvent, waitFor } from '@testing-library/react'; import '@testing-library/jest-dom'; import { useDeleteAccountSyncingDataFromUserStorage } from '../../../hooks/identity/useAccountSyncing'; -import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../test/lib/render-helpers-navigate'; import { BackupAndSyncDevSettings, useDeleteAccountSyncDataProps, diff --git a/ui/pages/settings/developer-options-tab/developer-options-tab.tsx b/ui/pages/settings/developer-options-tab/developer-options-tab.tsx index 9fa216f4cfcd..8b73e2193b9b 100644 --- a/ui/pages/settings/developer-options-tab/developer-options-tab.tsx +++ b/ui/pages/settings/developer-options-tab/developer-options-tab.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, diff --git a/ui/pages/settings/experimental-tab/experimental-tab.test.js b/ui/pages/settings/experimental-tab/experimental-tab.test.js index 9a9f474dcba4..1a528d6c318e 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.test.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.test.js @@ -1,5 +1,6 @@ import React from 'react'; -import { fireEvent, renderWithProvider, waitFor } from '../../../../test/jest'; +import { fireEvent, waitFor } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import { LegacyMetaMetricsProvider } from '../../../contexts/metametrics'; diff --git a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts index 0d8e9ba9c8ff..641dcac85c76 100644 --- a/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts +++ b/ui/pages/settings/networks-tab/networks-form/use-safe-chains.test.ts @@ -1,5 +1,5 @@ import * as FetchWithCacheModule from '../../../../../shared/lib/fetch-with-cache'; -import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers'; +import { renderHookWithProviderTyped } from '../../../../../test/lib/render-helpers-navigate'; import { rpcIdentifierUtility, SafeChain, diff --git a/ui/pages/settings/security-tab/change-password/change-password.test.tsx b/ui/pages/settings/security-tab/change-password/change-password.test.tsx index 6f24b8c4e96b..21df67263465 100644 --- a/ui/pages/settings/security-tab/change-password/change-password.test.tsx +++ b/ui/pages/settings/security-tab/change-password/change-password.test.tsx @@ -24,8 +24,8 @@ jest.mock('react-redux', () => { }; }); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, })); diff --git a/ui/pages/settings/security-tab/change-password/change-password.tsx b/ui/pages/settings/security-tab/change-password/change-password.tsx index d596c4de708d..9d5e1f06691b 100644 --- a/ui/pages/settings/security-tab/change-password/change-password.tsx +++ b/ui/pages/settings/security-tab/change-password/change-password.tsx @@ -1,7 +1,7 @@ import EventEmitter from 'events'; import React, { useContext, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Box, Button, diff --git a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx index 639b75359bfa..8c03b583507a 100644 --- a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx +++ b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.test.tsx @@ -8,8 +8,8 @@ import { FirstTimeFlowType } from '../../../../../shared/constants/onboarding'; import { RevealSrpList } from './reveal-srp-list'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, })); diff --git a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx index 4ce9efaa5327..d6de3a3ebbdb 100644 --- a/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx +++ b/ui/pages/settings/security-tab/reveal-srp-list/reveal-srp-list.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { AuthConnection } from '@metamask/seedless-onboarding-controller'; import { capitalize } from 'lodash'; diff --git a/ui/pages/settings/security-tab/security-tab.test.js b/ui/pages/settings/security-tab/security-tab.test.js index 8c1833041478..1710100a0401 100644 --- a/ui/pages/settings/security-tab/security-tab.test.js +++ b/ui/pages/settings/security-tab/security-tab.test.js @@ -50,8 +50,8 @@ jest.mock('../../../ducks/app/app.ts', () => { }); const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => ({ pathname: '/settings/security' }), useParams: () => ({}), diff --git a/ui/pages/settings/settings.component.js b/ui/pages/settings/settings.component.js index 2caa5b8d7e4e..c5ea8f106dd7 100644 --- a/ui/pages/settings/settings.component.js +++ b/ui/pages/settings/settings.component.js @@ -5,7 +5,7 @@ import { Route, matchPath, Navigate, -} from 'react-router-dom-v5-compat'; +} from 'react-router-dom'; import classnames from 'classnames'; import TabBar from '../../components/app/tab-bar'; @@ -33,7 +33,6 @@ import { TRANSACTION_SHIELD_ROUTE, TRANSACTION_SHIELD_CLAIM_ROUTES, } from '../../helpers/constants/routes'; - import { getSettingsRoutes } from '../../helpers/utils/settings-search'; import { ButtonIcon, @@ -63,6 +62,7 @@ import { SnapIcon } from '../../components/app/snaps/snap-icon'; import { SnapSettingsRenderer } from '../../components/app/snaps/snap-settings-page'; import PasswordOutdatedModal from '../../components/app/password-outdated-modal'; import ShieldEntryModal from '../../components/app/shield-entry-modal'; +import { toRelativeRoutePath } from '../routes/utils'; import SettingsTab from './settings-tab'; import AdvancedTab from './advanced-tab'; import InfoTab from './info-tab'; @@ -501,25 +501,36 @@ class SettingsPage extends PureComponent { } renderContent() { + // Use toRelativeRoutePath to convert absolute paths to relative paths + // for nested in React Router v6 return ( } /> - } /> } + /> + } /> - } /> - } /> } + /> + } + /> + @@ -529,7 +540,7 @@ class SettingsPage extends PureComponent { } /> this.props.toggleNetworkMenu()} @@ -537,43 +548,61 @@ class SettingsPage extends PureComponent { } /> this.props.toggleNetworkMenu()} /> } /> - } /> } + /> + } /> } /> - } /> + } + /> {(process.env.ENABLE_SETTINGS_PAGE_DEV_OPTIONS || process.env.IN_TEST) && ( } /> )} - } /> - } /> } + /> + } + /> + } /> } /> - } /> } + /> + } /> ({ - ...jest.requireActual('react-router-dom-v5-compat'), +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), useLocation: () => ({ pathname: '/settings' }), useNavigate: () => jest.fn(), useParams: () => ({}), diff --git a/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx b/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx index 59a2be435ba6..56f0bd5f9896 100644 --- a/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx +++ b/ui/pages/settings/transaction-shield-tab/cancel-membership-modal.test.tsx @@ -5,7 +5,7 @@ import { SUBSCRIPTION_STATUSES, Subscription, } from '@metamask/subscription-controller'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import CancelMembershipModal from './cancel-membership-modal'; const mockSubscription: Subscription = { diff --git a/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx b/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx index a21eff81ec93..a3feadbc1698 100644 --- a/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx +++ b/ui/pages/settings/transaction-shield-tab/claims-area/claims-area.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Routes as RouterRoutes, Route } from 'react-router-dom-v5-compat'; +import { Routes as RouterRoutes, Route } from 'react-router-dom'; import { ClaimsProvider } from '../../../../contexts/claims/claims'; import ClaimsList from '../claims-list'; import ClaimsForm from '../claims-form'; diff --git a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx index bb6941e547f6..2aed14b8c43d 100644 --- a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx +++ b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.test.tsx @@ -7,9 +7,9 @@ import mockState from '../../../../../test/data/mock-state.json'; import ClaimsForm from './claims-form'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); diff --git a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx index 5b34cdf5cc8f..d99f00d09b67 100644 --- a/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx +++ b/ui/pages/settings/transaction-shield-tab/claims-form/claims-form.tsx @@ -20,7 +20,7 @@ import { IconSize, } from '@metamask/design-system-react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import classnames from 'classnames'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { useClaims } from '../../../../contexts/claims/claims'; diff --git a/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx b/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx index 77de9a65da95..e947e3fd10c9 100644 --- a/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx +++ b/ui/pages/settings/transaction-shield-tab/claims-list/claims-list.tsx @@ -11,7 +11,7 @@ import { IconColor, TextAlign, } from '@metamask/design-system-react'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { Claim, ClaimStatusEnum } from '@metamask/claims-controller'; import LoadingScreen from '../../../../components/ui/loading-screen'; import { Tag } from '../../../../components/component-library'; diff --git a/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx b/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx index b659b3e62257..6332634a35e7 100644 --- a/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx +++ b/ui/pages/settings/transaction-shield-tab/transaction-shield.test.tsx @@ -9,15 +9,15 @@ import { Subscription, SUBSCRIPTION_STATUSES, } from '@metamask/subscription-controller'; -import { renderWithProvider } from '../../../../test/jest/rendering'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import mockState from '../../../../test/data/mock-state.json'; import TransactionShield from './transaction-shield'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation, }; diff --git a/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx b/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx index 98fdbf5311a0..2269fd85f9e2 100644 --- a/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx +++ b/ui/pages/settings/transaction-shield-tab/transaction-shield.tsx @@ -6,7 +6,7 @@ import { RECURRING_INTERVALS, SUBSCRIPTION_STATUSES, } from '@metamask/subscription-controller'; -import { useLocation, useNavigate } from 'react-router-dom-v5-compat'; +import { useLocation, useNavigate } from 'react-router-dom'; import { BannerAlert, BannerAlertSeverity, diff --git a/ui/pages/shield-plan/shield-payment-modal.test.tsx b/ui/pages/shield-plan/shield-payment-modal.test.tsx index 60bf9e3bb613..63b2bf8698d2 100644 --- a/ui/pages/shield-plan/shield-payment-modal.test.tsx +++ b/ui/pages/shield-plan/shield-payment-modal.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import { fireEvent } from '@testing-library/react'; import { PAYMENT_TYPES } from '@metamask/subscription-controller'; -import { renderWithProvider } from '../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import mockState from '../../../test/data/mock-state.json'; import { AssetType } from '../../../shared/constants/transaction'; import { TokenWithApprovalAmount } from '../../hooks/subscription/useSubscriptionPricing'; diff --git a/ui/pages/shield-plan/shield-plan.test.tsx b/ui/pages/shield-plan/shield-plan.test.tsx index b2447c8c590c..e2ff6cf187da 100644 --- a/ui/pages/shield-plan/shield-plan.test.tsx +++ b/ui/pages/shield-plan/shield-plan.test.tsx @@ -6,9 +6,9 @@ import ShieldPlan from './shield-plan'; const mockUseNavigate = jest.fn(); const mockUseLocation = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: () => mockUseLocation(), }; diff --git a/ui/pages/shield-plan/shield-plan.tsx b/ui/pages/shield-plan/shield-plan.tsx index c7b658f1bb88..daec32ba1559 100644 --- a/ui/pages/shield-plan/shield-plan.tsx +++ b/ui/pages/shield-plan/shield-plan.tsx @@ -8,7 +8,7 @@ import { RecurringInterval, } from '@metamask/subscription-controller'; import { useDispatch, useSelector } from 'react-redux'; -import { useLocation, useNavigate } from 'react-router-dom-v5-compat'; +import { useLocation, useNavigate } from 'react-router-dom'; import { Checkbox, TextVariant } from '@metamask/design-system-react'; import { Hex } from '@metamask/utils'; import { diff --git a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx index 55590a2a6986..59f50f1e323d 100644 --- a/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx +++ b/ui/pages/smart-transactions/smart-transaction-status-page/smart-transactions-status-page.test.tsx @@ -7,10 +7,8 @@ import { } from '@metamask/smart-transactions-controller'; import { fireEvent } from '@testing-library/react'; -import { - renderWithProvider, - createSwapsMockStore, -} from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { createSwapsMockStore } from '../../../../test/jest'; import { CHAIN_IDS } from '../../../../shared/constants/network'; import { SmartTransactionStatusPage, diff --git a/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx b/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx index f5b5f787fc42..3f53e5566213 100644 --- a/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx +++ b/ui/pages/snap-account-redirect/create-snap-redirect.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import configureStore from '../../store/store'; import mockState from '../../../test/data/mock-state.json'; -import { renderWithProvider } from '../../../test/jest'; +import { renderWithProvider } from '../../../test/lib/render-helpers-navigate'; import { TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL } from '../../../test/e2e/constants'; import SnapAccountRedirect from './snap-account-redirect'; diff --git a/ui/pages/snaps/snap-view/snap-settings.js b/ui/pages/snaps/snap-view/snap-settings.js index 81e39c41147c..6d6b48a1ab18 100644 --- a/ui/pages/snaps/snap-view/snap-settings.js +++ b/ui/pages/snaps/snap-view/snap-settings.js @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import semver from 'semver'; import { isSnapId } from '@metamask/snaps-utils'; import { useI18nContext } from '../../../hooks/useI18nContext'; diff --git a/ui/pages/snaps/snap-view/snap-view.js b/ui/pages/snaps/snap-view/snap-view.js index ebd4d8885c70..8e3096c0d941 100644 --- a/ui/pages/snaps/snap-view/snap-view.js +++ b/ui/pages/snaps/snap-view/snap-view.js @@ -1,8 +1,7 @@ import React, { useEffect, useState } from 'react'; -import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; import { hasProperty } from '@metamask/utils'; -import { useNavigate, useLocation } from 'react-router-dom-v5-compat'; +import { useNavigate, useLocation } from 'react-router-dom'; import { AlignItems, BackgroundColor, @@ -22,13 +21,9 @@ import SnapHomeMenu from '../../../components/app/snaps/snap-home-menu'; import { SnapHomeRenderer } from '../../../components/app/snaps/snap-home-page/snap-home-renderer'; import SnapSettings from './snap-settings'; -function SnapView({ navigate: navigateProp, location: locationProp }) { - const hookNavigate = useNavigate(); - const hookLocation = useLocation(); - - // Use passed props if they exist, otherwise fall back to hooks - const navigate = navigateProp ?? hookNavigate; - const location = locationProp ?? hookLocation; +function SnapView() { + const navigate = useNavigate(); + const location = useLocation(); const { pathname } = location; // The snap ID is in URI-encoded form in the last path segment of the URL. @@ -138,9 +133,4 @@ function SnapView({ navigate: navigateProp, location: locationProp }) { ); } -SnapView.propTypes = { - navigate: PropTypes.func, - location: PropTypes.object, -}; - export default SnapView; diff --git a/ui/pages/snaps/snap-view/snap-view.test.js b/ui/pages/snaps/snap-view/snap-view.test.js index 9d7e9bfa88d6..43d652e0225f 100644 --- a/ui/pages/snaps/snap-view/snap-view.test.js +++ b/ui/pages/snaps/snap-view/snap-view.test.js @@ -20,8 +20,8 @@ jest.mock('../../../store/actions.ts', () => { }; }); -jest.mock('react-router-dom-v5-compat', () => { - const original = jest.requireActual('react-router-dom-v5-compat'); +jest.mock('react-router-dom', () => { + const original = jest.requireActual('react-router-dom'); return { ...original, useLocation: jest.fn(() => ({ diff --git a/ui/pages/snaps/snaps-list/snap-list.js b/ui/pages/snaps/snaps-list/snap-list.js index f9c010fa24b6..2fd15435b32d 100644 --- a/ui/pages/snaps/snaps-list/snap-list.js +++ b/ui/pages/snaps/snaps-list/snap-list.js @@ -1,7 +1,6 @@ import React, { useRef, useEffect } from 'react'; -import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import SnapListItem from '../../../components/app/snaps/snap-list-item'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { @@ -39,14 +38,10 @@ import { } from '../../../components/multichain/pages/page'; import { getSnapRoute } from '../../../helpers/utils/util'; -const SnapList = ({ navigate: navigateProp }) => { +const SnapList = () => { const t = useI18nContext(); const settingsRef = useRef(); - - const hookNavigate = useNavigate(); - - // Use passed props if they exist, otherwise fall back to hooks - const navigate = navigateProp ?? hookNavigate; + const navigate = useNavigate(); const onClick = (snap) => { navigate(getSnapRoute(snap.id)); }; @@ -175,8 +170,4 @@ const SnapList = ({ navigate: navigateProp }) => { ); }; -SnapList.propTypes = { - navigate: PropTypes.func, -}; - export default SnapList; diff --git a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js index 0de989898955..1eab3c29130f 100644 --- a/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js +++ b/ui/pages/swaps/awaiting-signatures/awaiting-signatures.js @@ -1,6 +1,6 @@ import React, { useContext, useEffect } from 'react'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import isEqual from 'lodash/isEqual'; import { I18nContext } from '../../../contexts/i18n'; import { diff --git a/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js b/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js index 941bca984557..fda0149d7308 100644 --- a/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js +++ b/ui/pages/swaps/awaiting-signatures/swap-step-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SwapStepIcon from './swap-step-icon'; describe('SwapStepIcon', () => { diff --git a/ui/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/pages/swaps/awaiting-swap/awaiting-swap.js index 4da39eac1d6a..377f3de22a06 100644 --- a/ui/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/pages/swaps/awaiting-swap/awaiting-swap.js @@ -2,7 +2,7 @@ import EventEmitter from 'events'; import React, { useContext, useRef, useState, useEffect } from 'react'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import isEqual from 'lodash/isEqual'; import { getBlockExplorerLink } from '@metamask/etherscan-link'; import { I18nContext } from '../../../contexts/i18n'; diff --git a/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js b/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js index 12f2adf45af9..4b287b5dbbab 100644 --- a/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js +++ b/ui/pages/swaps/awaiting-swap/quotes-timeout-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import QuotesTimeoutIcon from './quotes-timeout-icon'; describe('QuotesTimeoutIcon', () => { diff --git a/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js b/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js index 02af2db06e0b..63cd0cab0c83 100644 --- a/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js +++ b/ui/pages/swaps/awaiting-swap/swap-failure-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SwapFailureIcon from './swap-failure-icon'; describe('SwapFailureIcon', () => { diff --git a/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js b/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js index 4e735f1580c1..abbd7a4cb70a 100644 --- a/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js +++ b/ui/pages/swaps/awaiting-swap/swap-success-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SwapSuccessIcon from './swap-success-icon'; describe('SwapSuccessIcon', () => { diff --git a/ui/pages/swaps/countdown-timer/countdown-timer.test.js b/ui/pages/swaps/countdown-timer/countdown-timer.test.js index a6317785df90..5b8898c395d1 100644 --- a/ui/pages/swaps/countdown-timer/countdown-timer.test.js +++ b/ui/pages/swaps/countdown-timer/countdown-timer.test.js @@ -1,10 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; - -import { - renderWithProvider, - createSwapsMockStore, -} from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { createSwapsMockStore } from '../../../../test/jest'; import CountdownTimer from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/countdown-timer/timer-icon.test.js b/ui/pages/swaps/countdown-timer/timer-icon.test.js index e1cd9d628ad2..39c9df92daea 100644 --- a/ui/pages/swaps/countdown-timer/timer-icon.test.js +++ b/ui/pages/swaps/countdown-timer/timer-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import TimerIcon from './timer-icon'; describe('TimerIcon', () => { diff --git a/ui/pages/swaps/create-new-swap/create-new-swap.js b/ui/pages/swaps/create-new-swap/create-new-swap.js index a3f32eac2ea4..04fe4d468367 100644 --- a/ui/pages/swaps/create-new-swap/create-new-swap.js +++ b/ui/pages/swaps/create-new-swap/create-new-swap.js @@ -1,7 +1,7 @@ import React, { useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import isEqual from 'lodash/isEqual'; import Box from '../../../components/ui/box'; import { I18nContext } from '../../../contexts/i18n'; diff --git a/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js b/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js index a4433da6a8ae..a51f71978d77 100644 --- a/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js +++ b/ui/pages/swaps/exchange-rate-display/exchange-rate-display.test.js @@ -1,6 +1,6 @@ import React from 'react'; - -import { renderWithProvider, fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../test/jest'; import ExchangeRateDisplay from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/fee-card/fee-card.test.js b/ui/pages/swaps/fee-card/fee-card.test.js index 234dd5bf215b..4fde6a15d606 100644 --- a/ui/pages/swaps/fee-card/fee-card.test.js +++ b/ui/pages/swaps/fee-card/fee-card.test.js @@ -2,7 +2,8 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { setBackgroundConnection } from '../../../store/background-connection'; -import { renderWithProvider, MOCKS, fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { MOCKS, fireEvent } from '../../../../test/jest'; import { checkNetworkAndAccountSupports1559, diff --git a/ui/pages/swaps/fee-card/pig-icon.test.js b/ui/pages/swaps/fee-card/pig-icon.test.js index 6321b7dc64e4..a7ba18f61be0 100644 --- a/ui/pages/swaps/fee-card/pig-icon.test.js +++ b/ui/pages/swaps/fee-card/pig-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import PigIcon from './pig-icon'; describe('PigIcon', () => { diff --git a/ui/pages/swaps/import-token/import-token.test.js b/ui/pages/swaps/import-token/import-token.test.js index ee3d74ff4685..77380b79f60c 100644 --- a/ui/pages/swaps/import-token/import-token.test.js +++ b/ui/pages/swaps/import-token/import-token.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ImportToken from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/index.js b/ui/pages/swaps/index.js index 71ee429aea6c..a16bae2514a9 100644 --- a/ui/pages/swaps/index.js +++ b/ui/pages/swaps/index.js @@ -5,13 +5,17 @@ import React, { useState, useCallback, } from 'react'; -import PropTypes from 'prop-types'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; -import { Routes, Route, Navigate } from 'react-router-dom-v5-compat'; +import { + Routes, + Route, + Navigate, + useNavigate, + useLocation, +} from 'react-router-dom'; import { isEqual } from 'lodash'; import { TransactionStatus } from '@metamask/transaction-controller'; import { I18nContext } from '../../contexts/i18n'; -import { useSafeNavigation } from '../../hooks/useSafeNavigation'; import { getSelectedAccount, @@ -19,7 +23,8 @@ import { isHardwareWallet, getHardwareWalletType, getHDEntropyIndex, -} from '../../selectors/selectors'; + getCurrentNetworkTransactions, +} from '../../selectors'; import { getCurrentChainId, getSelectedNetworkClientId, @@ -43,7 +48,6 @@ import { setTransactionSettingsOpened, getLatestAddedTokenTo, } from '../../ducks/swaps/swaps'; -import { getCurrentNetworkTransactions } from '../../selectors'; import { getSmartTransactionsEnabled, getSmartTransactionsOptInStatusForMetrics, @@ -60,6 +64,7 @@ import { SWAPS_NOTIFICATION_ROUTE, CROSS_CHAIN_SWAP_ROUTE, } from '../../helpers/constants/routes'; +import { toRelativeRoutePath } from '../routes/utils'; import { ERROR_FETCHING_QUOTES, QUOTES_NOT_AVAILABLE_ERROR, @@ -98,10 +103,10 @@ import AwaitingSwap from './awaiting-swap'; import LoadingQuote from './loading-swaps-quotes'; import NotificationPage from './notification-page/notification-page'; -export default function Swap({ location: propsLocation }) { +export default function Swap() { const t = useContext(I18nContext); - const { navigate, location: hookLocation } = useSafeNavigation(); - const location = propsLocation || hookLocation; + const navigate = useNavigate(); + const location = useLocation(); const dispatch = useDispatch(); const trackEvent = useContext(MetaMetricsContext); const hdEntropyIndex = useSelector(getHDEntropyIndex); @@ -406,9 +411,10 @@ export default function Swap({ location: propsLocation }) {
+ {/* Using relative paths for nested routes inside parent /swaps/* */} @@ -449,7 +455,7 @@ export default function Swap({ location: propsLocation }) { } /> @@ -495,15 +501,15 @@ export default function Swap({ location: propsLocation }) { } /> } /> } /> ); } - -Swap.propTypes = { - location: PropTypes.object, -}; diff --git a/ui/pages/swaps/index.test.js b/ui/pages/swaps/index.test.js index 1d2565ab6055..7061378fba0a 100644 --- a/ui/pages/swaps/index.test.js +++ b/ui/pages/swaps/index.test.js @@ -12,9 +12,9 @@ import Swap from '.'; const middleware = [thunk]; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, useLocation: jest.fn(() => { return { diff --git a/ui/pages/swaps/list-with-search/list-with-search.test.js b/ui/pages/swaps/list-with-search/list-with-search.test.js index 98ab4c1f3f37..d0a018e670bf 100644 --- a/ui/pages/swaps/list-with-search/list-with-search.test.js +++ b/ui/pages/swaps/list-with-search/list-with-search.test.js @@ -1,10 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; - -import { - renderWithProvider, - createSwapsMockStore, -} from '../../../../test/jest'; +import { createSwapsMockStore } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ListWithSearch from './list-with-search'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/loading-swaps-quotes/background-animation.test.js b/ui/pages/swaps/loading-swaps-quotes/background-animation.test.js index d0a694f5f4f4..7b8826bd1b01 100644 --- a/ui/pages/swaps/loading-swaps-quotes/background-animation.test.js +++ b/ui/pages/swaps/loading-swaps-quotes/background-animation.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import BackgroundAnimation from './background-animation'; describe('BackgroundAnimation', () => { diff --git a/ui/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js b/ui/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js index a2487bb78e13..78cd6204e640 100644 --- a/ui/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js +++ b/ui/pages/swaps/loading-swaps-quotes/loading-swaps-quotes.js @@ -3,7 +3,7 @@ import React, { useState, useEffect, useRef, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { shuffle } from 'lodash'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import isEqual from 'lodash/isEqual'; import { navigateBackToPrepareSwap, diff --git a/ui/pages/swaps/mascot-background-animation/mascot-background-animation.test.js b/ui/pages/swaps/mascot-background-animation/mascot-background-animation.test.js index fcbbc5f94cea..783ee3d7f3a3 100644 --- a/ui/pages/swaps/mascot-background-animation/mascot-background-animation.test.js +++ b/ui/pages/swaps/mascot-background-animation/mascot-background-animation.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import MascotBackgroundAnimation from './mascot-background-animation'; describe('MascotBackgroundAnimation', () => { diff --git a/ui/pages/swaps/notification-page/notification-page.js b/ui/pages/swaps/notification-page/notification-page.js index f13930233374..a8fff66ab09e 100644 --- a/ui/pages/swaps/notification-page/notification-page.js +++ b/ui/pages/swaps/notification-page/notification-page.js @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import PropTypes from 'prop-types'; import { I18nContext } from '../../../contexts/i18n'; import { setSwapsErrorKey } from '../../../store/actions'; diff --git a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js index 1de8c7196785..cc2626a73724 100644 --- a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js +++ b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js @@ -3,7 +3,7 @@ import BigNumber from 'bignumber.js'; import PropTypes from 'prop-types'; import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import { uniqBy, isEqual, isEmpty } from 'lodash'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { getAccountLink, getTokenTrackerLink } from '@metamask/etherscan-link'; import classnames from 'classnames'; import { MetaMetricsContext } from '../../../contexts/metametrics'; diff --git a/ui/pages/swaps/prepare-swap-page/review-quote.js b/ui/pages/swaps/prepare-swap-page/review-quote.js index 3eaf2eab9ef2..ae155e788e7f 100644 --- a/ui/pages/swaps/prepare-swap-page/review-quote.js +++ b/ui/pages/swaps/prepare-swap-page/review-quote.js @@ -7,7 +7,7 @@ import React, { useCallback, } from 'react'; import { shallowEqual, useSelector, useDispatch } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import BigNumber from 'bignumber.js'; import { isEqual } from 'lodash'; import classnames from 'classnames'; diff --git a/ui/pages/swaps/prepare-swap-page/slippage-notification-modal.test.tsx b/ui/pages/swaps/prepare-swap-page/slippage-notification-modal.test.tsx index edc2989efd56..2bf12b767ba3 100644 --- a/ui/pages/swaps/prepare-swap-page/slippage-notification-modal.test.tsx +++ b/ui/pages/swaps/prepare-swap-page/slippage-notification-modal.test.tsx @@ -1,13 +1,8 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; - -import { - renderWithProvider, - fireEvent, - createSwapsMockStore, - screen, -} from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { fireEvent, createSwapsMockStore, screen } from '../../../../test/jest'; import { SLIPPAGE_HIGH_ERROR, SLIPPAGE_LOW_ERROR, diff --git a/ui/pages/swaps/prepare-swap-page/view-quote-price-difference.test.js b/ui/pages/swaps/prepare-swap-page/view-quote-price-difference.test.js index c9f65b27e608..e190036e84db 100644 --- a/ui/pages/swaps/prepare-swap-page/view-quote-price-difference.test.js +++ b/ui/pages/swaps/prepare-swap-page/view-quote-price-difference.test.js @@ -1,6 +1,6 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { renderWithProvider } from '../../../../test/lib/render-helpers'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { GasRecommendations } from '../../../../shared/constants/gas'; import ViewQuotePriceDifference from './view-quote-price-difference'; diff --git a/ui/pages/swaps/searchable-item-list/item-list/item-list.component.test.js b/ui/pages/swaps/searchable-item-list/item-list/item-list.component.test.js index 83c076ed06e7..e76b62dc8658 100644 --- a/ui/pages/swaps/searchable-item-list/item-list/item-list.component.test.js +++ b/ui/pages/swaps/searchable-item-list/item-list/item-list.component.test.js @@ -1,11 +1,8 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; -import { - renderWithProvider, - createSwapsMockStore, - fireEvent, -} from '../../../../../test/jest'; +import { createSwapsMockStore, fireEvent } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; import ItemList from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/select-quote-popover/quote-details/quote-details.test.js b/ui/pages/swaps/select-quote-popover/quote-details/quote-details.test.js index a64c465c7fc0..28c515af7256 100644 --- a/ui/pages/swaps/select-quote-popover/quote-details/quote-details.test.js +++ b/ui/pages/swaps/select-quote-popover/quote-details/quote-details.test.js @@ -1,10 +1,7 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; - -import { - renderWithProvider, - createSwapsMockStore, -} from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../../test/lib/render-helpers-navigate'; +import { createSwapsMockStore } from '../../../../../test/jest'; import quoteDataRows from '../mock-quote-data'; import QuoteDetails from './quote-details'; diff --git a/ui/pages/swaps/select-quote-popover/select-quote-popover.test.js b/ui/pages/swaps/select-quote-popover/select-quote-popover.test.js index a22eb1f98624..2241dda67e46 100644 --- a/ui/pages/swaps/select-quote-popover/select-quote-popover.test.js +++ b/ui/pages/swaps/select-quote-popover/select-quote-popover.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import configureStore from '../../../store/store'; import mockState from '../../../../test/data/mock-state.json'; import SelectQuotePopover from '.'; diff --git a/ui/pages/swaps/select-quote-popover/sort-list/sort-list.test.js b/ui/pages/swaps/select-quote-popover/sort-list/sort-list.test.js index b5ec15dc4a2d..55e5c092bcd6 100644 --- a/ui/pages/swaps/select-quote-popover/sort-list/sort-list.test.js +++ b/ui/pages/swaps/select-quote-popover/sort-list/sort-list.test.js @@ -1,6 +1,6 @@ import React from 'react'; - -import { renderWithProvider, fireEvent } from '../../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../../test/jest'; import MockState from '../../../../../test/data/mock-state.json'; import configureStore from '../../../../store/store'; import SortList from './sort-list'; diff --git a/ui/pages/swaps/selected-token/selected-token.test.js b/ui/pages/swaps/selected-token/selected-token.test.js index af70ed0bd8f1..c1db795ee392 100644 --- a/ui/pages/swaps/selected-token/selected-token.test.js +++ b/ui/pages/swaps/selected-token/selected-token.test.js @@ -1,6 +1,6 @@ import React from 'react'; - -import { renderWithProvider, fireEvent } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SelectedToken from './selected-token'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/smart-transaction-status/arrow-icon.test.js b/ui/pages/swaps/smart-transaction-status/arrow-icon.test.js index 015239159226..d3d5817c3983 100644 --- a/ui/pages/swaps/smart-transaction-status/arrow-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/arrow-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ArrowIcon from './arrow-icon'; describe('ArrowIcon', () => { diff --git a/ui/pages/swaps/smart-transaction-status/canceled-icon.test.js b/ui/pages/swaps/smart-transaction-status/canceled-icon.test.js index 10c374497323..a5ab3d520361 100644 --- a/ui/pages/swaps/smart-transaction-status/canceled-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/canceled-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import CanceledIcon from './canceled-icon'; describe('CanceledIcon', () => { diff --git a/ui/pages/swaps/smart-transaction-status/reverted-icon.test.js b/ui/pages/swaps/smart-transaction-status/reverted-icon.test.js index 9a6cd2b2273a..73501c4eb392 100644 --- a/ui/pages/swaps/smart-transaction-status/reverted-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/reverted-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import RevertedIcon from './reverted-icon'; describe('RevertedIcon', () => { diff --git a/ui/pages/swaps/smart-transaction-status/smart-transaction-status.js b/ui/pages/swaps/smart-transaction-status/smart-transaction-status.js index 9994ff25bfa7..947a85c0dadb 100644 --- a/ui/pages/swaps/smart-transaction-status/smart-transaction-status.js +++ b/ui/pages/swaps/smart-transaction-status/smart-transaction-status.js @@ -1,6 +1,6 @@ import React, { useContext, useEffect, useState } from 'react'; import { useDispatch, useSelector, shallowEqual } from 'react-redux'; -import { useNavigate } from 'react-router-dom-v5-compat'; +import { useNavigate } from 'react-router-dom'; import { getBlockExplorerLink } from '@metamask/etherscan-link'; import { isEqual } from 'lodash'; import { I18nContext } from '../../../contexts/i18n'; diff --git a/ui/pages/swaps/smart-transaction-status/success-icon.test.js b/ui/pages/swaps/smart-transaction-status/success-icon.test.js index df6c4fdf8485..15d43bf3da21 100644 --- a/ui/pages/swaps/smart-transaction-status/success-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/success-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import SuccessIcon from './success-icon'; describe('SuccessIcon', () => { diff --git a/ui/pages/swaps/smart-transaction-status/timer-icon.test.js b/ui/pages/swaps/smart-transaction-status/timer-icon.test.js index e1cd9d628ad2..39c9df92daea 100644 --- a/ui/pages/swaps/smart-transaction-status/timer-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/timer-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import TimerIcon from './timer-icon'; describe('TimerIcon', () => { diff --git a/ui/pages/swaps/smart-transaction-status/unknown-icon.test.js b/ui/pages/swaps/smart-transaction-status/unknown-icon.test.js index ea759dccaea7..a78afcb21dcd 100644 --- a/ui/pages/swaps/smart-transaction-status/unknown-icon.test.js +++ b/ui/pages/swaps/smart-transaction-status/unknown-icon.test.js @@ -1,6 +1,6 @@ import React from 'react'; -import { renderWithProvider } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import UnknownIcon from './unknown-icon'; describe('UnknownIcon', () => { diff --git a/ui/pages/swaps/swaps-banner-alert/swaps-banner-alert.test.js b/ui/pages/swaps/swaps-banner-alert/swaps-banner-alert.test.js index e498e9b4b7a3..7575a613e952 100644 --- a/ui/pages/swaps/swaps-banner-alert/swaps-banner-alert.test.js +++ b/ui/pages/swaps/swaps-banner-alert/swaps-banner-alert.test.js @@ -1,11 +1,8 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; - -import { - renderWithProvider, - createSwapsMockStore, -} from '../../../../test/jest'; +import { createSwapsMockStore } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import { QUOTES_EXPIRED_ERROR, SWAP_FAILED_ERROR, diff --git a/ui/pages/swaps/swaps-footer/swaps-footer.test.js b/ui/pages/swaps/swaps-footer/swaps-footer.test.js index 0b721da8960f..842a77a9a333 100644 --- a/ui/pages/swaps/swaps-footer/swaps-footer.test.js +++ b/ui/pages/swaps/swaps-footer/swaps-footer.test.js @@ -1,6 +1,6 @@ import React from 'react'; - -import { renderWithProvider, fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { fireEvent } from '../../../../test/jest'; import SwapsFooter from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/swaps/transaction-settings/transaction-settings.test.js b/ui/pages/swaps/transaction-settings/transaction-settings.test.js index c7a29652751b..ad19d7cdac55 100644 --- a/ui/pages/swaps/transaction-settings/transaction-settings.test.js +++ b/ui/pages/swaps/transaction-settings/transaction-settings.test.js @@ -1,12 +1,8 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; - -import { - renderWithProvider, - fireEvent, - createSwapsMockStore, -} from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; +import { fireEvent, createSwapsMockStore } from '../../../../test/jest'; import { Slippage } from '../../../../shared/constants/swaps'; import TransactionSettings from './transaction-settings'; diff --git a/ui/pages/swaps/view-on-block-explorer/view-on-block-explorer.test.js b/ui/pages/swaps/view-on-block-explorer/view-on-block-explorer.test.js index 30af0c208cdb..74343baa700c 100644 --- a/ui/pages/swaps/view-on-block-explorer/view-on-block-explorer.test.js +++ b/ui/pages/swaps/view-on-block-explorer/view-on-block-explorer.test.js @@ -1,6 +1,7 @@ import React from 'react'; -import { renderWithProvider, fireEvent } from '../../../../test/jest'; +import { fireEvent } from '../../../../test/jest'; +import { renderWithProvider } from '../../../../test/lib/render-helpers-navigate'; import ViewOnBlockExplorer from '.'; const createProps = (customProps = {}) => { diff --git a/ui/pages/unlock-page/unlock-page.component.js b/ui/pages/unlock-page/unlock-page.component.js index 1187973b70fb..43725e8f7ad8 100644 --- a/ui/pages/unlock-page/unlock-page.component.js +++ b/ui/pages/unlock-page/unlock-page.component.js @@ -70,10 +70,6 @@ class UnlockPage extends Component { * Location router for redirect after action */ location: PropTypes.object.isRequired, - /** - * Navigation state from v5-compat navigation context - */ - navState: PropTypes.object, /** * If isUnlocked is true will redirect to most recent route in history */ @@ -157,13 +153,12 @@ class UnlockPage extends Component { } UNSAFE_componentWillMount() { - const { isUnlocked, navigate, location, navState } = this.props; + const { isUnlocked, navigate, location } = this.props; if (isUnlocked) { // Redirect to the intended route if available, otherwise DEFAULT_ROUTE let redirectTo = DEFAULT_ROUTE; - // Read from both v5 location.state and v5-compat navState - const fromLocation = location.state?.from || navState?.from; + const fromLocation = location.state?.from; if (fromLocation?.pathname) { const search = fromLocation.search || ''; redirectTo = fromLocation.pathname + search; diff --git a/ui/pages/unlock-page/unlock-page.container.js b/ui/pages/unlock-page/unlock-page.container.js index c1f852a9eb45..f0b484a6afe0 100644 --- a/ui/pages/unlock-page/unlock-page.container.js +++ b/ui/pages/unlock-page/unlock-page.container.js @@ -1,6 +1,4 @@ import { connect } from 'react-redux'; -import React from 'react'; -import PropTypes from 'prop-types'; import { compose } from 'redux'; // TODO: Remove restricted import // eslint-disable-next-line import/no-restricted-paths @@ -22,7 +20,6 @@ import { import { getIsSocialLoginFlow, getFirstTimeFlowType } from '../../selectors'; import { getCompletedOnboarding } from '../../ducks/metamask/metamask'; import withRouterHooks from '../../helpers/higher-order-components/with-router-hooks/with-router-hooks'; -import { useNavState } from '../../contexts/navigation-state'; import UnlockPage from './unlock-page.component'; const mapStateToProps = (state) => { @@ -61,7 +58,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { navigate, onSubmit: ownPropsSubmit, location, - navState, ...restOwnProps } = ownProps; @@ -80,8 +76,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { await propsTryUnlockMetamask(password); // Redirect to the intended route if available, otherwise DEFAULT_ROUTE let redirectTo = DEFAULT_ROUTE; - // Read from both v5 location.state and v5-compat navState - const fromLocation = location.state?.from || navState?.from; + const fromLocation = location.state?.from; if (fromLocation?.pathname) { const search = fromLocation.search || ''; redirectTo = fromLocation.pathname + search; @@ -97,7 +92,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { onSubmit: ownPropsSubmit || onSubmit, navigate, location, - navState, isPopup, }; }; @@ -107,26 +101,4 @@ const UnlockPageConnected = compose( connect(mapStateToProps, mapDispatchToProps, mergeProps), )(UnlockPage); -/** - * Inject navState from NavigationStateContext for v5-compat navigation. - * This wrapper ensures the unlock page can read navigation state from both - * v5 location.state and v5-compat NavigationStateContext. - * - * @param {object} props - Component props (navigate, location from route) - * @returns {React.ReactElement} UnlockPage with navState injected - */ -const UnlockPageWithNavState = (props) => { - const navState = useNavState(); - return ; -}; - -UnlockPageWithNavState.propTypes = { - navigate: PropTypes.func.isRequired, - location: PropTypes.object.isRequired, - onSubmit: PropTypes.func, -}; - -// Export the connected component for Storybook/testing -export { UnlockPageConnected }; - -export default UnlockPageWithNavState; +export default UnlockPageConnected; diff --git a/ui/pages/unlock-page/unlock-page.stories.js b/ui/pages/unlock-page/unlock-page.stories.js index 832cf26f3ce4..e372b562b86a 100644 --- a/ui/pages/unlock-page/unlock-page.stories.js +++ b/ui/pages/unlock-page/unlock-page.stories.js @@ -12,8 +12,6 @@ export default { }, }, argTypes: { - navigate: { control: 'object' }, - location: { control: 'object' }, isUnlocked: { control: 'boolean' }, onRestore: { action: 'onRestore' }, onSubmit: { action: 'onSubmit' }, diff --git a/ui/pages/unlock-page/unlock-page.test.js b/ui/pages/unlock-page/unlock-page.test.js index 9a46de1f5c5a..7d7e4af01b48 100644 --- a/ui/pages/unlock-page/unlock-page.test.js +++ b/ui/pages/unlock-page/unlock-page.test.js @@ -9,20 +9,13 @@ import { FirstTimeFlowType } from '../../../shared/constants/onboarding'; import UnlockPage from '.'; const mockUseNavigate = jest.fn(); -jest.mock('react-router-dom-v5-compat', () => { +jest.mock('react-router-dom', () => { return { - ...jest.requireActual('react-router-dom-v5-compat'), + ...jest.requireActual('react-router-dom'), useNavigate: () => mockUseNavigate, }; }); -const mockUseNavState = jest.fn(() => null); -jest.mock('../../contexts/navigation-state', () => ({ - useNavState: () => mockUseNavState(), - useSetNavState: () => jest.fn(), - NavigationStateProvider: ({ children }) => children, -})); - jest.mock('../onboarding-flow/welcome/fox-appear-animation', () => ({ __esModule: true, default: () =>
, @@ -67,7 +60,6 @@ describe('Unlock Page', () => { beforeEach(() => { jest.clearAllMocks(); - mockUseNavState.mockReturnValue(null); // Reset navState to null for each test }); it('should match snapshot', () => { @@ -178,28 +170,6 @@ describe('Unlock Page', () => { expect(mockUseNavigate).toHaveBeenCalledWith(intendedPath); }); - it('should redirect to context-stored location when unlocked (HashRouter v5-compat workaround)', () => { - const intendedPath = '/previous-route'; - const mockStateWithUnlock = { - metamask: { isUnlocked: true }, - }; - const store = configureMockStore([thunk])(mockStateWithUnlock); - - const pathname = '/unlock'; - - // Mock navState to provide the redirect location (v5-compat way) - mockUseNavState.mockReturnValueOnce({ - from: { pathname: intendedPath }, - }); - - renderWithProvider(, store, { - pathname, - }); - - expect(mockUseNavigate).toHaveBeenCalledTimes(1); - expect(mockUseNavigate).toHaveBeenCalledWith(intendedPath); - }); - it('changes password, submits, and redirects to the specified route (from location.state)', async () => { const intendedPath = '/intended-route'; const intendedSearch = '?abc=123'; @@ -230,49 +200,12 @@ describe('Unlock Page', () => { expect(mockUseNavigate).toHaveBeenCalledWith(intendedPath + intendedSearch); }); - it('changes password, submits, and redirects to the specified route (from navState)', async () => { - const intendedPath = '/intended-route'; - const intendedSearch = '?abc=123'; - const mockStateNonUnlocked = { - metamask: { isUnlocked: false }, - }; - const store = configureMockStore([thunk])(mockStateNonUnlocked); - - const pathname = '/unlock'; - - // Mock navState to provide the redirect location (v5-compat way) - mockUseNavState.mockReturnValue({ - from: { pathname: intendedPath, search: intendedSearch }, - }); - - const { queryByTestId } = renderWithProvider(, store, { - pathname, - }); - - const passwordField = queryByTestId('unlock-password'); - const loginButton = queryByTestId('unlock-submit'); - fireEvent.change(passwordField, { target: { value: 'a-password' } }); - fireEvent.click(loginButton); - await Promise.resolve(); // Wait for async operations - - expect(mockTryUnlockMetamask).toHaveBeenCalledTimes(1); - expect(mockUseNavigate).toHaveBeenCalledTimes(1); - expect(mockUseNavigate).toHaveBeenCalledWith(intendedPath + intendedSearch); - }); - it('should show login error modal when authentication error is thrown', async () => { - const intendedPath = '/intended-route'; - const intendedSearch = '?abc=123'; const mockStateNonUnlocked = { metamask: { isUnlocked: false, completedOnboarding: true }, }; const store = configureMockStore([thunk])(mockStateNonUnlocked); const pathname = '/unlock'; - // Mock navState to provide the redirect location (v5-compat way) - mockUseNavState.mockReturnValue({ - from: { pathname: intendedPath, search: intendedSearch }, - }); - mockTryUnlockMetamask.mockImplementationOnce( jest.fn(() => { return Promise.reject( diff --git a/yarn.lock b/yarn.lock index 8149eee368b5..51cbbf2548dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11225,10 +11225,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.19.2": - version: 1.19.2 - resolution: "@remix-run/router@npm:1.19.2" - checksum: 10/31b62b66ea68bd62018189047de7b262700113438f62407df019f81a9856a08a705b2b77454be9293518e2f5f3bbf3f8b858ac19f48cb7d89f8ab56b7b630c19 +"@remix-run/router@npm:1.23.1": + version: 1.23.1 + resolution: "@remix-run/router@npm:1.23.1" + checksum: 10/f54845ad174564f157a2255aec8446a7f4f4e543d9d6ef9ec749d32d1fdc57273d9cc80574f87f411c2790fbe51a242273abe7002d118515038eaf4aefd3d988 languageName: node linkType: hard @@ -28326,20 +28326,6 @@ __metadata: languageName: node linkType: hard -"history@npm:^4.9.0": - version: 4.10.1 - resolution: "history@npm:4.10.1" - dependencies: - "@babel/runtime": "npm:^7.1.2" - loose-envify: "npm:^1.2.0" - resolve-pathname: "npm:^3.0.0" - tiny-invariant: "npm:^1.0.2" - tiny-warning: "npm:^1.0.0" - value-equal: "npm:^1.0.1" - checksum: 10/042373f69dad6419a4d551b995ef40f449a8854775a1157c4e9f077ee39aea6ca7ed8f45ec3e1762ef1891357a724d17dad11f2fe7d0edeebcbcf9f48ed3e4d4 - languageName: node - linkType: hard - "history@npm:^5.3.0": version: 5.3.0 resolution: "history@npm:5.3.0" @@ -28360,7 +28346,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -32710,7 +32696,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -33706,8 +33692,7 @@ __metadata: react-popper: "npm:^2.2.3" react-redux: "npm:^7.2.9" react-responsive-carousel: "npm:^3.2.21" - react-router-dom: "npm:^5.3.4" - react-router-dom-v5-compat: "npm:^6.26.2" + react-router-dom: "npm:^6.28.0" react-simple-file-input: "npm:^2.0.0" react-syntax-highlighter: "npm:^15.5.0" react-tippy: "npm:^1.2.2" @@ -38035,7 +38020,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.1, react-is@npm:^16.3.2, react-is@npm:^16.6.0, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1, react-is@npm:^16.3.2, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 10/5aa564a1cde7d391ac980bedee21202fc90bdea3b399952117f54fb71a932af1e5902020144fb354b4690b2414a0c7aafe798eb617b76a3d441d956db7726fdf @@ -38286,65 +38271,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom-v5-compat@npm:^6.26.2": - version: 6.26.2 - resolution: "react-router-dom-v5-compat@npm:6.26.2" +"react-router-dom@npm:^6.28.0": + version: 6.30.2 + resolution: "react-router-dom@npm:6.30.2" dependencies: - "@remix-run/router": "npm:1.19.2" - history: "npm:^5.3.0" - react-router: "npm:6.26.2" + "@remix-run/router": "npm:1.23.1" + react-router: "npm:6.30.2" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - react-router-dom: 4 || 5 - checksum: 10/0662c16f8fbed2d89b79d7977c94961c331f576bf1c638ba9782656d72a57ab49f081940effc796913870f34a3ebac01287b1bdcb67750b2b04d35e6b59f8180 - languageName: node - linkType: hard - -"react-router-dom@npm:^5.3.4": - version: 5.3.4 - resolution: "react-router-dom@npm:5.3.4" - dependencies: - "@babel/runtime": "npm:^7.12.13" - history: "npm:^4.9.0" - loose-envify: "npm:^1.3.1" - prop-types: "npm:^15.6.2" - react-router: "npm:5.3.4" - tiny-invariant: "npm:^1.0.2" - tiny-warning: "npm:^1.0.0" - peerDependencies: - react: ">=15" - checksum: 10/5e0696ae2d86f466ff700944758a227e1dcd79b48797d567776506e4e3b4a08b81336155feb86a33be9f38c17c4d3d94212b5c60c8ee9a086022e4fd3961db29 - languageName: node - linkType: hard - -"react-router@npm:5.3.4": - version: 5.3.4 - resolution: "react-router@npm:5.3.4" - dependencies: - "@babel/runtime": "npm:^7.12.13" - history: "npm:^4.9.0" - hoist-non-react-statics: "npm:^3.1.0" - loose-envify: "npm:^1.3.1" - path-to-regexp: "npm:^1.7.0" - prop-types: "npm:^15.6.2" - react-is: "npm:^16.6.0" - tiny-invariant: "npm:^1.0.2" - tiny-warning: "npm:^1.0.0" - peerDependencies: - react: ">=15" - checksum: 10/99d54a99af6bc6d7cad2e5ea7eee9485b62a8b8e16a1182b18daa7fad7dafa5e526850eaeebff629848b297ae055a9cb5b4aba8760e81af8b903efc049d48f5c + checksum: 10/ca60fd157c8e1019c9994a7262a8c054326c2d5bba4bbd3b4a19918a1a21f1486cf7a1087dd3aee22c01381496b4712cd80cbd5b5388c956cdbb58541ee52194 languageName: node linkType: hard -"react-router@npm:6.26.2": - version: 6.26.2 - resolution: "react-router@npm:6.26.2" +"react-router@npm:6.30.2": + version: 6.30.2 + resolution: "react-router@npm:6.30.2" dependencies: - "@remix-run/router": "npm:1.19.2" + "@remix-run/router": "npm:1.23.1" peerDependencies: react: ">=16.8" - checksum: 10/496e855b53e61066c1791e354f5d79eab56a128d9722fdc6486c3ecd3b3a0bf9968e927028f429893b157f3cc10fc09e890a055847723ee242663e7995fedc9d + checksum: 10/537bd68aa9e8125e1b20702180d4d875421150280e2c4c039c663a105da05956a457cb4d0f4f6a56605d6cadf9b1c1282dc45a9845f81bdca9bc87364eafc073 languageName: node linkType: hard @@ -39382,13 +39329,6 @@ __metadata: languageName: node linkType: hard -"resolve-pathname@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-pathname@npm:3.0.0" - checksum: 10/6147241ba42c423dbe83cb067a2b4af4f60908c3af57e1ea567729cc71416c089737fe2a73e9e79e7a60f00f66c91e4b45ad0d37cd4be2d43fec44963ef14368 - languageName: node - linkType: hard - "resolve-pkg-maps@npm:^1.0.0": version: 1.0.0 resolution: "resolve-pkg-maps@npm:1.0.0" @@ -42679,7 +42619,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.0.2, tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": +"tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.1, tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 10/5e185c8cc2266967984ce3b352a4e57cb89dad5a8abb0dea21468a6ecaa67cd5bb47a3b7a85d08041008644af4f667fb8b6575ba38ba5fb00b3b5068306e59fe @@ -42714,7 +42654,7 @@ __metadata: languageName: node linkType: hard -"tiny-warning@npm:^1.0.0, tiny-warning@npm:^1.0.2": +"tiny-warning@npm:^1.0.2": version: 1.0.3 resolution: "tiny-warning@npm:1.0.3" checksum: 10/da62c4acac565902f0624b123eed6dd3509bc9a8d30c06e017104bedcf5d35810da8ff72864400ad19c5c7806fc0a8323c68baf3e326af7cb7d969f846100d71 @@ -44510,13 +44450,6 @@ __metadata: languageName: node linkType: hard -"value-equal@npm:^1.0.1": - version: 1.0.1 - resolution: "value-equal@npm:1.0.1" - checksum: 10/bb7ae1facc76b5cf8071aeb6c13d284d023fdb370478d10a5d64508e0e6e53bb459c4bbe34258df29d82e6f561f874f0105eba38de0e61fe9edd0bdce07a77a2 - languageName: node - linkType: hard - "value-or-function@npm:^3.0.0": version: 3.0.0 resolution: "value-or-function@npm:3.0.0"