From 3d98558bf6ca9f88baac8ca85166ab59bc2ba118 Mon Sep 17 00:00:00 2001
From: Syed Ali Abbas Zaidi
<88369802+Syed-Ali-Abbas-Zaidi@users.noreply.github.com>
Date: Fri, 18 Aug 2023 12:29:07 +0500
Subject: [PATCH] feat: upgrade react rotuer to v6 (#793)
* feat: upgrade react rotuer to v6
* fix: test cases
* build: update header and footer
* refactor: update jumpnav test case
---
package-lock.json | 208 ++++++------------
package.json | 10 +-
.../test/CertificatePreference.test.jsx | 7 +-
.../name-change/NameChange.jsx | 8 +-
.../name-change/test/NameChange.test.jsx | 9 +-
src/account-settings/test/JumpNav.test.jsx | 28 +--
.../test/__snapshots__/JumpNav.test.jsx.snap | 52 +++--
src/id-verification/IdVerificationPage.jsx | 151 ++++++-------
src/id-verification/panels/BasePanel.jsx | 4 +-
src/id-verification/panels/GetNameIdPanel.jsx | 9 +-
src/id-verification/panels/IdContextPanel.jsx | 2 +-
.../panels/PortraitPhotoContextPanel.jsx | 2 +-
.../panels/RequestCameraAccessPanel.jsx | 2 +-
.../panels/ReviewRequirementsPanel.jsx | 2 +-
src/id-verification/panels/SummaryPanel.jsx | 25 +--
.../panels/TakeIdPhotoPanel.jsx | 2 +-
.../panels/TakePortraitPhotoPanel.jsx | 2 +-
.../tests/AccessBlocked.test.jsx | 11 +-
src/id-verification/tests/Camera.test.jsx | 21 +-
.../tests/CollapsibleImageHelp.test.jsx | 9 +-
.../tests/IdVerificationPage.test.jsx | 16 +-
.../tests/panels/GetNameIdPanel.test.jsx | 9 +-
.../tests/panels/IdContextPanel.test.jsx | 13 +-
.../panels/PortraitPhotoContextPanel.test.jsx | 13 +-
.../panels/RequestCameraAccessPanel.test.jsx | 31 ++-
.../panels/ReviewRequirementsPanel.test.jsx | 9 +-
.../tests/panels/SubmittedPanel.test.jsx | 11 +-
.../tests/panels/SummaryPanel.test.jsx | 8 +-
.../tests/panels/TakeIdPhotoPanel.test.jsx | 17 +-
.../panels/TakePortraitPhotoPanel.test.jsx | 15 +-
src/index.jsx | 39 ++--
.../NotificationPreferences.jsx | 3 +-
32 files changed, 325 insertions(+), 423 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6294758..9d46adc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,9 +10,9 @@
"license": "AGPL-3.0",
"dependencies": {
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
- "@edx/frontend-component-footer": "12.1.2",
- "@edx/frontend-component-header": "4.5.0",
- "@edx/frontend-platform": "4.6.1",
+ "@edx/frontend-component-footer": "12.2.0",
+ "@edx/frontend-component-header": "4.6.0",
+ "@edx/frontend-platform": "5.0.0",
"@edx/paragon": "20.46.2",
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-brands-svg-icons": "5.15.4",
@@ -48,8 +48,8 @@
"react-dom": "17.0.2",
"react-helmet": "6.1.0",
"react-redux": "7.2.9",
- "react-router": "5.2.1",
- "react-router-dom": "5.3.0",
+ "react-router": "6.14.2",
+ "react-router-dom": "6.14.2",
"react-router-hash-link": "2.4.3",
"react-scrollspy": "3.4.3",
"react-transition-group": "4.4.5",
@@ -2167,9 +2167,9 @@
}
},
"node_modules/@edx/frontend-component-footer": {
- "version": "12.1.2",
- "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-12.1.2.tgz",
- "integrity": "sha512-f1lM1WTpdiD4vjrbE5pMC8J11ObWI9w7upBBk+xqP3Iv27+py9Sr4CJVhQVRwqvIYr6heurvv9UxECbZ0X3alg==",
+ "version": "12.2.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-12.2.0.tgz",
+ "integrity": "sha512-tAI6TSvb0U15drV/eKtEs8O+oiDtTE/yaN4uDKs++RJxKVpLUlar7sug54b7cVy9Y3FPR/3Cfb/ytsuIqhLmxw==",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-brands-svg-icons": "6.4.0",
@@ -2178,7 +2178,7 @@
"@fortawesome/react-fontawesome": "0.2.0"
},
"peerDependencies": {
- "@edx/frontend-platform": "^4.0.0",
+ "@edx/frontend-platform": "^4.0.0 || ^5.0.0",
"prop-types": "^15.5.10",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
@@ -2242,33 +2242,32 @@
}
},
"node_modules/@edx/frontend-component-header": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-4.5.0.tgz",
- "integrity": "sha512-bMVZlxBkufn15iEbnzJztzyq/waWqdRpacwQ0DSTnzqwil6ZV+s6oLfBv767J0OrvqwHz2iydamnoAMRWOwI+A==",
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-4.6.0.tgz",
+ "integrity": "sha512-zZuMgHQWfFMTquVb4iL/iQMwKRRgts8CFFLyL8R6vQL1WfHd21hndhKii2kp9lBnIJgrilIfF79RsbImb5L0og==",
"dependencies": {
- "@edx/paragon": "20.45.5",
- "@fortawesome/fontawesome-svg-core": "6.4.0",
- "@fortawesome/free-brands-svg-icons": "6.4.0",
- "@fortawesome/free-regular-svg-icons": "6.4.0",
- "@fortawesome/free-solid-svg-icons": "6.4.0",
+ "@edx/paragon": "20.46.2",
+ "@fortawesome/fontawesome-svg-core": "6.4.2",
+ "@fortawesome/free-brands-svg-icons": "6.4.2",
+ "@fortawesome/free-regular-svg-icons": "6.4.2",
+ "@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"axios-mock-adapter": "1.21.5",
"babel-polyfill": "6.26.0",
"react-responsive": "8.2.0",
- "react-router-dom": "5.3.4",
"react-transition-group": "4.4.5"
},
"peerDependencies": {
- "@edx/frontend-platform": "^4.0.0",
+ "@edx/frontend-platform": "^4.0.0 || ^5.0.0",
"prop-types": "^15.5.10",
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@edx/paragon": {
- "version": "20.45.5",
- "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.45.5.tgz",
- "integrity": "sha512-7GsGPKyxtjFo3Xnj+uQ4vx/Khz7S6srHe8MqcsYCMx2mJ8fulPN2JFm84m+0o1CSwHaL469wBPONI4KCa+vfrA==",
+ "version": "20.46.2",
+ "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.46.2.tgz",
+ "integrity": "sha512-px+KS/BV1CbiMKgfVgUofyjJi4CHUCUOLRukJbT66VPPqWP4Xon5Rns6uohoratPXMg2kNN46v2L8wIwqKQ4Lw==",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.1.1",
"@fortawesome/react-fontawesome": "^0.1.18",
@@ -2315,57 +2314,57 @@
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz",
- "integrity": "sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==",
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz",
+ "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-svg-core": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz",
- "integrity": "sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==",
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz",
+ "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.4.0"
+ "@fortawesome/fontawesome-common-types": "6.4.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.0.tgz",
- "integrity": "sha512-qvxTCo0FQ5k2N+VCXb/PZQ+QMhqRVM4OORiO6MXdG6bKolIojGU/srQ1ptvKk0JTbRgaJOfL2qMqGvBEZG7Z6g==",
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.2.tgz",
+ "integrity": "sha512-LKOwJX0I7+mR/cvvf6qIiqcERbdnY+24zgpUSouySml+5w8B4BJOx8EhDR/FTKAu06W12fmUIcv6lzPSwYKGGg==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.4.0"
+ "@fortawesome/fontawesome-common-types": "6.4.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-regular-svg-icons": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz",
- "integrity": "sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw==",
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz",
+ "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.4.0"
+ "@fortawesome/fontawesome-common-types": "6.4.2"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-solid-svg-icons": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz",
- "integrity": "sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==",
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz",
+ "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==",
"hasInstallScript": true,
"dependencies": {
- "@fortawesome/fontawesome-common-types": "6.4.0"
+ "@fortawesome/fontawesome-common-types": "6.4.2"
},
"engines": {
"node": ">=6"
@@ -2408,51 +2407,10 @@
"node": ">=10"
}
},
- "node_modules/@edx/frontend-component-header/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/@edx/frontend-component-header/node_modules/react-router": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz",
- "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==",
- "dependencies": {
- "@babel/runtime": "^7.12.13",
- "history": "^4.9.0",
- "hoist-non-react-statics": "^3.1.0",
- "loose-envify": "^1.3.1",
- "path-to-regexp": "^1.7.0",
- "prop-types": "^15.6.2",
- "react-is": "^16.6.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
- },
- "peerDependencies": {
- "react": ">=15"
- }
- },
- "node_modules/@edx/frontend-component-header/node_modules/react-router-dom": {
- "version": "5.3.4",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz",
- "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==",
- "dependencies": {
- "@babel/runtime": "^7.12.13",
- "history": "^4.9.0",
- "loose-envify": "^1.3.1",
- "prop-types": "^15.6.2",
- "react-router": "5.3.4",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
- },
- "peerDependencies": {
- "react": ">=15"
- }
- },
"node_modules/@edx/frontend-platform": {
- "version": "4.6.1",
- "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-4.6.1.tgz",
- "integrity": "sha512-Fi/k7iZlFYs8qCsAAVz6Dseyzb9bJGh3r6iKUCiAq4emUl9UA/LfFHe4fDZcA5trVIkohhdLqrDu1U3UksY/5w==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-5.0.0.tgz",
+ "integrity": "sha512-DD9/B4rnC3BKPiWlbEFF1JIYFbWC6vUBKTyN8sf4khi4DNhhWhsobk+iNeCWNzF9UgCPRbniIqesdV1F9NXNZw==",
"dependencies": {
"@cospired/i18n-iso-languages": "4.1.0",
"@formatjs/intl-pluralrules": "4.3.3",
@@ -2485,7 +2443,7 @@
"react": "^16.9.0 || ^17.0.0",
"react-dom": "^16.9.0 || ^17.0.0",
"react-redux": "^7.1.1",
- "react-router-dom": "^5.0.1",
+ "react-router-dom": "^6.0.0",
"redux": "^4.0.4"
}
},
@@ -5156,6 +5114,14 @@
"resolved": "https://registry.npmjs.org/@redux-saga/types/-/types-1.2.1.tgz",
"integrity": "sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA=="
},
+ "node_modules/@remix-run/router": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz",
+ "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@restart/context": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
@@ -16747,20 +16713,6 @@
"node": ">=4"
}
},
- "node_modules/mini-create-react-context": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
- "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
- "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
- "dependencies": {
- "@babel/runtime": "^7.12.1",
- "tiny-warning": "^1.0.3"
- },
- "peerDependencies": {
- "prop-types": "^15.0.0",
- "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/mini-css-extract-plugin": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz",
@@ -17700,14 +17652,6 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
- "node_modules/path-to-regexp": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
- "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
- "dependencies": {
- "isarray": "0.0.1"
- }
- },
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -19370,40 +19314,33 @@
}
},
"node_modules/react-router": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz",
- "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==",
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz",
+ "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==",
"dependencies": {
- "@babel/runtime": "^7.12.13",
- "history": "^4.9.0",
- "hoist-non-react-statics": "^3.1.0",
- "loose-envify": "^1.3.1",
- "mini-create-react-context": "^0.4.0",
- "path-to-regexp": "^1.7.0",
- "prop-types": "^15.6.2",
- "react-is": "^16.6.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
+ "@remix-run/router": "1.7.2"
+ },
+ "engines": {
+ "node": ">=14"
},
"peerDependencies": {
- "react": ">=15"
+ "react": ">=16.8"
}
},
"node_modules/react-router-dom": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz",
- "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==",
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz",
+ "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==",
"dependencies": {
- "@babel/runtime": "^7.12.13",
- "history": "^4.9.0",
- "loose-envify": "^1.3.1",
- "prop-types": "^15.6.2",
- "react-router": "5.2.1",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
+ "@remix-run/router": "1.7.2",
+ "react-router": "6.14.2"
+ },
+ "engines": {
+ "node": ">=14"
},
"peerDependencies": {
- "react": ">=15"
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
}
},
"node_modules/react-router-hash-link": {
@@ -19418,11 +19355,6 @@
"react-router-dom": ">=4"
}
},
- "node_modules/react-router/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
"node_modules/react-scrollspy": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/react-scrollspy/-/react-scrollspy-3.4.3.tgz",
diff --git a/package.json b/package.json
index 2b123a8..42bc061 100644
--- a/package.json
+++ b/package.json
@@ -28,9 +28,9 @@
],
"dependencies": {
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
- "@edx/frontend-component-footer": "12.1.2",
- "@edx/frontend-component-header": "4.5.0",
- "@edx/frontend-platform": "4.6.1",
+ "@edx/frontend-component-footer": "12.2.0",
+ "@edx/frontend-component-header": "4.6.0",
+ "@edx/frontend-platform": "5.0.0",
"@edx/paragon": "20.46.2",
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-brands-svg-icons": "5.15.4",
@@ -66,8 +66,8 @@
"react-dom": "17.0.2",
"react-helmet": "6.1.0",
"react-redux": "7.2.9",
- "react-router": "5.2.1",
- "react-router-dom": "5.3.0",
+ "react-router": "6.14.2",
+ "react-router-dom": "6.14.2",
"react-router-hash-link": "2.4.3",
"react-scrollspy": "3.4.3",
"react-transition-group": "4.4.5",
diff --git a/src/account-settings/certificate-preference/test/CertificatePreference.test.jsx b/src/account-settings/certificate-preference/test/CertificatePreference.test.jsx
index c97541b..4fff034 100644
--- a/src/account-settings/certificate-preference/test/CertificatePreference.test.jsx
+++ b/src/account-settings/certificate-preference/test/CertificatePreference.test.jsx
@@ -2,14 +2,13 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import { Router } from 'react-router-dom';
+import { BrowserRouter as Router } from 'react-router-dom';
import configureStore from 'redux-mock-store';
import {
fireEvent,
render,
screen,
} from '@testing-library/react';
-import { createMemoryHistory } from 'history';
import * as auth from '@edx/frontend-platform/auth';
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
@@ -28,8 +27,6 @@ jest.mock('react-redux', () => ({
jest.mock('@edx/frontend-platform/auth');
jest.mock('../../data/selectors', () => jest.fn().mockImplementation(() => ({ certPreferenceSelector: () => ({}) })));
-const history = createMemoryHistory();
-
const IntlCertificatePreference = injectIntl(CertificatePreference);
const mockStore = configureStore();
@@ -42,7 +39,7 @@ describe('NameChange', () => {
const labelText = 'If checked, this name will appear on your certificates and public-facing records.';
const reduxWrapper = children => (
-
+
{children}
diff --git a/src/account-settings/name-change/NameChange.jsx b/src/account-settings/name-change/NameChange.jsx
index 08e4adc..35bbda4 100644
--- a/src/account-settings/name-change/NameChange.jsx
+++ b/src/account-settings/name-change/NameChange.jsx
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import { connect, useDispatch } from 'react-redux';
-import { useHistory } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
@@ -29,7 +29,7 @@ const NameChangeModal = ({
saveState,
}) => {
const dispatch = useDispatch();
- const { push } = useHistory();
+ const navigate = useNavigate();
const { username } = getAuthenticatedUser();
const [verifiedNameInput, setVerifiedNameInput] = useState(formValues.verified_name || '');
const [confirmedWarning, setConfirmedWarning] = useState(false);
@@ -69,9 +69,9 @@ const NameChangeModal = ({
useEffect(() => {
if (saveState === 'complete') {
handleClose();
- push(`/id-verification?next=${encodeURIComponent('account/settings')}`);
+ navigate(`/id-verification?next=${encodeURIComponent('account/settings')}`);
}
- }, [handleClose, push, saveState]);
+ }, [handleClose, navigate, saveState]);
function renderErrors() {
if (Object.keys(errors).length > 0) {
diff --git a/src/account-settings/name-change/test/NameChange.test.jsx b/src/account-settings/name-change/test/NameChange.test.jsx
index a3a89dd..1085f54 100644
--- a/src/account-settings/name-change/test/NameChange.test.jsx
+++ b/src/account-settings/name-change/test/NameChange.test.jsx
@@ -2,14 +2,13 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import { Router } from 'react-router-dom';
+import { BrowserRouter as Router } from 'react-router-dom';
import configureStore from 'redux-mock-store';
import {
fireEvent,
render,
screen,
} from '@testing-library/react';
-import { createMemoryHistory } from 'history';
import * as auth from '@edx/frontend-platform/auth';
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
@@ -28,8 +27,6 @@ jest.mock('react-redux', () => ({
jest.mock('@edx/frontend-platform/auth');
jest.mock('../../data/selectors', () => jest.fn().mockImplementation(() => ({ nameChangeSelector: () => ({}) })));
-const history = createMemoryHistory();
-
const IntlNameChange = injectIntl(NameChange);
const mockStore = configureStore();
@@ -39,7 +36,7 @@ describe('NameChange', () => {
let store = {};
const reduxWrapper = children => (
-
+
{children}
@@ -168,6 +165,6 @@ describe('NameChange', () => {
props.saveState = 'complete';
render(reduxWrapper());
- expect(history.location.pathname).toEqual('/id-verification');
+ expect(window.location.pathname).toEqual('/id-verification');
});
});
diff --git a/src/account-settings/test/JumpNav.test.jsx b/src/account-settings/test/JumpNav.test.jsx
index f905c38..2b57934 100644
--- a/src/account-settings/test/JumpNav.test.jsx
+++ b/src/account-settings/test/JumpNav.test.jsx
@@ -4,7 +4,6 @@ import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { initializeMockApp, mergeConfig, setConfig } from '@edx/frontend-platform';
-import { BrowserRouter as Router } from 'react-router-dom';
import JumpNav from '../JumpNav';
import configureStore from '../../data/configureStore';
@@ -41,15 +40,11 @@ describe('JumpNav', () => {
it('should not render Optional Information link', () => {
const tree = renderer.create((
- // Had to wrap the following in a router or I will receive an error stating:
- // "Invariant failed: You should not use outside a "
-
-
-
-
-
-
-
+
+
+
+
+
))
.toJSON();
@@ -67,14 +62,11 @@ describe('JumpNav', () => {
};
const tree = renderer.create((
- // Same as previous test
-
-
-
-
-
-
-
+
+
+
+
+
))
.toJSON();
diff --git a/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap b/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap
index 2b01f27..a69f0ea 100644
--- a/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap
+++ b/src/account-settings/test/__snapshots__/JumpNav.test.jsx.snap
@@ -12,8 +12,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Account Information
@@ -23,8 +25,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Profile Information
@@ -34,8 +38,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Social Media Links
@@ -45,8 +51,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Site Preferences
@@ -56,8 +64,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Linked Accounts
@@ -67,8 +77,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
className=""
>
Delete My Account
@@ -90,8 +102,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Account Information
@@ -101,8 +115,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Profile Information
@@ -112,8 +128,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Optional Information
@@ -123,8 +141,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Social Media Links
@@ -134,8 +154,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Site Preferences
@@ -145,8 +167,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Linked Accounts
@@ -156,8 +180,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
className=""
>
Delete My Account
diff --git a/src/id-verification/IdVerificationPage.jsx b/src/id-verification/IdVerificationPage.jsx
index 4b3eea3..696f0b5 100644
--- a/src/id-verification/IdVerificationPage.jsx
+++ b/src/id-verification/IdVerificationPage.jsx
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import {
- Route, Switch, Redirect, useRouteMatch, useLocation,
+ Route, Routes, useLocation, useNavigate,
} from 'react-router-dom';
import camelCase from 'lodash.camelcase';
import qs from 'qs';
@@ -27,8 +27,8 @@ import messages from './IdVerification.messages';
// eslint-disable-next-line react/prefer-stateless-function
const IdVerificationPage = (props) => {
- const { path } = useRouteMatch();
const { search } = useLocation();
+ const navigate = useNavigate();
const [isModalOpen, setIsModalOpen] = useState(false);
@@ -45,81 +45,82 @@ const IdVerificationPage = (props) => {
}
}, [search]);
- return (
- <>
- {/* If user reloads, redirect to the beginning of the process */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
setIsModalOpen(false)}
- size="lg"
- hasCloseButton={false}
- >
-
-
- {props.intl.formatMessage(messages['id.verification.privacy.title'])}
-
-
-
-
-
- {props.intl.formatMessage(
- messages['id.verification.privacy.need.photo.question'],
- { siteName: getConfig().SITE_NAME },
- )}
-
-
{props.intl.formatMessage(messages['id.verification.privacy.need.photo.answer'])}
-
- {props.intl.formatMessage(
- messages['id.verification.privacy.do.with.photo.question'],
- { siteName: getConfig().SITE_NAME },
- )}
-
-
- {props.intl.formatMessage(
- messages['id.verification.privacy.do.with.photo.answer'],
- { siteName: getConfig().SITE_NAME },
- )}
-
-
-
-
-
-
- Close
-
-
-
-
+ useEffect(() => {
+ navigate('/id-verification/review-requirements');
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+ return (
+
+
+
+
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+
+
+
- >
+
setIsModalOpen(false)}
+ size="lg"
+ hasCloseButton={false}
+ >
+
+
+ {props.intl.formatMessage(messages['id.verification.privacy.title'])}
+
+
+
+
+
+ {props.intl.formatMessage(
+ messages['id.verification.privacy.need.photo.question'],
+ { siteName: getConfig().SITE_NAME },
+ )}
+
+
{props.intl.formatMessage(messages['id.verification.privacy.need.photo.answer'])}
+
+ {props.intl.formatMessage(
+ messages['id.verification.privacy.do.with.photo.question'],
+ { siteName: getConfig().SITE_NAME },
+ )}
+
+
+ {props.intl.formatMessage(
+ messages['id.verification.privacy.do.with.photo.answer'],
+ { siteName: getConfig().SITE_NAME },
+ )}
+
+
+
+
+
+
+ Close
+
+
+
+
+
+
);
};
diff --git a/src/id-verification/panels/BasePanel.jsx b/src/id-verification/panels/BasePanel.jsx
index 95f3f32..f2e174b 100644
--- a/src/id-verification/panels/BasePanel.jsx
+++ b/src/id-verification/panels/BasePanel.jsx
@@ -1,6 +1,6 @@
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
-import { Redirect } from 'react-router';
+import { Navigate } from 'react-router-dom';
import { useVerificationRedirectSlug } from '../routing-utilities';
const BasePanel = ({
@@ -20,7 +20,7 @@ const BasePanel = ({
const redirectSlug = useVerificationRedirectSlug(name);
if (redirectSlug) {
- return
;
+ return
;
}
return (
diff --git a/src/id-verification/panels/GetNameIdPanel.jsx b/src/id-verification/panels/GetNameIdPanel.jsx
index 69a8071..8bd9ab6 100644
--- a/src/id-verification/panels/GetNameIdPanel.jsx
+++ b/src/id-verification/panels/GetNameIdPanel.jsx
@@ -2,7 +2,7 @@ import React, {
useContext, useEffect, useRef,
} from 'react';
import { Form } from '@edx/paragon';
-import { Link, useHistory } from 'react-router-dom';
+import { Link, useNavigate, useLocation } from 'react-router-dom';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useNextPanelSlug } from '../routing-utilities';
@@ -12,7 +12,8 @@ import IdVerificationContext from '../IdVerificationContext';
import messages from '../IdVerification.messages';
const GetNameIdPanel = (props) => {
- const { push, location } = useHistory();
+ const location = useLocation();
+ const navigate = useNavigate();
const nameInputRef = useRef();
const panelSlug = 'get-name-id';
const nextPanelSlug = useNextPanelSlug(panelSlug);
@@ -33,7 +34,7 @@ const GetNameIdPanel = (props) => {
const handleSubmit = (e) => {
e.preventDefault();
if (idPhotoName) {
- push(nextPanelSlug);
+ navigate(`/id-verification/${nextPanelSlug}`);
}
};
@@ -79,7 +80,7 @@ const GetNameIdPanel = (props) => {
{
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/panels/PortraitPhotoContextPanel.jsx b/src/id-verification/panels/PortraitPhotoContextPanel.jsx
index 5fac850..cb0c90f 100644
--- a/src/id-verification/panels/PortraitPhotoContextPanel.jsx
+++ b/src/id-verification/panels/PortraitPhotoContextPanel.jsx
@@ -38,7 +38,7 @@ const PortraitPhotoContextPanel = (props) => {
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/panels/RequestCameraAccessPanel.jsx b/src/id-verification/panels/RequestCameraAccessPanel.jsx
index 3cd0439..f73f56a 100644
--- a/src/id-verification/panels/RequestCameraAccessPanel.jsx
+++ b/src/id-verification/panels/RequestCameraAccessPanel.jsx
@@ -85,7 +85,7 @@ const RequestCameraAccessPanel = (props) => {
{props.intl.formatMessage(messages['id.verification.camera.access.success'])}
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/panels/ReviewRequirementsPanel.jsx b/src/id-verification/panels/ReviewRequirementsPanel.jsx
index bb45bdf..b43885c 100644
--- a/src/id-verification/panels/ReviewRequirementsPanel.jsx
+++ b/src/id-verification/panels/ReviewRequirementsPanel.jsx
@@ -118,7 +118,7 @@ const ReviewRequirementsPanel = (props) => {
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/panels/SummaryPanel.jsx b/src/id-verification/panels/SummaryPanel.jsx
index 1ce1d62..9c2a366 100644
--- a/src/id-verification/panels/SummaryPanel.jsx
+++ b/src/id-verification/panels/SummaryPanel.jsx
@@ -1,9 +1,9 @@
import React, { useState, useContext, useEffect } from 'react';
-import { getConfig, history } from '@edx/frontend-platform';
+import { getConfig } from '@edx/frontend-platform';
import {
Alert, Hyperlink, Form, Button, Spinner,
} from '@edx/paragon';
-import { Link } from 'react-router-dom';
+import { Link, useNavigate } from 'react-router-dom';
import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n';
import { submitIdVerification } from '../data/service';
@@ -31,6 +31,7 @@ const SummaryPanel = (props) => {
const nameToBeUsed = idPhotoName || nameOnAccount || '';
const [isSubmitting, setIsSubmitting] = useState(false);
const [submissionError, setSubmissionError] = useState(null);
+ const navigate = useNavigate();
useEffect(() => setReachedSummary(true), [setReachedSummary]);
@@ -80,7 +81,7 @@ const SummaryPanel = (props) => {
const result = await submitIdVerification(verificationData);
if (result.success) {
stopUserMedia();
- history.push(nextPanelSlug);
+ navigate(`/id-verification/${nextPanelSlug}`);
} else {
stopUserMedia();
setIsSubmitting(false);
@@ -171,10 +172,8 @@ const SummaryPanel = (props) => {
/>
{props.intl.formatMessage(messages['id.verification.review.portrait.retake'])}
@@ -191,10 +190,8 @@ const SummaryPanel = (props) => {
/>
{props.intl.formatMessage(messages['id.verification.review.id.retake'])}
@@ -219,10 +216,8 @@ const SummaryPanel = (props) => {
{!profileDataManager && (
{
{useCameraForId && }
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/panels/TakePortraitPhotoPanel.jsx b/src/id-verification/panels/TakePortraitPhotoPanel.jsx
index d7855cf..eccb0c5 100644
--- a/src/id-verification/panels/TakePortraitPhotoPanel.jsx
+++ b/src/id-verification/panels/TakePortraitPhotoPanel.jsx
@@ -35,7 +35,7 @@ const TakePortraitPhotoPanel = (props) => {
-
+
{props.intl.formatMessage(messages['id.verification.next'])}
diff --git a/src/id-verification/tests/AccessBlocked.test.jsx b/src/id-verification/tests/AccessBlocked.test.jsx
index 134dfc5..e35769c 100644
--- a/src/id-verification/tests/AccessBlocked.test.jsx
+++ b/src/id-verification/tests/AccessBlocked.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen,
} from '@testing-library/react';
@@ -12,8 +11,6 @@ import AccessBlocked from '../AccessBlocked';
const IntlAccessBlocked = injectIntl(AccessBlocked);
-const history = createMemoryHistory();
-
describe('AccessBlocked', () => {
const defaultProps = {
intl: {},
@@ -28,7 +25,7 @@ describe('AccessBlocked', () => {
defaultProps.error = ERROR_REASONS.EXISTING_REQUEST;
await act(async () => render((
-
+
@@ -44,7 +41,7 @@ describe('AccessBlocked', () => {
defaultProps.error = ERROR_REASONS.COURSE_ENROLLMENT;
await act(async () => render((
-
+
@@ -60,7 +57,7 @@ describe('AccessBlocked', () => {
defaultProps.error = ERROR_REASONS.CANNOT_VERIFY;
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/Camera.test.jsx b/src/id-verification/tests/Camera.test.jsx
index b483bb3..8b33158 100644
--- a/src/id-verification/tests/Camera.test.jsx
+++ b/src/id-verification/tests/Camera.test.jsx
@@ -1,7 +1,6 @@
/* eslint-disable no-import-assign */
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, screen, act, fireEvent,
} from '@testing-library/react';
@@ -22,8 +21,6 @@ window.HTMLMediaElement.prototype.play = () => {};
const IntlCamera = injectIntl(Camera);
-const history = createMemoryHistory();
-
describe('SubmittedPanel', () => {
const defaultProps = {
intl: {},
@@ -45,7 +42,7 @@ describe('SubmittedPanel', () => {
it('takes photo', async () => {
await act(async () => render((
-
+
@@ -61,7 +58,7 @@ describe('SubmittedPanel', () => {
it('shows correct help text for portrait photo capture', async () => {
await act(async () => render((
-
+
@@ -75,7 +72,7 @@ describe('SubmittedPanel', () => {
it('shows correct help text for id photo capture', async () => {
await act(async () => render((
-
+
@@ -90,7 +87,7 @@ describe('SubmittedPanel', () => {
it('shows spinner when loading face detection', async () => {
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
await act(async () => render((
-
+
@@ -108,7 +105,7 @@ describe('SubmittedPanel', () => {
it('canvas is visible when detection is enabled', async () => {
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
await act(async () => render((
-
+
@@ -128,7 +125,7 @@ describe('SubmittedPanel', () => {
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
await act(async () => render((
-
+
@@ -147,7 +144,7 @@ describe('SubmittedPanel', () => {
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
await act(async () => render((
-
+
@@ -168,7 +165,7 @@ describe('SubmittedPanel', () => {
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/CollapsibleImageHelp.test.jsx b/src/id-verification/tests/CollapsibleImageHelp.test.jsx
index 9ae3895..181ee16 100644
--- a/src/id-verification/tests/CollapsibleImageHelp.test.jsx
+++ b/src/id-verification/tests/CollapsibleImageHelp.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, screen, act,
} from '@testing-library/react';
@@ -20,8 +19,6 @@ window.HTMLMediaElement.prototype.play = () => {};
const IntlCollapsible = injectIntl(CollapsibleImageHelp);
-const history = createMemoryHistory();
-
describe('CollapsibleImageHelpPanel', () => {
const defaultProps = { intl: {} };
@@ -36,7 +33,7 @@ describe('CollapsibleImageHelpPanel', () => {
it('shows the correct text if user should switch to upload', async () => {
await act(async () => render((
-
+
@@ -56,7 +53,7 @@ describe('CollapsibleImageHelpPanel', () => {
it('shows the correct text if user should switch to camera', async () => {
contextValue.useCameraForId = false;
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/IdVerificationPage.test.jsx b/src/id-verification/tests/IdVerificationPage.test.jsx
index 96ecb3e..c6d5a5c 100644
--- a/src/id-verification/tests/IdVerificationPage.test.jsx
+++ b/src/id-verification/tests/IdVerificationPage.test.jsx
@@ -1,8 +1,7 @@
/* eslint-disable react/jsx-no-useless-fragment */
import React from 'react';
import { Provider } from 'react-redux';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { MemoryRouter as Router } from 'react-router-dom';
import configureStore from 'redux-mock-store';
import {
render, act, screen, fireEvent,
@@ -50,7 +49,6 @@ jest.mock('../panels/SubmittedPanel', () => function SubmittedPanelMock() {
const IntlIdVerificationPage = injectIntl(IdVerificationPage);
const mockStore = configureStore();
-const history = createMemoryHistory();
describe('IdVerificationPage', () => {
selectors.mockClear();
@@ -60,9 +58,8 @@ describe('IdVerificationPage', () => {
intl: {},
};
it('decodes and stores course_id', async () => {
- history.push(`/?course_id=${encodeURIComponent('course-v1:edX+DemoX+Demo_Course')}`);
await act(async () => render((
-
+
@@ -77,9 +74,8 @@ describe('IdVerificationPage', () => {
});
it('stores `next` value', async () => {
- history.push('/?next=dashboard');
await act(async () => render((
-
+
@@ -93,9 +89,8 @@ describe('IdVerificationPage', () => {
);
});
it('shows modal on click of button', async () => {
- history.push('/?next=dashboard');
await act(async () => render((
-
+
@@ -108,9 +103,8 @@ describe('IdVerificationPage', () => {
expect(screen.getByTestId('Id-modal')).toBeInTheDocument();
});
it('shows modal on click of button', async () => {
- history.push('/?next=dashboard');
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/panels/GetNameIdPanel.test.jsx b/src/id-verification/tests/panels/GetNameIdPanel.test.jsx
index d26dd2c..e86bdbe 100644
--- a/src/id-verification/tests/panels/GetNameIdPanel.test.jsx
+++ b/src/id-verification/tests/panels/GetNameIdPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -16,8 +15,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
const IntlGetNameIdPanel = injectIntl(GetNameIdPanel);
-const history = createMemoryHistory();
-
describe('GetNameIdPanel', () => {
const defaultProps = {
intl: {},
@@ -36,7 +33,7 @@ describe('GetNameIdPanel', () => {
const getPanel = async (idVerificationContextValue = IDVerificationContextValue) => {
await act(async () => render((
-
+
@@ -82,6 +79,6 @@ describe('GetNameIdPanel', () => {
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/summary');
+ expect(window.location.pathname).toEqual('/id-verification/summary');
});
});
diff --git a/src/id-verification/tests/panels/IdContextPanel.test.jsx b/src/id-verification/tests/panels/IdContextPanel.test.jsx
index d32a564..6fbea76 100644
--- a/src/id-verification/tests/panels/IdContextPanel.test.jsx
+++ b/src/id-verification/tests/panels/IdContextPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -15,8 +14,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
const IntlIdContextPanel = injectIntl(IdContextPanel);
-const history = createMemoryHistory();
-
describe('IdContextPanel', () => {
const defaultProps = {
intl: {},
@@ -33,7 +30,7 @@ describe('IdContextPanel', () => {
it('routes to TakeIdPhotoPanel normally', async () => {
await act(async () => render((
-
+
@@ -43,13 +40,13 @@ describe('IdContextPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-id-photo');
+ expect(window.location.pathname).toEqual('/id-verification/take-id-photo');
});
it('routes to TakeIdPhotoPanel if reachedSummary is true', async () => {
contextValue.reachedSummary = true;
await act(async () => render((
-
+
@@ -59,6 +56,6 @@ describe('IdContextPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-id-photo');
+ expect(window.location.pathname).toEqual('/id-verification/take-id-photo');
});
});
diff --git a/src/id-verification/tests/panels/PortraitPhotoContextPanel.test.jsx b/src/id-verification/tests/panels/PortraitPhotoContextPanel.test.jsx
index a43580f..18a44b4 100644
--- a/src/id-verification/tests/panels/PortraitPhotoContextPanel.test.jsx
+++ b/src/id-verification/tests/panels/PortraitPhotoContextPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -15,8 +14,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
const IntlPortraitPhotoContextPanel = injectIntl(PortraitPhotoContextPanel);
-const history = createMemoryHistory();
-
describe('PortraitPhotoContextPanel', () => {
const defaultProps = {
intl: {},
@@ -30,7 +27,7 @@ describe('PortraitPhotoContextPanel', () => {
it('routes to TakePortraitPhotoPanel normally', async () => {
await act(async () => render((
-
+
@@ -40,13 +37,13 @@ describe('PortraitPhotoContextPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-portrait-photo');
+ expect(window.location.pathname).toEqual('/id-verification/take-portrait-photo');
});
it('routes to TakePortraitPhotoPanel if reachedSummary is true', async () => {
contextValue.reachedSummary = true;
await act(async () => render((
-
+
@@ -56,6 +53,6 @@ describe('PortraitPhotoContextPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-portrait-photo');
+ expect(window.location.pathname).toEqual('/id-verification/take-portrait-photo');
});
});
diff --git a/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx b/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx
index 3c9d8ba..7f8db44 100644
--- a/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx
+++ b/src/id-verification/tests/panels/RequestCameraAccessPanel.test.jsx
@@ -1,7 +1,6 @@
import React from 'react';
-import { Router } from 'react-router-dom';
+import { BrowserRouter as Router } from 'react-router-dom';
import Bowser from 'bowser';
-import { createMemoryHistory } from 'history';
import {
render, screen, cleanup, act, fireEvent,
} from '@testing-library/react';
@@ -16,8 +15,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
jest.mock('bowser');
-const history = createMemoryHistory();
-
const IntlRequestCameraAccessPanel = injectIntl(RequestCameraAccessPanel);
describe('RequestCameraAccessPanel', () => {
@@ -38,7 +35,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'pending';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -54,7 +51,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'granted';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -66,14 +63,14 @@ describe('RequestCameraAccessPanel', () => {
expect(text).toHaveTextContent(/Looks like your camera is working and ready./);
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/portrait-photo-context');
+ expect(window.location.pathname).toEqual('/id-verification/portrait-photo-context');
});
it('renders correctly with media access denied', async () => {
contextValue.mediaAccess = 'denied';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -89,7 +86,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'unsupported';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Chrome' } });
await act(async () => render((
-
+
@@ -106,7 +103,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'unsupported';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -123,7 +120,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'denied';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Chrome' } });
await act(async () => render((
-
+
@@ -139,7 +136,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'denied';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Firefox' } });
await act(async () => render((
-
+
@@ -155,7 +152,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'denied';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Safari' } });
await act(async () => render((
-
+
@@ -171,7 +168,7 @@ describe('RequestCameraAccessPanel', () => {
contextValue.mediaAccess = 'denied';
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Internet Explorer' } });
await act(async () => render((
-
+
@@ -188,7 +185,7 @@ describe('RequestCameraAccessPanel', () => {
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -205,7 +202,7 @@ describe('RequestCameraAccessPanel', () => {
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
await act(async () => render((
-
+
@@ -215,6 +212,6 @@ describe('RequestCameraAccessPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/portrait-photo-context');
+ expect(window.location.pathname).toEqual('/id-verification/portrait-photo-context');
});
});
diff --git a/src/id-verification/tests/panels/ReviewRequirementsPanel.test.jsx b/src/id-verification/tests/panels/ReviewRequirementsPanel.test.jsx
index 2c7c040..3771443 100644
--- a/src/id-verification/tests/panels/ReviewRequirementsPanel.test.jsx
+++ b/src/id-verification/tests/panels/ReviewRequirementsPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -15,8 +14,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
const IntlReviewRequirementsPanel = injectIntl(ReviewRequirementsPanel);
-const history = createMemoryHistory();
-
describe('ReviewRequirementsPanel', () => {
const defaultProps = {
intl: {},
@@ -26,7 +23,7 @@ describe('ReviewRequirementsPanel', () => {
const getPanel = async () => {
await act(async () => render((
-
+
@@ -44,7 +41,7 @@ describe('ReviewRequirementsPanel', () => {
await getPanel();
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/request-camera-access');
+ expect(window.location.pathname).toEqual('/id-verification/request-camera-access');
});
it('displays an alert if the user\'s account information is managed by a third party', async () => {
diff --git a/src/id-verification/tests/panels/SubmittedPanel.test.jsx b/src/id-verification/tests/panels/SubmittedPanel.test.jsx
index e7f88f5..215e312 100644
--- a/src/id-verification/tests/panels/SubmittedPanel.test.jsx
+++ b/src/id-verification/tests/panels/SubmittedPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen,
} from '@testing-library/react';
@@ -15,8 +14,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
const IntlSubmittedPanel = injectIntl(SubmittedPanel);
-const history = createMemoryHistory();
-
describe('SubmittedPanel', () => {
const defaultProps = {
intl: {},
@@ -43,7 +40,7 @@ describe('SubmittedPanel', () => {
it('links to dashboard without courseId or next value', async () => {
await act(async () => render((
-
+
@@ -59,7 +56,7 @@ describe('SubmittedPanel', () => {
it('links to course when courseId is stored', async () => {
sessionStorage.setItem('courseId', 'course-v1:edX+DemoX+Demo_Course');
await act(async () => render((
-
+
@@ -75,7 +72,7 @@ describe('SubmittedPanel', () => {
it('links to specified page when `next` value is provided', async () => {
sessionStorage.setItem('next', 'some_page');
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/panels/SummaryPanel.test.jsx b/src/id-verification/tests/panels/SummaryPanel.test.jsx
index 84364ca..8ca15bf 100644
--- a/src/id-verification/tests/panels/SummaryPanel.test.jsx
+++ b/src/id-verification/tests/panels/SummaryPanel.test.jsx
@@ -1,6 +1,6 @@
/* eslint-disable no-import-assign */
import React from 'react';
-import { Router } from 'react-router-dom';
+import { BrowserRouter as Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';
import {
render, cleanup, act, screen, fireEvent, waitFor,
@@ -61,16 +61,14 @@ describe('SummaryPanel', () => {
await getPanel();
const button = await screen.findByTestId('portrait-retake');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-portrait-photo');
- expect(history.location.state.fromSummary).toEqual(true);
+ expect(window.location.pathname).toEqual('/id-verification/take-portrait-photo');
});
it('routes back to TakeIdPhotoPanel', async () => {
await getPanel();
const button = await screen.findByTestId('id-retake');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/take-id-photo');
- expect(history.location.state.fromSummary).toEqual(true);
+ expect(window.location.pathname).toEqual('/id-verification/take-id-photo');
});
it('allows user to upload ID photo', async () => {
diff --git a/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx b/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx
index 0672bff..8f92a20 100644
--- a/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx
+++ b/src/id-verification/tests/panels/TakeIdPhotoPanel.test.jsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -14,8 +13,6 @@ jest.mock('@edx/frontend-platform/analytics', () => ({
jest.mock('../../Camera');
-const history = createMemoryHistory();
-
const IntlTakeIdPhotoPanel = injectIntl(TakeIdPhotoPanel);
describe('TakeIdPhotoPanel', () => {
@@ -37,7 +34,7 @@ describe('TakeIdPhotoPanel', () => {
it('doesn\'t show next button before photo is taken', async () => {
await act(async () => render((
-
+
@@ -52,7 +49,7 @@ describe('TakeIdPhotoPanel', () => {
it('shows next button after photo is taken and routes to GetNameIdPanel', async () => {
contextValue.idPhotoFile = 'test.jpg';
await act(async () => render((
-
+
@@ -63,14 +60,14 @@ describe('TakeIdPhotoPanel', () => {
const button = await screen.findByTestId('next-button');
expect(button).toBeVisible();
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/get-name-id');
+ expect(window.location.pathname).toEqual('/id-verification/get-name-id');
});
it('routes back to SummaryPanel if that was the source', async () => {
contextValue.idPhotoFile = 'test.jpg';
contextValue.reachedSummary = true;
await act(async () => render((
-
+
@@ -80,12 +77,12 @@ describe('TakeIdPhotoPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/summary');
+ expect(window.location.pathname).toEqual('/id-verification/summary');
});
it('shows correct text if user should use upload', async () => {
await act(async () => render((
-
+
diff --git a/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx b/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx
index 52b4457..816fafc 100644
--- a/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx
+++ b/src/id-verification/tests/panels/TakePortraitPhotoPanel.test.jsx
@@ -1,7 +1,6 @@
/* eslint-disable react/jsx-no-useless-fragment */
import React from 'react';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter as Router } from 'react-router-dom';
import {
render, cleanup, act, screen, fireEvent,
} from '@testing-library/react';
@@ -17,8 +16,6 @@ jest.mock('../../Camera', () => function CameraMock() {
return <>>;
});
-const history = createMemoryHistory();
-
const IntlTakePortraitPhotoPanel = injectIntl(TakePortraitPhotoPanel);
describe('TakePortraitPhotoPanel', () => {
@@ -39,7 +36,7 @@ describe('TakePortraitPhotoPanel', () => {
it('doesn\'t show next button before photo is taken', async () => {
await act(async () => render((
-
+
@@ -54,7 +51,7 @@ describe('TakePortraitPhotoPanel', () => {
it('shows next button after photo is taken and routes to IdContextPanel', async () => {
contextValue.facePhotoFile = 'test.jpg';
await act(async () => render((
-
+
@@ -65,7 +62,7 @@ describe('TakePortraitPhotoPanel', () => {
const button = await screen.findByTestId('next-button');
expect(button).toBeVisible();
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/id-context');
+ expect(window.location.pathname).toEqual('/id-verification/id-context');
});
it('routes back to SummaryPanel if that was the source', async () => {
@@ -73,7 +70,7 @@ describe('TakePortraitPhotoPanel', () => {
contextValue.idPhotoFile = 'test.jpg';
contextValue.reachedSummary = true;
await act(async () => render((
-
+
@@ -83,6 +80,6 @@ describe('TakePortraitPhotoPanel', () => {
)));
const button = await screen.findByTestId('next-button');
fireEvent.click(button);
- expect(history.location.pathname).toEqual('/summary');
+ expect(window.location.pathname).toEqual('/id-verification/summary');
});
});
diff --git a/src/index.jsx b/src/index.jsx
index daf9e10..e3e4504 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -8,7 +8,7 @@ import {
} from '@edx/frontend-platform';
import React from 'react';
import ReactDOM from 'react-dom';
-import { Route, Switch } from 'react-router-dom';
+import { Route, Routes, Outlet } from 'react-router-dom';
import Header from '@edx/frontend-component-header';
import Footer from '@edx/frontend-component-footer';
@@ -28,23 +28,26 @@ subscribe(APP_READY, () => {
ReactDOM.render(
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ } />
+
+
+
+
+
+
+
+ )}
+ >
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
,
document.getElementById('root'),
);
diff --git a/src/notification-preferences/NotificationPreferences.jsx b/src/notification-preferences/NotificationPreferences.jsx
index 990c50b..6c6d301 100644
--- a/src/notification-preferences/NotificationPreferences.jsx
+++ b/src/notification-preferences/NotificationPreferences.jsx
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
-import { useParams } from 'react-router';
-import { Link } from 'react-router-dom';
+import { Link, useParams } from 'react-router-dom';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Container, Icon, Spinner } from '@edx/paragon';
import { ArrowBack } from '@edx/paragon/icons';