Compare commits
7 Commits
temp-main
...
open-relea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
046fbeab01 | ||
|
|
27ea509989 | ||
|
|
27f0508e6e | ||
|
|
c53fedf7a1 | ||
|
|
0f1a5e9aef | ||
|
|
6cb4b799b7 | ||
|
|
439b9161b5 |
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
autoupdate:
|
||||
name: autoupdate
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: docker://chinthakagodawita/autoupdate-action:v1
|
||||
env:
|
||||
|
||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [18, 20]
|
||||
|
||||
205
package-lock.json
generated
205
package-lock.json
generated
@@ -32,11 +32,11 @@
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-loading-skeleton": "3.4.0",
|
||||
"react-loading-skeleton": "3.5.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-responsive": "8.2.0",
|
||||
"react-router": "6.26.1",
|
||||
"react-router-dom": "6.26.1",
|
||||
"react-router": "6.26.2",
|
||||
"react-router-dom": "6.26.2",
|
||||
"react-zendesk": "^0.1.13",
|
||||
"redux": "4.2.1",
|
||||
"redux-logger": "3.0.6",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@edx/reactifex": "1.1.0",
|
||||
"@openedx/frontend-build": "^14.0.3",
|
||||
"babel-plugin-formatjs": "10.5.16",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-import": "2.30.0",
|
||||
"glob": "7.2.3",
|
||||
"history": "5.3.0",
|
||||
"husky": "7.0.4",
|
||||
@@ -2017,7 +2017,9 @@
|
||||
"license": "AGPL-3.0"
|
||||
},
|
||||
"node_modules/@edx/eslint-config": {
|
||||
"version": "4.1.0",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/eslint-config/-/eslint-config-4.2.0.tgz",
|
||||
"integrity": "sha512-2wuIw49uyj6gRwS74qJ8WhBU+X2FOP4uot40sthIC4YU9qCM7WJOcOuAhkRPP1FvZKd3UQH3gZM7eJ85xzDBqA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
@@ -2123,7 +2125,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@edx/typescript-config": {
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@edx/typescript-config/-/typescript-config-1.1.0.tgz",
|
||||
"integrity": "sha512-HF+7dsSgA2YQ6f/qV4HnrEYBoIhIdxVQZgDyYk/YGvaVGqT6IFuaHnYUP7ImpCUMOUmx/Jl7EyuVeaMe2LrMcA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"typescript": "^4.9.4"
|
||||
@@ -3078,7 +3082,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/frontend-build": {
|
||||
"version": "14.0.14",
|
||||
"version": "14.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/frontend-build/-/frontend-build-14.1.4.tgz",
|
||||
"integrity": "sha512-DMzkitHqemtqwxmDsF8y7zRVAJcW8URPfWcLKtFvXffqJ3WW7fJXXMmiZWKra/vGBw3SRyYRqvdzQG1d2giPAw==",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@babel/cli": "7.24.8",
|
||||
@@ -3089,9 +3095,9 @@
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/preset-env": "7.24.8",
|
||||
"@babel/preset-react": "7.24.7",
|
||||
"@edx/eslint-config": "4.1.0",
|
||||
"@edx/eslint-config": "4.2.0",
|
||||
"@edx/new-relic-source-map-webpack-plugin": "2.1.0",
|
||||
"@edx/typescript-config": "1.0.1",
|
||||
"@edx/typescript-config": "1.1.0",
|
||||
"@formatjs/cli": "^6.0.3",
|
||||
"@fullhuman/postcss-purgecss": "5.0.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.15",
|
||||
@@ -3099,7 +3105,7 @@
|
||||
"@types/jest": "29.5.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
||||
"@typescript-eslint/parser": "^5.58.0",
|
||||
"autoprefixer": "10.4.19",
|
||||
"autoprefixer": "10.4.20",
|
||||
"babel-jest": "29.6.1",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-plugin-formatjs": "^10.4.0",
|
||||
@@ -3127,7 +3133,8 @@
|
||||
"jest": "29.6.1",
|
||||
"jest-environment-jsdom": "29.6.1",
|
||||
"mini-css-extract-plugin": "1.6.2",
|
||||
"postcss": "8.4.39",
|
||||
"parse5": "7.1.2",
|
||||
"postcss": "8.4.47",
|
||||
"postcss-custom-media": "10.0.8",
|
||||
"postcss-loader": "7.3.4",
|
||||
"postcss-rtlcss": "5.1.2",
|
||||
@@ -3146,7 +3153,8 @@
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-merge": "^5.10.0"
|
||||
"webpack-merge": "^5.10.0",
|
||||
"webpack-remove-empty-scripts": "1.0.4"
|
||||
},
|
||||
"bin": {
|
||||
"fedx-scripts": "bin/fedx-scripts.js"
|
||||
@@ -3157,6 +3165,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/@eslint/js": {
|
||||
"version": "8.44.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
|
||||
"integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -3164,10 +3174,14 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint": {
|
||||
"version": "8.44.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
|
||||
"integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
@@ -3222,6 +3236,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint-plugin-import": {
|
||||
"version": "2.27.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
|
||||
"integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"array-includes": "^3.1.6",
|
||||
@@ -3249,6 +3265,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint-plugin-import/node_modules/debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
@@ -3256,6 +3274,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint-plugin-import/node_modules/doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"esutils": "^2.0.2"
|
||||
@@ -3266,6 +3286,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint-scope": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
||||
"integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
@@ -3280,6 +3302,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/eslint-visitor-keys": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -3290,6 +3314,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/find-up": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^6.0.0",
|
||||
@@ -3304,6 +3330,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/glob-parent": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
@@ -3314,6 +3342,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/globals": {
|
||||
"version": "13.24.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
@@ -3327,6 +3357,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/jest": {
|
||||
"version": "29.6.1",
|
||||
"resolved": "https://registry.npmjs.org/jest/-/jest-29.6.1.tgz",
|
||||
"integrity": "sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jest/core": "^29.6.1",
|
||||
@@ -3351,6 +3383,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
@@ -3361,6 +3395,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^5.0.0"
|
||||
@@ -3374,6 +3410,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/p-locate": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^3.0.2"
|
||||
@@ -3387,6 +3425,8 @@
|
||||
},
|
||||
"node_modules/@openedx/frontend-build/node_modules/type-fest": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -3396,7 +3436,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openedx/paragon": {
|
||||
"version": "22.7.0",
|
||||
"version": "22.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@openedx/paragon/-/paragon-22.8.1.tgz",
|
||||
"integrity": "sha512-lm2x0tvNZrtJvp0L+cjvLLmkE9NoUbNIzt9L1FaOx9g92gf8rFVgq4aadq7IVAjN12HW19/QJMEJaQ0SVsvY2A==",
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
"example",
|
||||
@@ -3447,6 +3489,8 @@
|
||||
},
|
||||
"node_modules/@openedx/paragon/node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.1.19",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz",
|
||||
"integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.8.1"
|
||||
@@ -3458,6 +3502,8 @@
|
||||
},
|
||||
"node_modules/@openedx/paragon/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
@@ -3465,6 +3511,9 @@
|
||||
},
|
||||
"node_modules/@openedx/paragon/node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
@@ -3482,6 +3531,8 @@
|
||||
},
|
||||
"node_modules/@openedx/paragon/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -3721,9 +3772,10 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.1.tgz",
|
||||
"integrity": "sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==",
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
|
||||
"integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
@@ -3745,6 +3797,12 @@
|
||||
"react": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rtsao/scc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||
"integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.27.8",
|
||||
"license": "MIT"
|
||||
@@ -5050,6 +5108,19 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansis": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ansis/-/ansis-1.5.2.tgz",
|
||||
"integrity": "sha512-T3vUABrcgSj/HXv27P+A/JxGk5b/ydx0JjN3lgjBTC2iZUFxQGjh43zCzLSbU4C1QTgmx9oaPeWNJFM+auI8qw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12.13"
|
||||
},
|
||||
"funding": {
|
||||
"type": "patreon",
|
||||
"url": "https://patreon.com/biodiscus"
|
||||
}
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"license": "ISC",
|
||||
@@ -5246,7 +5317,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.19",
|
||||
"version": "10.4.20",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -5263,11 +5336,11 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.0",
|
||||
"caniuse-lite": "^1.0.30001599",
|
||||
"browserslist": "^4.23.3",
|
||||
"caniuse-lite": "^1.0.30001646",
|
||||
"fraction.js": "^4.3.7",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"picocolors": "^1.0.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -7489,7 +7562,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-module-utils": {
|
||||
"version": "2.8.1",
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz",
|
||||
"integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^3.2.7"
|
||||
@@ -7676,24 +7751,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import": {
|
||||
"version": "2.29.1",
|
||||
"version": "2.30.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz",
|
||||
"integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"array-includes": "^3.1.7",
|
||||
"array.prototype.findlastindex": "^1.2.3",
|
||||
"@rtsao/scc": "^1.1.0",
|
||||
"array-includes": "^3.1.8",
|
||||
"array.prototype.findlastindex": "^1.2.5",
|
||||
"array.prototype.flat": "^1.3.2",
|
||||
"array.prototype.flatmap": "^1.3.2",
|
||||
"debug": "^3.2.7",
|
||||
"doctrine": "^2.1.0",
|
||||
"eslint-import-resolver-node": "^0.3.9",
|
||||
"eslint-module-utils": "^2.8.0",
|
||||
"hasown": "^2.0.0",
|
||||
"is-core-module": "^2.13.1",
|
||||
"eslint-module-utils": "^2.9.0",
|
||||
"hasown": "^2.0.2",
|
||||
"is-core-module": "^2.15.1",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "^3.1.2",
|
||||
"object.fromentries": "^2.0.7",
|
||||
"object.groupby": "^1.0.1",
|
||||
"object.values": "^1.1.7",
|
||||
"object.fromentries": "^2.0.8",
|
||||
"object.groupby": "^1.0.3",
|
||||
"object.values": "^1.2.0",
|
||||
"semver": "^6.3.1",
|
||||
"tsconfig-paths": "^3.15.0"
|
||||
},
|
||||
@@ -7706,6 +7784,8 @@
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/debug": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
|
||||
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.1"
|
||||
@@ -7713,6 +7793,8 @@
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"esutils": "^2.0.2"
|
||||
@@ -9574,7 +9656,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.15.0",
|
||||
"version": "2.15.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
|
||||
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
@@ -12002,7 +12086,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
@@ -12207,7 +12293,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.39",
|
||||
"version": "8.4.47",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -12225,8 +12313,8 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.1",
|
||||
"source-map-js": "^1.2.0"
|
||||
"picocolors": "^1.1.0",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
@@ -13358,7 +13446,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-loading-skeleton": {
|
||||
"version": "3.4.0",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.5.0.tgz",
|
||||
"integrity": "sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0"
|
||||
@@ -13493,11 +13583,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.26.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.1.tgz",
|
||||
"integrity": "sha512-kIwJveZNwp7teQRI5QmwWo39A5bXRyqpH0COKKmPnyD2vBvDwgFXSqDUYtt1h+FEyfnE8eXr7oe0MxRzVwCcvQ==",
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz",
|
||||
"integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.19.1"
|
||||
"@remix-run/router": "1.19.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -13507,12 +13598,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.26.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.1.tgz",
|
||||
"integrity": "sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw==",
|
||||
"version": "6.26.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz",
|
||||
"integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.19.1",
|
||||
"react-router": "6.26.1"
|
||||
"@remix-run/router": "1.19.2",
|
||||
"react-router": "6.26.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -14500,7 +14592,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -16078,6 +16172,25 @@
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-remove-empty-scripts": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack-remove-empty-scripts/-/webpack-remove-empty-scripts-1.0.4.tgz",
|
||||
"integrity": "sha512-W/Vd94oNXMsQam+W9G+aAzGgFlX1aItcJpkG3byuHGDaxyK3H17oD/b5RcqS/ZHzStIKepksdLDznejDhDUs+Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"ansis": "1.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "patreon",
|
||||
"url": "https://patreon.com/biodiscus"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": ">=5.32.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-sources": {
|
||||
"version": "1.4.3",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -55,11 +55,11 @@
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-loading-skeleton": "3.4.0",
|
||||
"react-loading-skeleton": "3.5.0",
|
||||
"react-redux": "7.2.9",
|
||||
"react-responsive": "8.2.0",
|
||||
"react-router": "6.26.1",
|
||||
"react-router-dom": "6.26.1",
|
||||
"react-router": "6.26.2",
|
||||
"react-router-dom": "6.26.2",
|
||||
"react-zendesk": "^0.1.13",
|
||||
"redux": "4.2.1",
|
||||
"redux-logger": "3.0.6",
|
||||
@@ -75,7 +75,7 @@
|
||||
"@edx/reactifex": "1.1.0",
|
||||
"@openedx/frontend-build": "^14.0.3",
|
||||
"babel-plugin-formatjs": "10.5.16",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-import": "2.30.0",
|
||||
"glob": "7.2.3",
|
||||
"history": "5.3.0",
|
||||
"husky": "7.0.4",
|
||||
|
||||
@@ -60,7 +60,7 @@ const InstitutionLogistration = props => {
|
||||
className="btn nav-item p-0 mb-1 institutions--provider-link"
|
||||
destination={lmsBaseUrl + provider.loginUrl}
|
||||
>
|
||||
{provider?.name}
|
||||
{provider.name}
|
||||
</Hyperlink>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Navigate } from 'react-router-dom';
|
||||
import {
|
||||
AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS, REDIRECT,
|
||||
} from '../data/constants';
|
||||
import setCookie from '../data/utils/cookies';
|
||||
import { setCookie } from '../data/utils';
|
||||
|
||||
const RedirectLogistration = (props) => {
|
||||
const {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
@@ -9,20 +8,15 @@ import { Login } from '@openedx/paragon/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import messages from './messages';
|
||||
import { LOGIN_PAGE, REGISTER_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
|
||||
import { setCookie } from '../data/utils';
|
||||
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
|
||||
|
||||
const SocialAuthProviders = (props) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const { referrer, socialAuthProviders } = props;
|
||||
const registrationFields = useSelector(state => state.register.registrationFormData);
|
||||
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (referrer === REGISTER_PAGE) {
|
||||
setCookie('marketingEmailsOptIn', registrationFields?.configurableFormFields?.marketingEmailsOptIn);
|
||||
}
|
||||
const url = e.currentTarget.dataset.providerUrl;
|
||||
window.location.href = getConfig().LMS_BASE_URL + url;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import messages from './messages';
|
||||
import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
|
||||
import setCookie from '../data/utils/cookies';
|
||||
|
||||
const ThirdPartyAuthAlert = (props) => {
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -21,10 +20,7 @@ const ThirdPartyAuthAlert = (props) => {
|
||||
message = formatMessage(messages['register.third.party.auth.account.not.linked'], { currentProvider, platformName });
|
||||
}
|
||||
|
||||
if (currentProvider) {
|
||||
// Setting this cookie to capture marketingEmailsOptIn for SSO flow on the onboarding component
|
||||
setCookie('ssoPipelineRedirectionDone', true);
|
||||
} else {
|
||||
if (!currentProvider) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ import { getConfig } from '@edx/frontend-platform';
|
||||
import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { RESET_PAGE } from '../data/constants';
|
||||
import { updatePathWithQueryParams } from '../data/utils';
|
||||
import {
|
||||
DEFAULT_REDIRECT_URL,
|
||||
} from '../data/constants';
|
||||
|
||||
/**
|
||||
* This wrapper redirects the requester to our default redirect url if they are
|
||||
@@ -24,12 +25,7 @@ const UnAuthOnlyRoute = ({ children }) => {
|
||||
|
||||
if (isReady) {
|
||||
if (authUser && authUser.username) {
|
||||
const updatedPath = updatePathWithQueryParams(window.location.pathname);
|
||||
if (updatedPath.startsWith(RESET_PAGE)) {
|
||||
global.location.href = getConfig().LMS_BASE_URL;
|
||||
return null;
|
||||
}
|
||||
global.location.href = getConfig().LMS_BASE_URL.concat(updatedPath);
|
||||
global.location.href = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
export const registerFields = {
|
||||
fields: {
|
||||
country: {
|
||||
name: 'country',
|
||||
error_message: 'Select your country or region of residence',
|
||||
},
|
||||
honor_code: {
|
||||
name: 'honor_code',
|
||||
type: 'tos_and_honor_code',
|
||||
error_message: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const progressiveProfilingFields = {
|
||||
extended_profile: [],
|
||||
fields: {
|
||||
level_of_education: {
|
||||
name: 'level_of_education',
|
||||
type: 'select',
|
||||
label: 'Highest level of education completed',
|
||||
error_message: '',
|
||||
options: [
|
||||
[
|
||||
'p',
|
||||
'Doctorate',
|
||||
],
|
||||
[
|
||||
'm',
|
||||
"Master's or professional degree",
|
||||
],
|
||||
[
|
||||
'b',
|
||||
"Bachelor's degree",
|
||||
],
|
||||
[
|
||||
'a',
|
||||
'Associate degree',
|
||||
],
|
||||
[
|
||||
'hs',
|
||||
'Secondary/high school',
|
||||
],
|
||||
[
|
||||
'jhs',
|
||||
'Junior secondary/junior high/middle school',
|
||||
],
|
||||
[
|
||||
'none',
|
||||
'No formal education',
|
||||
],
|
||||
[
|
||||
'other',
|
||||
'Other education',
|
||||
],
|
||||
],
|
||||
},
|
||||
gender: {
|
||||
name: 'gender',
|
||||
type: 'select',
|
||||
label: 'Gender',
|
||||
error_message: '',
|
||||
options: [
|
||||
[
|
||||
'm',
|
||||
'Male',
|
||||
],
|
||||
[
|
||||
'f',
|
||||
'Female',
|
||||
],
|
||||
[
|
||||
'o',
|
||||
'Other/Prefer Not to Say',
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { logError } from '@edx/frontend-platform/logging';
|
||||
import { call, put, takeEvery } from 'redux-saga/effects';
|
||||
|
||||
@@ -8,7 +7,6 @@ import {
|
||||
getThirdPartyAuthContextSuccess,
|
||||
THIRD_PARTY_AUTH_CONTEXT,
|
||||
} from './actions';
|
||||
import { progressiveProfilingFields, registerFields } from './constants';
|
||||
import {
|
||||
getThirdPartyAuthContext,
|
||||
} from './service';
|
||||
@@ -22,16 +20,7 @@ export function* fetchThirdPartyAuthContext(action) {
|
||||
} = yield call(getThirdPartyAuthContext, action.payload.urlParams);
|
||||
|
||||
yield put(setCountryFromThirdPartyAuthContext(thirdPartyAuthContext.countryCode));
|
||||
// hard code country field, level of education and gender fields
|
||||
if (getConfig().ENABLE_HARD_CODE_OPTIONAL_FIELDS) {
|
||||
yield put(getThirdPartyAuthContextSuccess(
|
||||
registerFields,
|
||||
progressiveProfilingFields,
|
||||
thirdPartyAuthContext,
|
||||
));
|
||||
} else {
|
||||
yield put(getThirdPartyAuthContextSuccess(fieldDescriptions, optionalFields, thirdPartyAuthContext));
|
||||
}
|
||||
yield put(getThirdPartyAuthContextSuccess(fieldDescriptions, optionalFields, thirdPartyAuthContext));
|
||||
} catch (e) {
|
||||
yield put(getThirdPartyAuthContextFailure());
|
||||
logError(e);
|
||||
|
||||
@@ -1,35 +1,16 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import renderer from 'react-test-renderer';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import registerIcons from '../RegisterFaIcons';
|
||||
import SocialAuthProviders from '../SocialAuthProviders';
|
||||
|
||||
registerIcons();
|
||||
const mockStore = configureStore();
|
||||
|
||||
describe('SocialAuthProviders', () => {
|
||||
let props = {};
|
||||
|
||||
const initialState = {
|
||||
register: {
|
||||
registrationFormData: {
|
||||
configurableFormFields: {
|
||||
marketingEmailsOptIn: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const store = mockStore(initialState);
|
||||
const reduxWrapper = children => (
|
||||
<IntlProvider locale="en">
|
||||
<Provider store={store}>{children}</Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
const appleProvider = {
|
||||
id: 'oa2-apple-id',
|
||||
name: 'Apple',
|
||||
@@ -49,11 +30,11 @@ describe('SocialAuthProviders', () => {
|
||||
it('should match social auth provider with iconImage snapshot', () => {
|
||||
props = { socialAuthProviders: [appleProvider, facebookProvider] };
|
||||
|
||||
const tree = renderer.create(reduxWrapper(
|
||||
const tree = renderer.create(
|
||||
<IntlProvider locale="en">
|
||||
<SocialAuthProviders {...props} />
|
||||
</IntlProvider>,
|
||||
)).toJSON();
|
||||
).toJSON();
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
@@ -67,11 +48,11 @@ describe('SocialAuthProviders', () => {
|
||||
}],
|
||||
};
|
||||
|
||||
const tree = renderer.create(reduxWrapper(
|
||||
const tree = renderer.create(
|
||||
<IntlProvider locale="en">
|
||||
<SocialAuthProviders {...props} />
|
||||
</IntlProvider>,
|
||||
)).toJSON();
|
||||
).toJSON();
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
@@ -85,11 +66,11 @@ describe('SocialAuthProviders', () => {
|
||||
}],
|
||||
};
|
||||
|
||||
const tree = renderer.create(reduxWrapper(
|
||||
const tree = renderer.create(
|
||||
<IntlProvider locale="en">
|
||||
<SocialAuthProviders {...props} />
|
||||
</IntlProvider>,
|
||||
)).toJSON();
|
||||
).toJSON();
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ const configuration = {
|
||||
MARKETING_EMAILS_OPT_IN: process.env.MARKETING_EMAILS_OPT_IN || '',
|
||||
SHOW_CONFIGURABLE_EDX_FIELDS: process.env.SHOW_CONFIGURABLE_EDX_FIELDS || false,
|
||||
SHOW_REGISTRATION_LINKS: process.env.SHOW_REGISTRATION_LINKS !== 'false',
|
||||
ENABLE_HARD_CODE_OPTIONAL_FIELDS: process.env.ENABLE_HARD_CODE_OPTIONAL_FIELDS || false,
|
||||
ENABLE_IMAGE_LAYOUT: process.env.ENABLE_IMAGE_LAYOUT || false,
|
||||
// Links
|
||||
ACTIVATION_EMAIL_SUPPORT_LINK: process.env.ACTIVATION_EMAIL_SUPPORT_LINK || null,
|
||||
@@ -36,7 +35,6 @@ const configuration = {
|
||||
ZENDESK_LOGO_URL: process.env.ZENDESK_LOGO_URL,
|
||||
ALGOLIA_APP_ID: process.env.ALGOLIA_APP_ID || '',
|
||||
ALGOLIA_SEARCH_API_KEY: process.env.ALGOLIA_SEARCH_API_KEY || '',
|
||||
AUTO_GENERATED_USERNAME_EXPERIMENT_ID: process.env.AUTO_GENERATED_USERNAME_EXPERIMENT_ID || '',
|
||||
};
|
||||
|
||||
export default configuration;
|
||||
|
||||
@@ -37,4 +37,3 @@ export const VALID_EMAIL_REGEX = '(^[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+(\\.[-!#$%&\'*+
|
||||
// things like auto-enrollment upon login and registration.
|
||||
export const AUTH_PARAMS = ['course_id', 'enrollment_action', 'course_mode', 'email_opt_in', 'purchase_workflow', 'next', 'register_for_free', 'track', 'is_account_recovery', 'variant', 'host', 'cta'];
|
||||
export const REDIRECT = 'redirect';
|
||||
export const APP_NAME = 'authn_mfe';
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
|
||||
import { APP_NAME } from '../constants';
|
||||
|
||||
export const LINK_TIMEOUT = 300;
|
||||
|
||||
/**
|
||||
* Creates an event tracker function that sends a tracking event with the given name and options.
|
||||
*
|
||||
* @param {string} name - The name of the event to be tracked.
|
||||
* @param {object} [options={}] - Additional options to be included with the event.
|
||||
* @returns {function} - A function that, when called, sends the tracking event.
|
||||
*/
|
||||
export const createEventTracker = (name, options = {}) => () => sendTrackEvent(
|
||||
name,
|
||||
{ ...options, app_name: APP_NAME },
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates an event tracker function that sends a tracking event with the given name and options.
|
||||
*
|
||||
* @param {string} name - The name of the event to be tracked.
|
||||
* @param {object} [options={}] - Additional options to be included with the event.
|
||||
* @returns {function} - A function that, when called, sends the tracking event.
|
||||
*/
|
||||
export const createPageEventTracker = (name, options = null) => () => sendPageEvent(
|
||||
name,
|
||||
options,
|
||||
{ app_name: APP_NAME },
|
||||
);
|
||||
|
||||
export const createLinkTracker = (tracker, href) => (e) => {
|
||||
e.preventDefault();
|
||||
tracker();
|
||||
return setTimeout(() => { window.location.href = href; }, LINK_TIMEOUT);
|
||||
};
|
||||
@@ -11,11 +11,3 @@ export default function setCookie(cookieName, cookieValue, cookieExpiry) {
|
||||
cookies.set(cookieName, cookieValue, options);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeCookie(cookieName) {
|
||||
if (cookieName) {
|
||||
const cookies = new Cookies();
|
||||
const options = { domain: getConfig().SESSION_COOKIE_DOMAIN, path: '/' };
|
||||
cookies.remove(cookieName, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@ export {
|
||||
windowScrollTo,
|
||||
} from './dataUtils';
|
||||
export { default as AsyncActionType } from './reduxUtils';
|
||||
export { default as setCookie, removeCookie } from './cookies';
|
||||
export { default as setCookie } from './cookies';
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Form,
|
||||
@@ -24,10 +25,6 @@ import BaseContainer from '../base-container';
|
||||
import { FormGroup } from '../common-components';
|
||||
import { DEFAULT_STATE, LOGIN_PAGE, VALID_EMAIL_REGEX } from '../data/constants';
|
||||
import { updatePathWithQueryParams, windowScrollTo } from '../data/utils';
|
||||
import {
|
||||
trackForgotPasswordPageEvent,
|
||||
trackForgotPasswordPageViewed,
|
||||
} from '../tracking/trackers/forgotpassword';
|
||||
|
||||
const ForgotPasswordPage = (props) => {
|
||||
const platformName = getConfig().SITE_NAME;
|
||||
@@ -44,8 +41,8 @@ const ForgotPasswordPage = (props) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
trackForgotPasswordPageEvent();
|
||||
trackForgotPasswordPageViewed();
|
||||
sendPageEvent('login_and_registration', 'reset');
|
||||
sendTrackEvent('edx.bi.password_reset_form.viewed', { category: 'user-engagement' });
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { injectIntl, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import {
|
||||
Form, StatefulButton,
|
||||
@@ -41,11 +42,7 @@ import {
|
||||
getTpaProvider,
|
||||
updatePathWithQueryParams,
|
||||
} from '../data/utils';
|
||||
import { removeCookie } from '../data/utils/cookies';
|
||||
import ResetPasswordSuccess from '../reset-password/ResetPasswordSuccess';
|
||||
import {
|
||||
trackForgotPasswordLinkClick, trackLoginPageViewed, trackLoginSuccess,
|
||||
} from '../tracking/trackers/login';
|
||||
|
||||
const LoginPage = (props) => {
|
||||
const {
|
||||
@@ -81,18 +78,9 @@ const LoginPage = (props) => {
|
||||
const tpaHint = getTpaHint();
|
||||
|
||||
useEffect(() => {
|
||||
trackLoginPageViewed();
|
||||
sendPageEvent('login_and_registration', 'login');
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (loginResult.success) {
|
||||
trackLoginSuccess();
|
||||
|
||||
// Remove this cookie that was set to capture marketingEmailsOptIn for the onboarding component
|
||||
removeCookie('ssoPipelineRedirectionDone');
|
||||
}
|
||||
}, [loginResult]);
|
||||
|
||||
useEffect(() => {
|
||||
const payload = { ...queryParams };
|
||||
if (tpaHint) {
|
||||
@@ -182,6 +170,9 @@ const LoginPage = (props) => {
|
||||
const { name } = event.target;
|
||||
setErrors(prevErrors => ({ ...prevErrors, [name]: '' }));
|
||||
};
|
||||
const trackForgotPasswordLinkClick = () => {
|
||||
sendTrackEvent('edx.bi.password-reset_form.toggled', { category: 'user-engagement' });
|
||||
};
|
||||
|
||||
const { provider, skipHintedLogin } = getTpaProvider(tpaHint, providers, secondaryProviders);
|
||||
|
||||
|
||||
@@ -11,9 +11,7 @@ import { act } from 'react-dom/test-utils';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import {
|
||||
APP_NAME, COMPLETE_STATE, LOGIN_PAGE, PENDING_STATE,
|
||||
} from '../../data/constants';
|
||||
import { COMPLETE_STATE, LOGIN_PAGE, PENDING_STATE } from '../../data/constants';
|
||||
import { backupLoginFormBegin, dismissPasswordResetBanner, loginRequest } from '../data/actions';
|
||||
import { INTERNAL_SERVER_ERROR } from '../data/constants';
|
||||
import LoginPage from '../LoginPage';
|
||||
@@ -753,7 +751,7 @@ describe('LoginPage', () => {
|
||||
|
||||
it('should send page event when login page is rendered', () => {
|
||||
render(reduxWrapper(<IntlLoginPage {...props} />));
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'login', { app_name: APP_NAME });
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'login');
|
||||
});
|
||||
|
||||
it('tests that form is in invalid state when it is submitted', () => {
|
||||
@@ -786,7 +784,7 @@ describe('LoginPage', () => {
|
||||
{ selector: '#forgot-password' },
|
||||
));
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.password-reset_form.toggled', { category: 'user-engagement', app_name: APP_NAME });
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.password-reset_form.toggled', { category: 'user-engagement' });
|
||||
});
|
||||
|
||||
it('should backup the login form state when shouldBackupState is true', () => {
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
tpaProvidersSelector,
|
||||
} from '../common-components/data/selectors';
|
||||
import messages from '../common-components/messages';
|
||||
import { APP_NAME, LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
|
||||
import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
|
||||
import {
|
||||
getTpaHint, getTpaProvider, updatePathWithQueryParams,
|
||||
} from '../data/utils';
|
||||
@@ -56,11 +56,11 @@ const Logistration = (props) => {
|
||||
}, [navigate, disablePublicAccountCreation]);
|
||||
|
||||
const handleInstitutionLogin = (e) => {
|
||||
sendTrackEvent('edx.bi.institution_login_form.toggled', { category: 'user-engagement', app_name: APP_NAME });
|
||||
sendTrackEvent('edx.bi.institution_login_form.toggled', { category: 'user-engagement' });
|
||||
if (typeof e === 'string') {
|
||||
sendPageEvent('login_and_registration', e === '/login' ? 'login' : 'register', { app_name: APP_NAME });
|
||||
sendPageEvent('login_and_registration', e === '/login' ? 'login' : 'register');
|
||||
} else {
|
||||
sendPageEvent('login_and_registration', e.target.dataset.eventName, { app_name: APP_NAME });
|
||||
sendPageEvent('login_and_registration', e.target.dataset.eventName);
|
||||
}
|
||||
|
||||
setInstitutionLogin(!institutionLogin);
|
||||
@@ -70,7 +70,7 @@ const Logistration = (props) => {
|
||||
if (tabKey === currentTab) {
|
||||
return;
|
||||
}
|
||||
sendTrackEvent(`edx.bi.${tabKey.replace('/', '')}_form.toggled`, { category: 'user-engagement', app_name: APP_NAME });
|
||||
sendTrackEvent(`edx.bi.${tabKey.replace('/', '')}_form.toggled`, { category: 'user-engagement' });
|
||||
props.clearThirdPartyAuthContextErrorMessage();
|
||||
if (tabKey === LOGIN_PAGE) {
|
||||
props.backupRegistrationForm();
|
||||
|
||||
@@ -11,21 +11,16 @@ import configureStore from 'redux-mock-store';
|
||||
import Logistration from './Logistration';
|
||||
import { clearThirdPartyAuthContextErrorMessage } from '../common-components/data/actions';
|
||||
import {
|
||||
APP_NAME,
|
||||
COMPLETE_STATE, LOGIN_PAGE, REGISTER_PAGE,
|
||||
} from '../data/constants';
|
||||
import { backupLoginForm } from '../login/data/actions';
|
||||
import { backupRegistrationForm } from '../register/data/actions';
|
||||
import { NOT_INITIALIZED } from '../register/data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation
|
||||
from '../register/data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics', () => ({
|
||||
sendPageEvent: jest.fn(),
|
||||
sendTrackEvent: jest.fn(),
|
||||
}));
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
jest.mock('../register/data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation', () => jest.fn());
|
||||
|
||||
const mockStore = configureStore();
|
||||
const IntlLogistration = injectIntl(Logistration);
|
||||
@@ -89,7 +84,6 @@ describe('Logistration', () => {
|
||||
})),
|
||||
}));
|
||||
|
||||
useAutoGeneratedUsernameExperimentVariation.mockReturnValue(NOT_INITIALIZED);
|
||||
configure({
|
||||
loggingService: { logError: jest.fn() },
|
||||
config: {
|
||||
@@ -230,8 +224,8 @@ describe('Logistration', () => {
|
||||
render(reduxWrapper(<IntlLogistration {...props} />));
|
||||
fireEvent.click(screen.getByText('Institution/campus credentials'));
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.institution_login_form.toggled', { category: 'user-engagement', app_name: APP_NAME });
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'institution_login', { app_name: APP_NAME });
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.institution_login_form.toggled', { category: 'user-engagement' });
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'institution_login');
|
||||
|
||||
mergeConfig({
|
||||
DISABLE_ENTERPRISE_LOGIN: '',
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getConfig, snakeCaseObject } from '@edx/frontend-platform';
|
||||
import { identifyAuthenticatedUser } from '@edx/frontend-platform/analytics';
|
||||
import { identifyAuthenticatedUser, sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import {
|
||||
AxiosJwtAuthService,
|
||||
configure as configureAuth,
|
||||
@@ -39,13 +39,6 @@ import {
|
||||
import isOneTrustFunctionalCookieEnabled from '../data/oneTrust';
|
||||
import { getAllPossibleQueryParams, isHostAvailableInQueryParams } from '../data/utils';
|
||||
import { FormFieldRenderer } from '../field-renderer';
|
||||
import {
|
||||
trackDisablePostRegistrationRecommendations,
|
||||
trackProgressiveProfilingPageViewed,
|
||||
trackProgressiveProfilingSkipLinkClick,
|
||||
trackProgressiveProfilingSubmitClick,
|
||||
trackProgressiveProfilingSupportLinkCLick,
|
||||
} from '../tracking/trackers/progressive-profiling';
|
||||
|
||||
const ProgressiveProfiling = (props) => {
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -105,13 +98,14 @@ const ProgressiveProfiling = (props) => {
|
||||
useEffect(() => {
|
||||
if (authenticatedUser?.userId) {
|
||||
identifyAuthenticatedUser(authenticatedUser.userId);
|
||||
trackProgressiveProfilingPageViewed();
|
||||
sendPageEvent('login_and_registration', 'welcome');
|
||||
}
|
||||
}, [authenticatedUser]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enablePostRegistrationRecommendations) {
|
||||
trackDisablePostRegistrationRecommendations(
|
||||
sendTrackEvent(
|
||||
'edx.bi.user.recommendations.not.enabled',
|
||||
{ functionalCookiesConsent, page: 'authn_recommendations' },
|
||||
);
|
||||
return;
|
||||
@@ -155,23 +149,29 @@ const ProgressiveProfiling = (props) => {
|
||||
});
|
||||
}
|
||||
props.saveUserProfile(authenticatedUser.username, snakeCaseObject(payload));
|
||||
const eventProperties = {
|
||||
isGenderSelected: !!values.gender,
|
||||
isYearOfBirthSelected: !!values.year_of_birth,
|
||||
isLevelOfEducationSelected: !!values.level_of_education,
|
||||
isWorkExperienceSelected: !!values.work_experience,
|
||||
host: queryParams?.host || '',
|
||||
};
|
||||
trackProgressiveProfilingSubmitClick(eventProperties);
|
||||
|
||||
sendTrackEvent(
|
||||
'edx.bi.welcome.page.submit.clicked',
|
||||
{
|
||||
isGenderSelected: !!values.gender,
|
||||
isYearOfBirthSelected: !!values.year_of_birth,
|
||||
isLevelOfEducationSelected: !!values.level_of_education,
|
||||
isWorkExperienceSelected: !!values.work_experience,
|
||||
host: queryParams?.host || '',
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleSkip = (e) => {
|
||||
e.preventDefault();
|
||||
window.history.replaceState(location.state, null, '');
|
||||
setShowModal(true);
|
||||
trackProgressiveProfilingSkipLinkClick({
|
||||
host: queryParams?.host || '',
|
||||
});
|
||||
sendTrackEvent(
|
||||
'edx.bi.welcome.page.skip.link.clicked',
|
||||
{
|
||||
host: queryParams?.host || '',
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const onChangeHandler = (e) => {
|
||||
@@ -242,7 +242,7 @@ const ProgressiveProfiling = (props) => {
|
||||
destination={getConfig().AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK}
|
||||
target="_blank"
|
||||
showLaunchIcon={false}
|
||||
onClick={() => (trackProgressiveProfilingSupportLinkCLick())}
|
||||
onClick={() => (sendTrackEvent('edx.bi.welcome.page.support.link.clicked'))}
|
||||
>
|
||||
{formatMessage(messages['optional.fields.information.link'])}
|
||||
</Hyperlink>
|
||||
|
||||
@@ -12,7 +12,6 @@ import { MemoryRouter, mockNavigate, useLocation } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import {
|
||||
APP_NAME,
|
||||
AUTHN_PROGRESSIVE_PROFILING,
|
||||
COMPLETE_STATE, DEFAULT_REDIRECT_URL,
|
||||
EMBEDDED,
|
||||
@@ -144,9 +143,8 @@ describe('ProgressiveProfilingTests', () => {
|
||||
const modalContentContainer = document.getElementsByClassName('.pgn__modal-content-container');
|
||||
|
||||
expect(modalContentContainer).toBeTruthy();
|
||||
const payload = { host: '', app_name: APP_NAME };
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', payload);
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', { host: '' });
|
||||
});
|
||||
|
||||
// ******** test event functionality ********
|
||||
@@ -167,7 +165,7 @@ describe('ProgressiveProfilingTests', () => {
|
||||
const supportLink = screen.getByRole('link', { name: /learn more about how we use this information/i });
|
||||
fireEvent.click(supportLink);
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.support.link.clicked', { app_name: APP_NAME });
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.support.link.clicked');
|
||||
});
|
||||
|
||||
it('should set empty host property value for non-embedded experience', () => {
|
||||
@@ -177,7 +175,6 @@ describe('ProgressiveProfilingTests', () => {
|
||||
isLevelOfEducationSelected: false,
|
||||
isWorkExperienceSelected: false,
|
||||
host: '',
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(AUTHN_PROGRESSIVE_PROFILING) };
|
||||
@@ -319,7 +316,7 @@ describe('ProgressiveProfilingTests', () => {
|
||||
const skipLinkButton = screen.getByText('Skip for now');
|
||||
fireEvent.click(skipLinkButton);
|
||||
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', { host, app_name: APP_NAME });
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.welcome.page.skip.link.clicked', { host });
|
||||
});
|
||||
|
||||
it('should show spinner while fetching the optional fields', () => {
|
||||
@@ -352,7 +349,6 @@ describe('ProgressiveProfilingTests', () => {
|
||||
isLevelOfEducationSelected: false,
|
||||
isWorkExperienceSelected: false,
|
||||
host: 'http://example.com',
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
delete window.location;
|
||||
window.location = {
|
||||
|
||||
@@ -15,7 +15,7 @@ const generateProductKey = (product) => (
|
||||
export const getProductMapping = (recommendedProducts) => recommendedProducts.map((product) => ({
|
||||
product_key: generateProductKey(product),
|
||||
product_line: product.cardType,
|
||||
product_source: product?.productSource?.name,
|
||||
product_source: product.productSource.name,
|
||||
}));
|
||||
|
||||
export const trackRecommendationClick = (product, position, userId) => {
|
||||
@@ -25,7 +25,7 @@ export const trackRecommendationClick = (product, position, userId) => {
|
||||
recommendation_type: product.recommendationType,
|
||||
product_key: generateProductKey(product),
|
||||
product_line: product.cardType,
|
||||
product_source: product?.productSource?.name,
|
||||
product_source: product.productSource.name,
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export const INVALID_NAME_REGEX = /https?:\/\/(?:[-\w.]|(?:%[\da-fA-F]{2}))*/g;
|
||||
|
||||
const validateName = (value, formatMessage) => {
|
||||
let fieldError = '';
|
||||
if (!value || (value && !value.trim())) {
|
||||
if (!value.trim()) {
|
||||
fieldError = formatMessage(messages['empty.name.field.error']);
|
||||
} else if (URL_REGEX.test(value) || HTML_REGEX.test(value) || INVALID_NAME_REGEX.test(value)) {
|
||||
fieldError = formatMessage(messages['name.validation.message']);
|
||||
|
||||
@@ -4,6 +4,7 @@ import React, {
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { Form, Spinner, StatefulButton } from '@openedx/paragon';
|
||||
import classNames from 'classnames';
|
||||
@@ -17,7 +18,6 @@ import {
|
||||
backupRegistrationFormBegin,
|
||||
clearRegistrationBackendError,
|
||||
registerNewUser,
|
||||
setAutoGeneratedUsernameExperimentData,
|
||||
setEmailSuggestionInStore,
|
||||
setUserPipelineDataLoaded,
|
||||
} from './data/actions';
|
||||
@@ -25,8 +25,6 @@ import {
|
||||
FORM_SUBMISSION_ERROR,
|
||||
TPA_AUTHENTICATION_FAILURE,
|
||||
} from './data/constants';
|
||||
import { AUTO_GENERATED_USERNAME_REGISTRATION_EXP_VARIATION, NOT_INITIALIZED } from './data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation from './data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
import getBackendValidations from './data/selectors';
|
||||
import {
|
||||
isFormValid, prepareRegistrationPayload,
|
||||
@@ -43,12 +41,11 @@ import { getThirdPartyAuthContext as getRegistrationDataFromBackend } from '../c
|
||||
import EnterpriseSSO from '../common-components/EnterpriseSSO';
|
||||
import ThirdPartyAuth from '../common-components/ThirdPartyAuth';
|
||||
import {
|
||||
APP_NAME, COMPLETE_STATE, PENDING_STATE, REGISTER_PAGE,
|
||||
COMPLETE_STATE, PENDING_STATE, REGISTER_PAGE,
|
||||
} from '../data/constants';
|
||||
import {
|
||||
getAllPossibleQueryParams, getTpaHint, getTpaProvider, isHostAvailableInQueryParams, removeCookie, setCookie,
|
||||
getAllPossibleQueryParams, getTpaHint, getTpaProvider, isHostAvailableInQueryParams, setCookie,
|
||||
} from '../data/utils';
|
||||
import { trackRegistrationPageViewed, trackRegistrationSuccess } from '../tracking/trackers/register';
|
||||
|
||||
/**
|
||||
* Main Registration Page component
|
||||
@@ -71,7 +68,6 @@ const RegistrationPage = (props) => {
|
||||
} = props;
|
||||
|
||||
const backedUpFormData = useSelector(state => state.register.registrationFormData);
|
||||
const initExpVariation = useSelector(state => state.register.autoGeneratedUsernameExperimentVariation);
|
||||
const registrationError = useSelector(state => state.register.registrationError);
|
||||
const registrationErrorCode = registrationError?.errorCode;
|
||||
const registrationResult = useSelector(state => state.register.registrationResult);
|
||||
@@ -107,12 +103,6 @@ const RegistrationPage = (props) => {
|
||||
? formatMessage(messages['create.account.cta.button'], { label: cta })
|
||||
: formatMessage(messages['create.account.for.free.button']);
|
||||
|
||||
const autoGeneratedUsernameExpVariation = useAutoGeneratedUsernameExperimentVariation(
|
||||
initExpVariation, registrationEmbedded, tpaHint, currentProvider, thirdPartyAuthApiStatus,
|
||||
);
|
||||
|
||||
const hideUsernameField = flags.autoGeneratedUsernameEnabled
|
||||
|| autoGeneratedUsernameExpVariation === AUTO_GENERATED_USERNAME_REGISTRATION_EXP_VARIATION;
|
||||
/**
|
||||
* Set the userPipelineDetails data in formFields for only first time
|
||||
*/
|
||||
@@ -138,7 +128,7 @@ const RegistrationPage = (props) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!formStartTime) {
|
||||
trackRegistrationPageViewed();
|
||||
sendPageEvent('login_and_registration', 'register');
|
||||
const payload = { ...queryParams, is_register_page: true };
|
||||
if (tpaHint) {
|
||||
payload.tpa_hint = tpaHint;
|
||||
@@ -159,10 +149,8 @@ const RegistrationPage = (props) => {
|
||||
formFields: { ...formFields },
|
||||
errors: { ...errors },
|
||||
}));
|
||||
dispatch(setAutoGeneratedUsernameExperimentData(autoGeneratedUsernameExpVariation));
|
||||
}
|
||||
}, [shouldBackupState, configurableFormFields, // eslint-disable-line react-hooks/exhaustive-deps
|
||||
formFields, errors, dispatch, backedUpFormData]);
|
||||
}, [shouldBackupState, configurableFormFields, formFields, errors, dispatch, backedUpFormData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (backendValidations) {
|
||||
@@ -183,15 +171,10 @@ const RegistrationPage = (props) => {
|
||||
useEffect(() => {
|
||||
if (registrationResult.success) {
|
||||
// This event is used by GTM
|
||||
trackRegistrationSuccess();
|
||||
sendTrackEvent('edx.bi.user.account.registered.client', {});
|
||||
|
||||
// This is used by the "User Retention Rate Event" on GTM
|
||||
setCookie(getConfig().USER_RETENTION_COOKIE_NAME, true);
|
||||
|
||||
// Remove marketingEmailsOptIn cookie that was set on SSO registration flow
|
||||
removeCookie('marketingEmailsOptIn');
|
||||
// Remove this cookie that was set to capture marketingEmailsOptIn for the onboarding component
|
||||
removeCookie('ssoPipelineRedirectionDone');
|
||||
}
|
||||
}, [registrationResult]);
|
||||
|
||||
@@ -227,13 +210,13 @@ const RegistrationPage = (props) => {
|
||||
|
||||
const registerUser = () => {
|
||||
const totalRegistrationTime = (Date.now() - formStartTime) / 1000;
|
||||
let payload = { ...formFields, app_name: APP_NAME };
|
||||
let payload = { ...formFields };
|
||||
|
||||
if (currentProvider) {
|
||||
delete payload.password;
|
||||
payload.social_auth_provider = currentProvider;
|
||||
}
|
||||
if (hideUsernameField) {
|
||||
if (flags.autoGeneratedUsernameEnabled) {
|
||||
delete payload.username;
|
||||
}
|
||||
|
||||
@@ -303,109 +286,106 @@ const RegistrationPage = (props) => {
|
||||
getConfig().ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN && !!Object.keys(optionalFields.fields).length
|
||||
}
|
||||
/>
|
||||
{(autoSubmitRegForm && !errorCode.type)
|
||||
|| (!autoGeneratedUsernameExpVariation && !(
|
||||
autoGeneratedUsernameExpVariation === NOT_INITIALIZED
|
||||
|| registrationEmbedded || !!tpaHint || !!currentProvider))
|
||||
? (
|
||||
<div className="mw-xs mt-5 text-center">
|
||||
<Spinner animation="border" variant="primary" id="tpa-spinner" />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={classNames(
|
||||
'mw-xs mt-3',
|
||||
{ 'w-100 m-auto pt-4 main-content': registrationEmbedded },
|
||||
{autoSubmitRegForm && !errorCode.type ? (
|
||||
<div className="mw-xs mt-5 text-center">
|
||||
<Spinner animation="border" variant="primary" id="tpa-spinner" />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={classNames(
|
||||
'mw-xs mt-3',
|
||||
{ 'w-100 m-auto pt-4 main-content': registrationEmbedded },
|
||||
)}
|
||||
>
|
||||
<ThirdPartyAuthAlert
|
||||
currentProvider={currentProvider}
|
||||
platformName={platformName}
|
||||
referrer={REGISTER_PAGE}
|
||||
/>
|
||||
<RegistrationFailure
|
||||
errorCode={errorCode.type}
|
||||
failureCount={errorCode.count}
|
||||
context={{ provider: currentProvider, errorMessage: thirdPartyAuthErrorMessage }}
|
||||
/>
|
||||
<Form id="registration-form" name="registration-form">
|
||||
<NameField
|
||||
name="name"
|
||||
value={formFields.name}
|
||||
shouldFetchUsernameSuggestions={!formFields.username.trim()}
|
||||
handleChange={handleOnChange}
|
||||
handleErrorChange={handleErrorChange}
|
||||
errorMessage={errors.name}
|
||||
helpText={[formatMessage(messages['help.text.name'])]}
|
||||
floatingLabel={formatMessage(messages['registration.fullname.label'])}
|
||||
/>
|
||||
<EmailField
|
||||
name="email"
|
||||
value={formFields.email}
|
||||
confirmEmailValue={configurableFormFields?.confirm_email}
|
||||
handleErrorChange={handleErrorChange}
|
||||
handleChange={handleOnChange}
|
||||
errorMessage={errors.email}
|
||||
helpText={[formatMessage(messages['help.text.email'])]}
|
||||
floatingLabel={formatMessage(messages['registration.email.label'])}
|
||||
/>
|
||||
{!flags.autoGeneratedUsernameEnabled && (
|
||||
<UsernameField
|
||||
name="username"
|
||||
spellCheck="false"
|
||||
value={formFields.username}
|
||||
handleChange={handleOnChange}
|
||||
handleErrorChange={handleErrorChange}
|
||||
errorMessage={errors.username}
|
||||
helpText={[formatMessage(messages['help.text.username.1']), formatMessage(messages['help.text.username.2'])]}
|
||||
floatingLabel={formatMessage(messages['registration.username.label'])}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<ThirdPartyAuthAlert
|
||||
currentProvider={currentProvider}
|
||||
platformName={platformName}
|
||||
referrer={REGISTER_PAGE}
|
||||
/>
|
||||
<RegistrationFailure
|
||||
errorCode={errorCode.type}
|
||||
failureCount={errorCode.count}
|
||||
context={{ provider: currentProvider, errorMessage: thirdPartyAuthErrorMessage }}
|
||||
/>
|
||||
<Form id="registration-form" name="registration-form">
|
||||
<NameField
|
||||
name="name"
|
||||
value={formFields.name}
|
||||
shouldFetchUsernameSuggestions={!formFields.username.trim()}
|
||||
{!currentProvider && (
|
||||
<PasswordField
|
||||
name="password"
|
||||
value={formFields.password}
|
||||
handleChange={handleOnChange}
|
||||
handleErrorChange={handleErrorChange}
|
||||
errorMessage={errors.name}
|
||||
helpText={[formatMessage(messages['help.text.name'])]}
|
||||
floatingLabel={formatMessage(messages['registration.fullname.label'])}
|
||||
errorMessage={errors.password}
|
||||
floatingLabel={formatMessage(messages['registration.password.label'])}
|
||||
/>
|
||||
<EmailField
|
||||
name="email"
|
||||
value={formFields.email}
|
||||
confirmEmailValue={configurableFormFields?.confirm_email}
|
||||
handleErrorChange={handleErrorChange}
|
||||
handleChange={handleOnChange}
|
||||
errorMessage={errors.email}
|
||||
helpText={[formatMessage(messages['help.text.email'])]}
|
||||
floatingLabel={formatMessage(messages['registration.email.label'])}
|
||||
)}
|
||||
<ConfigurableRegistrationForm
|
||||
email={formFields.email}
|
||||
fieldErrors={errors}
|
||||
formFields={configurableFormFields}
|
||||
setFieldErrors={registrationEmbedded ? setTemporaryErrors : setErrors}
|
||||
setFormFields={setConfigurableFormFields}
|
||||
autoSubmitRegisterForm={autoSubmitRegForm}
|
||||
fieldDescriptions={fieldDescriptions}
|
||||
/>
|
||||
<StatefulButton
|
||||
id="register-user"
|
||||
name="register-user"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="register-button mt-4 mb-4"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: buttonLabel,
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
{!registrationEmbedded && (
|
||||
<ThirdPartyAuth
|
||||
currentProvider={currentProvider}
|
||||
providers={providers}
|
||||
secondaryProviders={secondaryProviders}
|
||||
handleInstitutionLogin={handleInstitutionLogin}
|
||||
thirdPartyAuthApiStatus={thirdPartyAuthApiStatus}
|
||||
/>
|
||||
{!hideUsernameField && (
|
||||
<UsernameField
|
||||
name="username"
|
||||
spellCheck="false"
|
||||
value={formFields.username}
|
||||
handleChange={handleOnChange}
|
||||
handleErrorChange={handleErrorChange}
|
||||
errorMessage={errors.username}
|
||||
helpText={[formatMessage(messages['help.text.username.1']), formatMessage(messages['help.text.username.2'])]}
|
||||
floatingLabel={formatMessage(messages['registration.username.label'])}
|
||||
/>
|
||||
)}
|
||||
{!currentProvider && (
|
||||
<PasswordField
|
||||
name="password"
|
||||
value={formFields.password}
|
||||
handleChange={handleOnChange}
|
||||
handleErrorChange={handleErrorChange}
|
||||
errorMessage={errors.password}
|
||||
floatingLabel={formatMessage(messages['registration.password.label'])}
|
||||
/>
|
||||
)}
|
||||
<ConfigurableRegistrationForm
|
||||
email={formFields.email}
|
||||
fieldErrors={errors}
|
||||
formFields={configurableFormFields}
|
||||
setFieldErrors={registrationEmbedded ? setTemporaryErrors : setErrors}
|
||||
setFormFields={setConfigurableFormFields}
|
||||
autoSubmitRegisterForm={autoSubmitRegForm}
|
||||
fieldDescriptions={fieldDescriptions}
|
||||
/>
|
||||
<StatefulButton
|
||||
id="register-user"
|
||||
name="register-user"
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="register-button mt-4 mb-4"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: buttonLabel,
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
{!registrationEmbedded && (
|
||||
<ThirdPartyAuth
|
||||
currentProvider={currentProvider}
|
||||
providers={providers}
|
||||
secondaryProviders={secondaryProviders}
|
||||
handleInstitutionLogin={handleInstitutionLogin}
|
||||
thirdPartyAuthApiStatus={thirdPartyAuthApiStatus}
|
||||
/>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,12 +17,9 @@ import {
|
||||
setUserPipelineDataLoaded,
|
||||
} from './data/actions';
|
||||
import { INTERNAL_SERVER_ERROR } from './data/constants';
|
||||
import { NOT_INITIALIZED } from './data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation
|
||||
from './data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
import RegistrationPage from './RegistrationPage';
|
||||
import {
|
||||
APP_NAME, AUTHN_PROGRESSIVE_PROFILING, COMPLETE_STATE, PENDING_STATE, REGISTER_PAGE,
|
||||
AUTHN_PROGRESSIVE_PROFILING, COMPLETE_STATE, PENDING_STATE, REGISTER_PAGE,
|
||||
} from '../data/constants';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics', () => ({
|
||||
@@ -33,7 +30,6 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
...jest.requireActual('@edx/frontend-platform/i18n'),
|
||||
getLocale: jest.fn(),
|
||||
}));
|
||||
jest.mock('./data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation', () => jest.fn());
|
||||
|
||||
const IntlRegistrationPage = injectIntl(RegistrationPage);
|
||||
const mockStore = configureStore();
|
||||
@@ -132,7 +128,6 @@ describe('RegistrationPage', () => {
|
||||
institutionLogin: false,
|
||||
};
|
||||
window.location = { search: '' };
|
||||
useAutoGeneratedUsernameExperimentVariation.mockReturnValue(NOT_INITIALIZED);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -190,7 +185,6 @@ describe('RegistrationPage', () => {
|
||||
honor_code: true,
|
||||
total_registration_time: 0,
|
||||
next: '/course/demo-course-url',
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
@@ -213,7 +207,6 @@ describe('RegistrationPage', () => {
|
||||
honor_code: true,
|
||||
social_auth_provider: 'Apple',
|
||||
total_registration_time: 0,
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
|
||||
store = mockStore({
|
||||
@@ -299,7 +292,6 @@ describe('RegistrationPage', () => {
|
||||
honor_code: true,
|
||||
total_registration_time: 0,
|
||||
marketing_emails_opt_in: true,
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
@@ -326,7 +318,6 @@ describe('RegistrationPage', () => {
|
||||
country: 'Pakistan',
|
||||
honor_code: true,
|
||||
total_registration_time: 0,
|
||||
app_name: APP_NAME,
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
@@ -601,7 +592,7 @@ describe('RegistrationPage', () => {
|
||||
|
||||
it('should send page event when register page is rendered', () => {
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'register', { app_name: APP_NAME });
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'register');
|
||||
});
|
||||
|
||||
it('should send track event when user has successfully registered', () => {
|
||||
@@ -619,7 +610,7 @@ describe('RegistrationPage', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.user.account.registered.client', { app_name: APP_NAME });
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.user.account.registered.client', {});
|
||||
});
|
||||
|
||||
it('should populate form with pipeline user details', () => {
|
||||
@@ -892,7 +883,6 @@ describe('RegistrationPage', () => {
|
||||
country: 'PK',
|
||||
social_auth_provider: 'Apple',
|
||||
total_registration_time: 0,
|
||||
app_name: APP_NAME,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getCountryList, getLocale, useIntl } from '@edx/frontend-platform/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { FormFieldRenderer } from '../../field-renderer';
|
||||
import { backupRegistrationFormBegin } from '../data/actions';
|
||||
import { FIELDS } from '../data/constants';
|
||||
import messages from '../messages';
|
||||
import { CountryField, HonorCode, TermsOfService } from '../RegistrationFields';
|
||||
@@ -34,16 +32,12 @@ const ConfigurableRegistrationForm = (props) => {
|
||||
setFormFields,
|
||||
autoSubmitRegistrationForm,
|
||||
} = props;
|
||||
const dispatch = useDispatch();
|
||||
|
||||
/** The reason for adding the entry 'United States' is that Chrome browser aut-fill the form with the 'Unites
|
||||
States' instead of 'United States of America' which does not exist in country dropdown list and gets the user
|
||||
confused and unable to create an account. So we added the United States entry in the dropdown list.
|
||||
*/
|
||||
|
||||
const countryList = useMemo(() => (
|
||||
getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }]).filter(country => country.code !== 'RU')
|
||||
), []);
|
||||
const countryList = useMemo(() => getCountryList(getLocale()).concat([{ code: 'US', name: 'United States' }]), []);
|
||||
|
||||
let showTermsOfServiceAndHonorCode = false;
|
||||
let showCountryField = false;
|
||||
@@ -56,8 +50,6 @@ const ConfigurableRegistrationForm = (props) => {
|
||||
showMarketingEmailOptInCheckbox: getConfig().MARKETING_EMAILS_OPT_IN,
|
||||
};
|
||||
|
||||
const backedUpFormData = useSelector(state => state.register.registrationFormData);
|
||||
|
||||
/**
|
||||
* If auto submitting register form, we will check tos and honor code fields if they exist for feature parity.
|
||||
*/
|
||||
@@ -98,16 +90,6 @@ const ConfigurableRegistrationForm = (props) => {
|
||||
setFieldErrors(prevErrors => ({ ...prevErrors, [name]: '' }));
|
||||
}
|
||||
}
|
||||
// setting marketingEmailsOptIn state for SSO authentication flow for register API call
|
||||
if (name === 'marketingEmailsOptIn') {
|
||||
dispatch(backupRegistrationFormBegin({
|
||||
...backedUpFormData,
|
||||
configurableFormFields: {
|
||||
...backedUpFormData.configurableFormFields,
|
||||
[name]: value,
|
||||
},
|
||||
}));
|
||||
}
|
||||
setFormFields(prevState => ({ ...prevState, [name]: value }));
|
||||
};
|
||||
|
||||
|
||||
@@ -9,12 +9,8 @@ import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import { APP_NAME } from '../../../data/constants';
|
||||
import { registerNewUser } from '../../data/actions';
|
||||
import { FIELDS } from '../../data/constants';
|
||||
import { NOT_INITIALIZED } from '../../data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation
|
||||
from '../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
import RegistrationPage from '../../RegistrationPage';
|
||||
import ConfigurableRegistrationForm from '../ConfigurableRegistrationForm';
|
||||
|
||||
@@ -26,7 +22,6 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
...jest.requireActual('@edx/frontend-platform/i18n'),
|
||||
getLocale: jest.fn(),
|
||||
}));
|
||||
jest.mock('../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation', () => jest.fn());
|
||||
|
||||
const IntlConfigurableRegistrationForm = injectIntl(ConfigurableRegistrationForm);
|
||||
const IntlRegistrationPage = injectIntl(RegistrationPage);
|
||||
@@ -126,7 +121,6 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
};
|
||||
window.location = { search: '' };
|
||||
getLocale.mockImplementationOnce(() => ('en-us'));
|
||||
useAutoGeneratedUsernameExperimentVariation.mockReturnValue(NOT_INITIALIZED);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -266,7 +260,7 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...payload, country: 'PK', app_name: APP_NAME }));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...payload, country: 'PK' }));
|
||||
});
|
||||
|
||||
it('should show error messages for required fields on empty form submission', () => {
|
||||
|
||||
@@ -12,9 +12,6 @@ import configureStore from 'redux-mock-store';
|
||||
import {
|
||||
FORBIDDEN_REQUEST, INTERNAL_SERVER_ERROR, TPA_AUTHENTICATION_FAILURE, TPA_SESSION_EXPIRED,
|
||||
} from '../../data/constants';
|
||||
import { NOT_INITIALIZED } from '../../data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation
|
||||
from '../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
import RegistrationPage from '../../RegistrationPage';
|
||||
import RegistrationFailureMessage from '../RegistrationFailure';
|
||||
|
||||
@@ -26,7 +23,6 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
...jest.requireActual('@edx/frontend-platform/i18n'),
|
||||
getLocale: jest.fn(),
|
||||
}));
|
||||
jest.mock('../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation', () => jest.fn());
|
||||
|
||||
const IntlRegistrationPage = injectIntl(RegistrationPage);
|
||||
const IntlRegistrationFailure = injectIntl(RegistrationFailureMessage);
|
||||
@@ -125,7 +121,6 @@ describe('RegistrationFailure', () => {
|
||||
institutionLogin: false,
|
||||
};
|
||||
window.location = { search: '' };
|
||||
useAutoGeneratedUsernameExperimentVariation.mockReturnValue(NOT_INITIALIZED);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -12,9 +12,6 @@ import configureStore from 'redux-mock-store';
|
||||
import {
|
||||
COMPLETE_STATE, LOGIN_PAGE, PENDING_STATE, REGISTER_PAGE,
|
||||
} from '../../../data/constants';
|
||||
import { NOT_INITIALIZED } from '../../data/optimizelyExperiment/helper';
|
||||
import useAutoGeneratedUsernameExperimentVariation
|
||||
from '../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation';
|
||||
import RegistrationPage from '../../RegistrationPage';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics', () => ({
|
||||
@@ -25,7 +22,6 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
|
||||
...jest.requireActual('@edx/frontend-platform/i18n'),
|
||||
getLocale: jest.fn(),
|
||||
}));
|
||||
jest.mock('../../data/optimizelyExperiment/useAutoGeneratedUsernameExperimentVariation', () => jest.fn());
|
||||
|
||||
const IntlRegistrationPage = injectIntl(RegistrationPage);
|
||||
const mockStore = configureStore();
|
||||
@@ -124,7 +120,6 @@ describe('ThirdPartyAuth', () => {
|
||||
institutionLogin: false,
|
||||
};
|
||||
window.location = { search: '' };
|
||||
useAutoGeneratedUsernameExperimentVariation.mockReturnValue(NOT_INITIALIZED);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -8,7 +8,7 @@ export const REGISTRATION_CLEAR_BACKEND_ERROR = 'REGISTRATION_CLEAR_BACKEND_ERRO
|
||||
export const REGISTER_SET_COUNTRY_CODE = 'REGISTER_SET_COUNTRY_CODE';
|
||||
export const REGISTER_SET_USER_PIPELINE_DATA_LOADED = 'REGISTER_SET_USER_PIPELINE_DATA_LOADED';
|
||||
export const REGISTER_SET_EMAIL_SUGGESTIONS = 'REGISTER_SET_EMAIL_SUGGESTIONS';
|
||||
export const REGISTER_SET_AUTO_GENERATED_USERNAME_REGISTRATION_EXP_DATA = 'REGISTER_SET_AUTO_GENERATED_USERNAME_REGISTRATION_EXP_DATA';
|
||||
|
||||
// Backup registration form
|
||||
export const backupRegistrationForm = () => ({
|
||||
type: BACKUP_REGISTRATION_DATA.BASE,
|
||||
@@ -83,9 +83,3 @@ export const setUserPipelineDataLoaded = (value) => ({
|
||||
type: REGISTER_SET_USER_PIPELINE_DATA_LOADED,
|
||||
payload: { value },
|
||||
});
|
||||
|
||||
// Auto Generated Username Registration Experiment Actions
|
||||
export const setAutoGeneratedUsernameExperimentData = (autoGeneratedRegExpVariation) => ({
|
||||
type: REGISTER_SET_AUTO_GENERATED_USERNAME_REGISTRATION_EXP_DATA,
|
||||
payload: { autoGeneratedRegExpVariation },
|
||||
});
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* This file contains data for auto generated username Optimizely experiment
|
||||
*/
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
|
||||
export const NOT_INITIALIZED = 'experiment-not-initialized';
|
||||
export const CONTROL = 'control-registration-page';
|
||||
export const AUTO_GENERATED_USERNAME_REGISTRATION_EXP_VARIATION = 'auto-generated-username-register-page';
|
||||
const AUTO_GENERATED_USERNAME_EXP_PAGE = 'targeting_for_auto_generated_username_page';
|
||||
|
||||
export function getAutoGeneratedUsernameExperimentVariation() {
|
||||
try {
|
||||
if (window.optimizely
|
||||
&& window.optimizely.get('data').experiments[getConfig().AUTO_GENERATED_USERNAME_EXPERIMENT_ID]) {
|
||||
const selectedVariant = window.optimizely.get('state').getVariationMap()[
|
||||
getConfig().AUTO_GENERATED_USERNAME_EXPERIMENT_ID
|
||||
];
|
||||
return selectedVariant?.name;
|
||||
}
|
||||
} catch (e) { /* empty */ }
|
||||
return '';
|
||||
}
|
||||
|
||||
export function activateAutoGeneratedUsernameExperiment() {
|
||||
window.optimizely = window.optimizely || [];
|
||||
window.optimizely.push({
|
||||
type: 'page',
|
||||
pageName: AUTO_GENERATED_USERNAME_EXP_PAGE,
|
||||
});
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import {
|
||||
activateAutoGeneratedUsernameExperiment,
|
||||
getAutoGeneratedUsernameExperimentVariation,
|
||||
NOT_INITIALIZED,
|
||||
} from './helper';
|
||||
import { COMPLETE_STATE } from '../../../data/constants';
|
||||
|
||||
/**
|
||||
* This hook returns activates multi step registration experiment and returns the experiment
|
||||
* variation for the user.
|
||||
*/
|
||||
const useAutoGeneratedUsernameExperimentVariation = (
|
||||
initExpVariation,
|
||||
registrationEmbedded,
|
||||
tpaHint,
|
||||
currentProvider,
|
||||
thirdPartyAuthApiStatus,
|
||||
) => {
|
||||
const [variation, setVariation] = useState(initExpVariation);
|
||||
useEffect(() => {
|
||||
if (initExpVariation || registrationEmbedded || !!tpaHint || !!currentProvider
|
||||
|| thirdPartyAuthApiStatus !== COMPLETE_STATE) {
|
||||
return variation;
|
||||
}
|
||||
|
||||
const getVariation = () => {
|
||||
const expVariation = getAutoGeneratedUsernameExperimentVariation();
|
||||
if (expVariation) {
|
||||
setVariation(expVariation);
|
||||
} else {
|
||||
// This is to handle the case when user dont get variation for some reason, the register page
|
||||
// shows unlimited spinner.
|
||||
setVariation(NOT_INITIALIZED);
|
||||
}
|
||||
};
|
||||
|
||||
activateAutoGeneratedUsernameExperiment();
|
||||
|
||||
const timer = setTimeout(getVariation, 300);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [ // eslint-disable-line react-hooks/exhaustive-deps
|
||||
initExpVariation, currentProvider, registrationEmbedded, thirdPartyAuthApiStatus, tpaHint,
|
||||
]);
|
||||
|
||||
return variation;
|
||||
};
|
||||
|
||||
export default useAutoGeneratedUsernameExperimentVariation;
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
REGISTER_CLEAR_USERNAME_SUGGESTIONS,
|
||||
REGISTER_FORM_VALIDATIONS,
|
||||
REGISTER_NEW_USER,
|
||||
REGISTER_SET_AUTO_GENERATED_USERNAME_REGISTRATION_EXP_DATA,
|
||||
REGISTER_SET_COUNTRY_CODE,
|
||||
REGISTER_SET_EMAIL_SUGGESTIONS,
|
||||
REGISTER_SET_USER_PIPELINE_DATA_LOADED,
|
||||
@@ -40,7 +39,6 @@ export const defaultState = {
|
||||
usernameSuggestions: [],
|
||||
validationApiRateLimited: false,
|
||||
shouldBackupState: false,
|
||||
autoGeneratedUsernameExperimentVariation: '',
|
||||
};
|
||||
|
||||
const reducer = (state = defaultState, action = {}) => {
|
||||
@@ -57,12 +55,6 @@ const reducer = (state = defaultState, action = {}) => {
|
||||
registrationFormData: { ...action.payload },
|
||||
userPipelineDataLoaded: state.userPipelineDataLoaded,
|
||||
};
|
||||
case REGISTER_SET_AUTO_GENERATED_USERNAME_REGISTRATION_EXP_DATA: {
|
||||
return {
|
||||
...state,
|
||||
autoGeneratedUsernameExperimentVariation: action.payload.autoGeneratedRegExpVariation,
|
||||
};
|
||||
}
|
||||
case REGISTER_NEW_USER.BEGIN:
|
||||
return {
|
||||
...state,
|
||||
|
||||
@@ -38,7 +38,6 @@ describe('Registration Reducer Tests', () => {
|
||||
usernameSuggestions: [],
|
||||
validationApiRateLimited: false,
|
||||
shouldBackupState: false,
|
||||
autoGeneratedUsernameExperimentVariation: '',
|
||||
};
|
||||
|
||||
it('should return the initial state', () => {
|
||||
|
||||
@@ -43,31 +43,39 @@ export const isFormValid = (
|
||||
Object.keys(payload).forEach(key => {
|
||||
switch (key) {
|
||||
case 'name':
|
||||
fieldErrors.name = validateName(payload.name, formatMessage);
|
||||
if (!fieldErrors.name) {
|
||||
fieldErrors.name = validateName(payload.name, formatMessage);
|
||||
}
|
||||
if (fieldErrors.name) { isValid = false; }
|
||||
break;
|
||||
case 'email': {
|
||||
const {
|
||||
fieldError, confirmEmailError, suggestion,
|
||||
} = validateEmail(payload.email, configurableFormFields?.confirm_email, formatMessage);
|
||||
if (fieldError) {
|
||||
fieldErrors.email = fieldError;
|
||||
isValid = false;
|
||||
if (!fieldErrors.email) {
|
||||
const {
|
||||
fieldError, confirmEmailError, suggestion,
|
||||
} = validateEmail(payload.email, configurableFormFields?.confirm_email, formatMessage);
|
||||
if (fieldError) {
|
||||
fieldErrors.email = fieldError;
|
||||
isValid = false;
|
||||
}
|
||||
if (confirmEmailError) {
|
||||
fieldErrors.confirm_email = confirmEmailError;
|
||||
isValid = false;
|
||||
}
|
||||
emailSuggestion = suggestion;
|
||||
}
|
||||
if (confirmEmailError) {
|
||||
fieldErrors.confirm_email = confirmEmailError;
|
||||
isValid = false;
|
||||
}
|
||||
emailSuggestion = suggestion;
|
||||
if (fieldErrors.email) { isValid = false; }
|
||||
break;
|
||||
}
|
||||
case 'username':
|
||||
fieldErrors.username = validateUsername(payload.username, formatMessage);
|
||||
if (!fieldErrors.username) {
|
||||
fieldErrors.username = validateUsername(payload.username, formatMessage);
|
||||
}
|
||||
if (fieldErrors.username) { isValid = false; }
|
||||
break;
|
||||
case 'password':
|
||||
fieldErrors.password = validatePasswordField(payload.password, formatMessage);
|
||||
if (!fieldErrors.password) {
|
||||
fieldErrors.password = validatePasswordField(payload.password, formatMessage);
|
||||
}
|
||||
if (fieldErrors.password) { isValid = false; }
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -18,7 +18,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
import { resetPassword, validateToken } from './data/actions';
|
||||
import {
|
||||
FORM_SUBMISSION_ERROR, PASSWORD_RESET_ERROR, PASSWORD_VALIDATION_ERROR, SUCCESS, TOKEN_STATE,
|
||||
FORM_SUBMISSION_ERROR, PASSWORD_RESET_ERROR, PASSWORD_VALIDATION_ERROR, TOKEN_STATE,
|
||||
} from './data/constants';
|
||||
import { resetPasswordResultSelector } from './data/selectors';
|
||||
import { validatePassword } from './data/service';
|
||||
@@ -30,7 +30,6 @@ import {
|
||||
LETTER_REGEX, LOGIN_PAGE, NUMBER_REGEX, RESET_PAGE,
|
||||
} from '../data/constants';
|
||||
import { getAllPossibleQueryParams, updatePathWithQueryParams, windowScrollTo } from '../data/utils';
|
||||
import { trackPasswordResetSuccess, trackResetPasswordPageViewed } from '../tracking/trackers/reset-password';
|
||||
|
||||
const ResetPasswordPage = (props) => {
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -43,15 +42,6 @@ const ResetPasswordPage = (props) => {
|
||||
const { token } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (props.status === TOKEN_STATE.VALID) {
|
||||
trackResetPasswordPageViewed();
|
||||
}
|
||||
if (props.status === SUCCESS) {
|
||||
trackPasswordResetSuccess();
|
||||
}
|
||||
}, [props.status]);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.status !== TOKEN_STATE.PENDING && props.status !== PASSWORD_RESET_ERROR) {
|
||||
setErrorCode(props.status);
|
||||
@@ -149,7 +139,7 @@ const ResetPasswordPage = (props) => {
|
||||
}
|
||||
} else if (props.status === PASSWORD_RESET_ERROR) {
|
||||
navigate(updatePathWithQueryParams(RESET_PAGE));
|
||||
} else if (props.status === SUCCESS) {
|
||||
} else if (props.status === 'success') {
|
||||
navigate(updatePathWithQueryParams(LOGIN_PAGE));
|
||||
} else {
|
||||
return (
|
||||
|
||||
@@ -19,11 +19,6 @@ import ResetPasswordPage from '../ResetPasswordPage';
|
||||
const mockedNavigator = jest.fn();
|
||||
const token = '1c-bmjdkc-5e60e084cf8113048ca7';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics', () => ({
|
||||
sendPageEvent: jest.fn(),
|
||||
sendTrackEvent: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...(jest.requireActual('react-router-dom')),
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../data/segment/utils';
|
||||
|
||||
export const eventNames = {
|
||||
loginAndRegistration: 'login_and_registration',
|
||||
forgotPasswordPageViewed: 'edx.bi.password_reset_form.viewed',
|
||||
};
|
||||
|
||||
export const categories = {
|
||||
userEngagement: 'user-engagement',
|
||||
};
|
||||
|
||||
// Event tracker for forgot password page viewed
|
||||
export const trackForgotPasswordPageViewed = () => createEventTracker(
|
||||
eventNames.forgotPasswordPageViewed,
|
||||
{
|
||||
category: categories.userEngagement,
|
||||
},
|
||||
)();
|
||||
|
||||
export const trackForgotPasswordPageEvent = () => {
|
||||
createPageEventTracker(eventNames.loginAndRegistration, 'forgot-password')();
|
||||
};
|
||||
@@ -1,29 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../data/segment/utils';
|
||||
|
||||
export const eventNames = {
|
||||
forgotPasswordLinkClicked: 'edx.bi.password-reset_form.toggled',
|
||||
loginAndRegistration: 'login_and_registration',
|
||||
registerFormToggled: 'edx.bi.register_form.toggled',
|
||||
loginSuccess: 'edx.bi.user.account.authenticated.client',
|
||||
};
|
||||
|
||||
export const categories = {
|
||||
userEngagement: 'user-engagement',
|
||||
};
|
||||
|
||||
// Event tracker for Forgot Password link click
|
||||
export const trackForgotPasswordLinkClick = () => createEventTracker(
|
||||
eventNames.forgotPasswordLinkClicked,
|
||||
{ category: categories.userEngagement },
|
||||
)();
|
||||
|
||||
// Tracks the login page event.
|
||||
export const trackLoginPageViewed = () => {
|
||||
createPageEventTracker(eventNames.loginAndRegistration, 'login')();
|
||||
};
|
||||
|
||||
// Tracks the login sucess event.
|
||||
export const trackLoginSuccess = () => createEventTracker(
|
||||
eventNames.loginSuccess,
|
||||
{},
|
||||
)();
|
||||
@@ -1,37 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../data/segment/utils';
|
||||
|
||||
export const eventNames = {
|
||||
progressiveProfilingSubmitClick: 'edx.bi.welcome.page.submit.clicked',
|
||||
progressiveProfilingSkipLinkClick: 'edx.bi.welcome.page.skip.link.clicked',
|
||||
disablePostRegistrationRecommendations: 'edx.bi.user.recommendations.not.enabled',
|
||||
progressiveProfilingSupportLinkCLick: 'edx.bi.welcome.page.support.link.clicked',
|
||||
loginAndRegistration: 'login_and_registration',
|
||||
};
|
||||
|
||||
// Event link tracker for Progressive profiling skip button click
|
||||
export const trackProgressiveProfilingSkipLinkClick = evenProperties => createEventTracker(
|
||||
eventNames.progressiveProfilingSkipLinkClick, { ...evenProperties },
|
||||
)();
|
||||
|
||||
// Event tracker for progressive profiling submit button click
|
||||
export const trackProgressiveProfilingSubmitClick = (evenProperties) => createEventTracker(
|
||||
eventNames.progressiveProfilingSubmitClick,
|
||||
{ ...evenProperties },
|
||||
)();
|
||||
|
||||
// Event tracker for progressive profiling submit button click
|
||||
export const trackDisablePostRegistrationRecommendations = (evenProperties) => createEventTracker(
|
||||
eventNames.disablePostRegistrationRecommendations,
|
||||
{ ...evenProperties },
|
||||
)();
|
||||
|
||||
// Tracks the progressive profiling page event.
|
||||
export const trackProgressiveProfilingPageViewed = () => {
|
||||
createPageEventTracker(eventNames.loginAndRegistration, 'welcome')();
|
||||
};
|
||||
|
||||
// Tracks the progressive profiling spport link click.
|
||||
export const trackProgressiveProfilingSupportLinkCLick = () => createEventTracker(
|
||||
eventNames.progressiveProfilingSupportLinkCLick,
|
||||
{},
|
||||
)();
|
||||
@@ -1,22 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../data/segment/utils';
|
||||
|
||||
export const eventNames = {
|
||||
loginAndRegistration: 'login_and_registration',
|
||||
registrationSuccess: 'edx.bi.user.account.registered.client',
|
||||
loginFormToggled: 'edx.bi.login_form.toggled',
|
||||
};
|
||||
|
||||
export const categories = {
|
||||
userEngagement: 'user-engagement',
|
||||
};
|
||||
|
||||
// Event tracker for successful registration
|
||||
export const trackRegistrationSuccess = () => createEventTracker(
|
||||
eventNames.registrationSuccess,
|
||||
{},
|
||||
)();
|
||||
|
||||
// Tracks the progressive profiling page event.
|
||||
export const trackRegistrationPageViewed = () => {
|
||||
createPageEventTracker(eventNames.loginAndRegistration, 'register')();
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../data/segment/utils';
|
||||
|
||||
export const eventNames = {
|
||||
loginAndRegistration: 'login_and_registration',
|
||||
resetPasswordSuccess: 'edx.bi.user.password.reset.success',
|
||||
};
|
||||
|
||||
export const trackResetPasswordPageViewed = () => {
|
||||
createPageEventTracker(eventNames.loginAndRegistration, 'reset-password')();
|
||||
};
|
||||
|
||||
export const trackPasswordResetSuccess = () => {
|
||||
createEventTracker(eventNames.resetPasswordSuccess, {})();
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../../data/segment/utils';
|
||||
import {
|
||||
categories,
|
||||
eventNames,
|
||||
trackForgotPasswordPageEvent,
|
||||
trackForgotPasswordPageViewed,
|
||||
} from '../forgotpassword';
|
||||
|
||||
// Mock createEventTracker function
|
||||
jest.mock('../../../data/segment/utils', () => ({
|
||||
createEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createPageEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
}));
|
||||
|
||||
describe('Tracking Functions', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should fire trackForgotPasswordPageEvent', () => {
|
||||
trackForgotPasswordPageEvent();
|
||||
|
||||
expect(createPageEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.loginAndRegistration,
|
||||
'forgot-password',
|
||||
);
|
||||
});
|
||||
|
||||
it('should fire forgotPasswordPageViewedEvent', () => {
|
||||
trackForgotPasswordPageViewed();
|
||||
|
||||
expect(createEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.forgotPasswordPageViewed,
|
||||
{ category: categories.userEngagement },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../../data/segment/utils';
|
||||
import {
|
||||
categories,
|
||||
eventNames,
|
||||
trackForgotPasswordLinkClick,
|
||||
trackLoginPageViewed,
|
||||
} from '../login';
|
||||
|
||||
// Mock createEventTracker function
|
||||
jest.mock('../../../data/segment/utils', () => ({
|
||||
createEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createPageEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
}));
|
||||
|
||||
describe('Tracking Functions', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('trackForgotPasswordLinkClick function', () => {
|
||||
trackForgotPasswordLinkClick();
|
||||
|
||||
expect(createEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.forgotPasswordLinkClicked,
|
||||
{ category: categories.userEngagement },
|
||||
);
|
||||
});
|
||||
|
||||
it('trackLoginPageEvent function', () => {
|
||||
trackLoginPageViewed();
|
||||
|
||||
expect(createPageEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.loginAndRegistration,
|
||||
'login',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,37 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../../data/segment/utils';
|
||||
import {
|
||||
eventNames,
|
||||
trackProgressiveProfilingPageViewed,
|
||||
trackProgressiveProfilingSkipLinkClick,
|
||||
} from '../progressive-profiling';
|
||||
|
||||
// Mock createEventTracker function
|
||||
jest.mock('../../../data/segment/utils', () => ({
|
||||
createEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createPageEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createLinkTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
}));
|
||||
|
||||
describe('Tracking Functions', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should fire trackProgressiveProfilingSkipLinkClickEvent', () => {
|
||||
trackProgressiveProfilingSkipLinkClick();
|
||||
|
||||
expect(createEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.progressiveProfilingSkipLinkClick,
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should fire trackProgressiveProfilingPageEvent', () => {
|
||||
trackProgressiveProfilingPageViewed();
|
||||
|
||||
expect(createPageEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.loginAndRegistration,
|
||||
'welcome',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,36 +0,0 @@
|
||||
import { createEventTracker, createPageEventTracker } from '../../../data/segment/utils';
|
||||
import {
|
||||
eventNames,
|
||||
trackRegistrationPageViewed,
|
||||
trackRegistrationSuccess,
|
||||
} from '../register';
|
||||
|
||||
// Mock createEventTracker function
|
||||
jest.mock('../../../data/segment/utils', () => ({
|
||||
createEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createPageEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
}));
|
||||
|
||||
describe('Tracking Functions', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should fire registrationSuccessEvent', () => {
|
||||
trackRegistrationSuccess();
|
||||
|
||||
expect(createEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.registrationSuccess,
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
it('should fire trackRegistrationPageEvent', () => {
|
||||
trackRegistrationPageViewed();
|
||||
|
||||
expect(createPageEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.loginAndRegistration,
|
||||
'register',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import { createPageEventTracker } from '../../../data/segment/utils';
|
||||
import {
|
||||
eventNames,
|
||||
trackResetPasswordPageViewed,
|
||||
} from '../reset-password';
|
||||
|
||||
// Mock createEventTracker function
|
||||
jest.mock('../../../data/segment/utils', () => ({
|
||||
createEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
createPageEventTracker: jest.fn().mockImplementation(() => jest.fn()),
|
||||
}));
|
||||
|
||||
describe('Tracking Functions', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should fire trackResettPasswordPageEvent', () => {
|
||||
trackResetPasswordPageViewed();
|
||||
|
||||
expect(createPageEventTracker).toHaveBeenCalledWith(
|
||||
eventNames.loginAndRegistration,
|
||||
'reset-password',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user