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
This commit is contained in:
committed by
GitHub
parent
e7e7f518bf
commit
3d98558bf6
208
package-lock.json
generated
208
package-lock.json
generated
@@ -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",
|
||||
|
||||
10
package.json
10
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",
|
||||
|
||||
@@ -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 => (
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>{children}</Provider>
|
||||
</IntlProvider>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 => (
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>{children}</Provider>
|
||||
</IntlProvider>
|
||||
@@ -168,6 +165,6 @@ describe('NameChange', () => {
|
||||
props.saveState = 'complete';
|
||||
|
||||
render(reduxWrapper(<IntlNameChange {...props} />));
|
||||
expect(history.location.pathname).toEqual('/id-verification');
|
||||
expect(window.location.pathname).toEqual('/id-verification');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 <NavLink> outside a <Router>"
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<AppProvider store={store}>
|
||||
<IntlJumpNav {...props} />
|
||||
</AppProvider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
<IntlProvider locale="en">
|
||||
<AppProvider store={store}>
|
||||
<IntlJumpNav {...props} />
|
||||
</AppProvider>
|
||||
</IntlProvider>
|
||||
))
|
||||
.toJSON();
|
||||
|
||||
@@ -67,14 +62,11 @@ describe('JumpNav', () => {
|
||||
};
|
||||
|
||||
const tree = renderer.create((
|
||||
// Same as previous test
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<AppProvider store={store}>
|
||||
<IntlJumpNav {...props} />
|
||||
</AppProvider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
<IntlProvider locale="en">
|
||||
<AppProvider store={store}>
|
||||
<IntlJumpNav {...props} />
|
||||
</AppProvider>
|
||||
</IntlProvider>
|
||||
))
|
||||
.toJSON();
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#basic-information"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Account Information
|
||||
@@ -23,8 +25,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#profile-information"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Profile Information
|
||||
@@ -34,8 +38,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#social-media"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Social Media Links
|
||||
@@ -45,8 +51,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#site-preferences"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Site Preferences
|
||||
@@ -56,8 +64,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#linked-accounts"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Linked Accounts
|
||||
@@ -67,8 +77,10 @@ exports[`JumpNav should not render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#delete-account"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Delete My Account
|
||||
@@ -90,8 +102,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#basic-information"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Account Information
|
||||
@@ -101,8 +115,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#profile-information"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Profile Information
|
||||
@@ -112,8 +128,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#demographics-information"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Optional Information
|
||||
@@ -123,8 +141,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#social-media"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Social Media Links
|
||||
@@ -134,8 +154,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#site-preferences"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Site Preferences
|
||||
@@ -145,8 +167,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#linked-accounts"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Linked Accounts
|
||||
@@ -156,8 +180,10 @@ exports[`JumpNav should render Optional Information link 1`] = `
|
||||
className=""
|
||||
>
|
||||
<a
|
||||
aria-current={null}
|
||||
aria-current="page"
|
||||
className="active"
|
||||
href="/#delete-account"
|
||||
isActive={[Function]}
|
||||
onClick={[Function]}
|
||||
>
|
||||
Delete My Account
|
||||
|
||||
@@ -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 */}
|
||||
<Redirect to={`${path}/review-requirements`} />
|
||||
<div className="page__id-verification container-fluid py-5">
|
||||
<div className="row">
|
||||
<div className="col-lg-6 col-md-8">
|
||||
<VerifiedNameContextProvider>
|
||||
<IdVerificationContextProvider>
|
||||
<Switch>
|
||||
<Route path={`${path}/review-requirements`} component={ReviewRequirementsPanel} />
|
||||
<Route path={`${path}/request-camera-access`} component={RequestCameraAccessPanel} />
|
||||
<Route path={`${path}/portrait-photo-context`} component={PortraitPhotoContextPanel} />
|
||||
<Route path={`${path}/take-portrait-photo`} component={TakePortraitPhotoPanel} />
|
||||
<Route path={`${path}/id-context`} component={IdContextPanel} />
|
||||
<Route path={`${path}/get-name-id`} component={GetNameIdPanel} />
|
||||
<Route path={`${path}/take-id-photo`} component={TakeIdPhotoPanel} />
|
||||
<Route path={`${path}/summary`} component={SummaryPanel} />
|
||||
<Route path={`${path}/submitted`} component={SubmittedPanel} />
|
||||
</Switch>
|
||||
</IdVerificationContextProvider>
|
||||
</VerifiedNameContextProvider>
|
||||
</div>
|
||||
<div className="col-lg-6 col-md-4 pt-md-0 pt-4 text-right">
|
||||
<Button variant="link" className="px-0" onClick={() => setIsModalOpen(true)}>
|
||||
Privacy Information
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<ModalDialog
|
||||
isOpen={isModalOpen}
|
||||
title="Id modal"
|
||||
onClose={() => setIsModalOpen(false)}
|
||||
size="lg"
|
||||
hasCloseButton={false}
|
||||
>
|
||||
<ModalDialog.Header>
|
||||
<ModalDialog.Title data-testid="Id-modal">
|
||||
{props.intl.formatMessage(messages['id.verification.privacy.title'])}
|
||||
</ModalDialog.Title>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<div className="p-3">
|
||||
<h6>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.need.photo.question'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</h6>
|
||||
<p>{props.intl.formatMessage(messages['id.verification.privacy.need.photo.answer'])}</p>
|
||||
<h6>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.do.with.photo.question'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</h6>
|
||||
<p>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.do.with.photo.answer'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer className="p-2">
|
||||
<ActionRow>
|
||||
<ModalDialog.CloseButton variant="link">
|
||||
Close
|
||||
</ModalDialog.CloseButton>
|
||||
</ActionRow>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
useEffect(() => {
|
||||
navigate('/id-verification/review-requirements');
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="page__id-verification container-fluid py-5">
|
||||
<div className="row">
|
||||
<div className="col-lg-6 col-md-8">
|
||||
<VerifiedNameContextProvider>
|
||||
<IdVerificationContextProvider>
|
||||
<Routes>
|
||||
<Route path="/review-requirements" element={<ReviewRequirementsPanel />} />
|
||||
<Route path="/request-camera-access" element={<RequestCameraAccessPanel />} />
|
||||
<Route path="/portrait-photo-context" element={<PortraitPhotoContextPanel />} />
|
||||
<Route path="/take-portrait-photo" element={<TakePortraitPhotoPanel />} />
|
||||
<Route path="/id-context" element={<IdContextPanel />} />
|
||||
<Route path="/get-name-id" element={<GetNameIdPanel />} />
|
||||
<Route path="/take-id-photo" element={<TakeIdPhotoPanel />} />
|
||||
<Route path="/summary" element={<SummaryPanel />} />
|
||||
<Route path="/submitted" element={<SubmittedPanel />} />
|
||||
</Routes>
|
||||
</IdVerificationContextProvider>
|
||||
</VerifiedNameContextProvider>
|
||||
</div>
|
||||
<div className="col-lg-6 col-md-4 pt-md-0 pt-4 text-right">
|
||||
<Button variant="link" className="px-0" onClick={() => setIsModalOpen(true)}>
|
||||
Privacy Information
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
<ModalDialog
|
||||
isOpen={isModalOpen}
|
||||
title="Id modal"
|
||||
onClose={() => setIsModalOpen(false)}
|
||||
size="lg"
|
||||
hasCloseButton={false}
|
||||
>
|
||||
<ModalDialog.Header>
|
||||
<ModalDialog.Title data-testid="Id-modal">
|
||||
{props.intl.formatMessage(messages['id.verification.privacy.title'])}
|
||||
</ModalDialog.Title>
|
||||
</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<div className="p-3">
|
||||
<h6>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.need.photo.question'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</h6>
|
||||
<p>{props.intl.formatMessage(messages['id.verification.privacy.need.photo.answer'])}</p>
|
||||
<h6>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.do.with.photo.question'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</h6>
|
||||
<p>
|
||||
{props.intl.formatMessage(
|
||||
messages['id.verification.privacy.do.with.photo.answer'],
|
||||
{ siteName: getConfig().SITE_NAME },
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer className="p-2">
|
||||
<ActionRow>
|
||||
<ModalDialog.CloseButton variant="link">
|
||||
Close
|
||||
</ModalDialog.CloseButton>
|
||||
</ActionRow>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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 <Redirect to={redirectSlug} />;
|
||||
return <Navigate replace to={`/id-verification/${redirectSlug}`} />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
<div className="action-row">
|
||||
<Link
|
||||
to={nextPanelSlug}
|
||||
to={`/id-verification/${nextPanelSlug}`}
|
||||
className={`btn btn-primary ${!idPhotoName && 'disabled'}`}
|
||||
data-testid="next-button"
|
||||
aria-disabled={!idPhotoName}
|
||||
|
||||
@@ -41,7 +41,7 @@ const IdContextPanel = (props) => {
|
||||
</div>
|
||||
<CameraHelp isOpen />
|
||||
<div className="action-row">
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@ const PortraitPhotoContextPanel = (props) => {
|
||||
</div>
|
||||
<CameraHelp isOpen isPortrait />
|
||||
<div className="action-row">
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -85,7 +85,7 @@ const RequestCameraAccessPanel = (props) => {
|
||||
{props.intl.formatMessage(messages['id.verification.camera.access.success'])}
|
||||
</p>
|
||||
<div className="action-row">
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -118,7 +118,7 @@ const ReviewRequirementsPanel = (props) => {
|
||||
</p>
|
||||
|
||||
<div className="action-row">
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -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) => {
|
||||
/>
|
||||
<Link
|
||||
className="btn btn-outline-primary"
|
||||
to={{
|
||||
pathname: 'take-portrait-photo',
|
||||
state: { fromSummary: true },
|
||||
}}
|
||||
to="/id-verification/take-portrait-photo"
|
||||
state={{ fromSummary: true }}
|
||||
data-testid="portrait-retake"
|
||||
>
|
||||
{props.intl.formatMessage(messages['id.verification.review.portrait.retake'])}
|
||||
@@ -191,10 +190,8 @@ const SummaryPanel = (props) => {
|
||||
/>
|
||||
<Link
|
||||
className="btn btn-outline-primary"
|
||||
to={{
|
||||
pathname: 'take-id-photo',
|
||||
state: { fromSummary: true },
|
||||
}}
|
||||
to="/id-verification/take-id-photo"
|
||||
state={{ fromSummary: true }}
|
||||
data-testid="id-retake"
|
||||
>
|
||||
{props.intl.formatMessage(messages['id.verification.review.id.retake'])}
|
||||
@@ -219,10 +216,8 @@ const SummaryPanel = (props) => {
|
||||
{!profileDataManager && (
|
||||
<Link
|
||||
className="btn btn-link ml-3 px-0"
|
||||
to={{
|
||||
pathname: 'get-name-id',
|
||||
state: { fromSummary: true },
|
||||
}}
|
||||
to="/id-verification/get-name-id"
|
||||
state={{ fromSummary: true }}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="id.verification.account.name.edit"
|
||||
|
||||
@@ -61,7 +61,7 @@ const TakeIdPhotoPanel = (props) => {
|
||||
{useCameraForId && <CameraHelp />}
|
||||
<CollapsibleImageHelp />
|
||||
<div className="action-row" style={{ visibility: idPhotoFile ? 'unset' : 'hidden' }}>
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@ const TakePortraitPhotoPanel = (props) => {
|
||||
</div>
|
||||
<CameraHelp isPortrait />
|
||||
<div className="action-row" style={{ visibility: facePhotoFile ? 'unset' : 'hidden' }}>
|
||||
<Link to={nextPanelSlug} className="btn btn-primary" data-testid="next-button">
|
||||
<Link to={`/id-verification/${nextPanelSlug}`} className="btn btn-primary" data-testid="next-button">
|
||||
{props.intl.formatMessage(messages['id.verification.next'])}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IntlAccessBlocked {...defaultProps} />
|
||||
</IntlProvider>
|
||||
@@ -44,7 +41,7 @@ describe('AccessBlocked', () => {
|
||||
defaultProps.error = ERROR_REASONS.COURSE_ENROLLMENT;
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IntlAccessBlocked {...defaultProps} />
|
||||
</IntlProvider>
|
||||
@@ -60,7 +57,7 @@ describe('AccessBlocked', () => {
|
||||
defaultProps.error = ERROR_REASONS.CANNOT_VERIFY;
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IntlAccessBlocked {...defaultProps} />
|
||||
</IntlProvider>
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -61,7 +58,7 @@ describe('SubmittedPanel', () => {
|
||||
|
||||
it('shows correct help text for portrait photo capture', async () => {
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -75,7 +72,7 @@ describe('SubmittedPanel', () => {
|
||||
|
||||
it('shows correct help text for id photo capture', async () => {
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...idProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -128,7 +125,7 @@ describe('SubmittedPanel', () => {
|
||||
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -147,7 +144,7 @@ describe('SubmittedPanel', () => {
|
||||
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...defaultProps} />
|
||||
@@ -168,7 +165,7 @@ describe('SubmittedPanel', () => {
|
||||
blazeface.load = jest.fn().mockResolvedValue({ estimateFaces: jest.fn().mockResolvedValue([]) });
|
||||
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCamera {...idProps} />
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCollapsible {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlCollapsible {...defaultProps} />
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router initialEntries={[`/?course_id=${encodeURIComponent('course-v1:edX+DemoX+Demo_Course')}`]}>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<IntlIdVerificationPage {...props} />
|
||||
@@ -77,9 +74,8 @@ describe('IdVerificationPage', () => {
|
||||
});
|
||||
|
||||
it('stores `next` value', async () => {
|
||||
history.push('/?next=dashboard');
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router initialEntries={['/?next=dashboard']}>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<IntlIdVerificationPage {...props} />
|
||||
@@ -93,9 +89,8 @@ describe('IdVerificationPage', () => {
|
||||
);
|
||||
});
|
||||
it('shows modal on click of button', async () => {
|
||||
history.push('/?next=dashboard');
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router initialEntries={['/?next=dashboard']}>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<IntlIdVerificationPage {...props} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router initialEntries={['/?next=dashboard']}>
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>
|
||||
<IntlIdVerificationPage {...props} />
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<VerifiedNameContext.Provider value={verifiedNameContextValue}>
|
||||
<IdVerificationContext.Provider value={idVerificationContextValue}>
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlIdContextPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlIdContextPanel {...defaultProps} />
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlPortraitPhotoContextPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlPortraitPhotoContextPanel {...defaultProps} />
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -54,7 +51,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'granted';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -89,7 +86,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'unsupported';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Chrome' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -106,7 +103,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'unsupported';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -123,7 +120,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'denied';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Chrome' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -139,7 +136,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'denied';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Firefox' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -155,7 +152,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'denied';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Safari' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -171,7 +168,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
contextValue.mediaAccess = 'denied';
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: 'Internet Explorer' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -188,7 +185,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -205,7 +202,7 @@ describe('RequestCameraAccessPanel', () => {
|
||||
|
||||
Bowser.parse = jest.fn().mockReturnValue({ browser: { name: '' } });
|
||||
await act(async () => render((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlRequestCameraAccessPanel {...defaultProps} />
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={context}>
|
||||
<IntlReviewRequirementsPanel {...defaultProps} />
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlSubmittedPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlSubmittedPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlSubmittedPanel {...defaultProps} />
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakeIdPhotoPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakeIdPhotoPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakeIdPhotoPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakeIdPhotoPanel {...defaultProps} />
|
||||
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakePortraitPhotoPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakePortraitPhotoPanel {...defaultProps} />
|
||||
@@ -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((
|
||||
<Router history={history}>
|
||||
<Router>
|
||||
<IntlProvider locale="en">
|
||||
<IdVerificationContext.Provider value={contextValue}>
|
||||
<IntlTakePortraitPhotoPanel {...defaultProps} />
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
<AppProvider store={configureStore()}>
|
||||
<Head />
|
||||
<Switch>
|
||||
<Route path="/coaching_consent" component={CoachingConsent} />
|
||||
<div className="d-flex flex-column" style={{ minHeight: '100vh' }}>
|
||||
<Header />
|
||||
<main className="flex-grow-1">
|
||||
<Switch>
|
||||
<Route path="/notifications/:courseId" component={NotificationPreferences} />
|
||||
<Route path="/notifications" component={NotificationCourses} />
|
||||
<Route path="/id-verification" component={IdVerificationPage} />
|
||||
<Route exact path="/" component={AccountSettingsPage} />
|
||||
<Route path="/notfound" component={NotFoundPage} />
|
||||
<Route path="*" component={NotFoundPage} />
|
||||
</Switch>
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</Switch>
|
||||
<Routes>
|
||||
<Route path="/coaching_consent" element={<CoachingConsent />} />
|
||||
<Route element={(
|
||||
<div className="d-flex flex-column" style={{ minHeight: '100vh' }}>
|
||||
<Header />
|
||||
<main className="flex-grow-1">
|
||||
<Outlet />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<Route path="/notifications/:courseId" element={<NotificationPreferences />} />
|
||||
<Route path="/notifications" element={<NotificationCourses />} />
|
||||
<Route path="/id-verification/*" element={<IdVerificationPage />} />
|
||||
<Route path="/" element={<AccountSettingsPage />} />
|
||||
<Route path="/notfound" element={<NotFoundPage />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</AppProvider>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user