diff --git a/.eslintrc b/.eslintrc index 64423cd8..7f627918 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,4 @@ { - "extends": [ - "@kth/eslint-config-kth" - ] -} \ No newline at end of file + "root": true, + "extends": ["@kth/eslint-config-kth"], +} diff --git a/package-lock.json b/package-lock.json index 6ef49565..daf17208 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,12 +37,9 @@ "react-data-table-component": "^7.6.2", "react-dom": "^18.2.0", "react-icons": "^5.0.1", - "react-router": "^6.22.3", "react-router-dom": "^6.22.3", "reactstrap": "^9.2.2", - "rimraf": "^5.0.5", "sanitize-html": "^2.12.1", - "styled-components": "^6.1.8", "victory": "^36.9.1", "xlsx": "^0.18.5" }, @@ -59,19 +56,17 @@ "@testing-library/react": "^14.2.1", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", - "ansi-regex": "^6.0.1", "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "css-loader": "^6.10.0", - "decache": "^4.6.2", "eslint": "^8.57.0", + "eslint-plugin-prettier": "^5.1.3", "file-loader": "^6.2.0", "husky": "^9.0.11", "jest": "^29.7.0", "jest-environment-jsdom": "29.7.0", - "jest-extended": "^4.0.2", "lint-staged": "^15.2.2", "mini-css-extract-plugin": "^2.8.1", "nodemon": "^3.1.0", @@ -83,7 +78,6 @@ "react-error-boundary": "^4.0.13", "sass": "^1.71.1", "sass-loader": "^14.1.1", - "set-value": "^4.1.0", "terser-webpack-plugin": "^5.3.10", "webpack": "^5.90.3", "webpack-cli": "^5.1.4" @@ -2100,6 +2094,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "peer": true, "dependencies": { "@emotion/memoize": "^0.8.1" } @@ -2107,12 +2102,14 @@ "node_modules/@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "peer": true }, "node_modules/@emotion/unitless": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==", + "peer": true }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", @@ -3217,35 +3214,6 @@ "eslint-plugin-testing-library": "^6.0.1" } }, - "node_modules/@kth/eslint-config-kth/node_modules/eslint-plugin-prettier": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.1.tgz", - "integrity": "sha512-m3u5RnR56asrwV/lDC4GHorlW75DsFfmUcjfCYylTUs85dBRnB7VM6xG8eCMJdeDRnppzmxZVf1GEPJvl1JmNg==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.5" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, "node_modules/@kth/kth-node-response": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@kth/kth-node-response/-/kth-node-response-1.0.7.tgz", @@ -4223,7 +4191,8 @@ "node_modules/@types/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==", + "peer": true }, "node_modules/@types/tough-cookie": { "version": "4.0.5", @@ -5767,15 +5736,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5839,6 +5799,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6550,6 +6511,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "peer": true, "engines": { "node": ">=4" } @@ -6641,6 +6603,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "peer": true, "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", @@ -6879,15 +6842,6 @@ } } }, - "node_modules/decache": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/decache/-/decache-4.6.2.tgz", - "integrity": "sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==", - "dev": true, - "dependencies": { - "callsite": "^1.0.0" - } - }, "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", @@ -7489,9 +7443,9 @@ } }, "node_modules/envinfo": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", - "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", + "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -7946,6 +7900,36 @@ "dequal": "^2.0.3" } }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react": { "version": "7.33.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", @@ -9888,15 +9872,6 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "node_modules/is-primitive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -10969,27 +10944,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-extended": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.2.tgz", - "integrity": "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog==", - "dev": true, - "dependencies": { - "jest-diff": "^29.0.0", - "jest-get-type": "^29.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "jest": ">=27.2.5" - }, - "peerDependenciesMeta": { - "jest": { - "optional": true - } - } - }, "node_modules/jest-get-type": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", @@ -15311,66 +15265,6 @@ "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", "dev": true }, - "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/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==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-applescript": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", @@ -15740,36 +15634,6 @@ "node": ">= 0.4" } }, - "node_modules/set-value": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", - "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", - "dev": true, - "funding": [ - "https://github.com/sponsors/jonschlinkert", - "https://paypal.me/jonathanschlinkert", - "https://jonschlinkert.dev/sponsor" - ], - "dependencies": { - "is-plain-object": "^2.0.4", - "is-primitive": "^3.0.1" - }, - "engines": { - "node": ">=11.0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -15790,7 +15654,8 @@ "node_modules/shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "peer": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -16247,6 +16112,7 @@ "version": "6.1.8", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", + "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.2.1", "@emotion/unitless": "0.8.0", @@ -16273,7 +16139,8 @@ "node_modules/styled-components/node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "peer": true }, "node_modules/styled-components/node_modules/postcss": { "version": "8.4.31", @@ -16293,6 +16160,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -16305,12 +16173,14 @@ "node_modules/styled-components/node_modules/tslib": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "peer": true }, "node_modules/stylis": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", - "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==", + "peer": true }, "node_modules/supports-color": { "version": "5.5.0", diff --git a/package.json b/package.json index f87fe83d..23664823 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:file:watch": "jest ./server/apiCalls/transformers/offerings-over-several-semesters.test.js --watch", "test:notify": "jest --watch --notify", "docker": "npm install --development && npm run build && npm prune --production", - "lint": "eslint . && prettier-eslint --list-different **/*.js", + "lint": "eslint public server && prettier-eslint --list-different **/*.js", "prepare": "husky", "start": "bash -c 'cat /KTH_NODEJS; NODE_ENV=production node app.js'", "start-dev": "bash -c 'NODE_ENV=development concurrently --kill-others -n build,app \"npm run build-dev\" \"nodemon app.js\"'" @@ -54,12 +54,9 @@ "react-data-table-component": "^7.6.2", "react-dom": "^18.2.0", "react-icons": "^5.0.1", - "react-router": "^6.22.3", "react-router-dom": "^6.22.3", "reactstrap": "^9.2.2", - "rimraf": "^5.0.5", "sanitize-html": "^2.12.1", - "styled-components": "^6.1.8", "victory": "^36.9.1", "xlsx": "^0.18.5" }, @@ -76,19 +73,17 @@ "@testing-library/react": "^14.2.1", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", - "ansi-regex": "^6.0.1", "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "css-loader": "^6.10.0", - "decache": "^4.6.2", "eslint": "^8.57.0", + "eslint-plugin-prettier": "^5.1.3", "file-loader": "^6.2.0", "husky": "^9.0.11", "jest": "^29.7.0", "jest-environment-jsdom": "29.7.0", - "jest-extended": "^4.0.2", "lint-staged": "^15.2.2", "mini-css-extract-plugin": "^2.8.1", "nodemon": "^3.1.0", @@ -100,7 +95,6 @@ "react-error-boundary": "^4.0.13", "sass": "^1.71.1", "sass-loader": "^14.1.1", - "set-value": "^4.1.0", "terser-webpack-plugin": "^5.3.10", "webpack": "^5.90.3", "webpack-cli": "^5.1.4" diff --git a/public/js/app/app.jsx b/public/js/app/app.jsx index bdf91536..3c2fcfe2 100644 --- a/public/js/app/app.jsx +++ b/public/js/app/app.jsx @@ -1,6 +1,6 @@ 'use strict' -import React, { useState, useEffect } from 'react' +import React from 'react' import { BrowserRouter, Route, Routes } from 'react-router-dom' import { ErrorBoundary } from 'react-error-boundary' import { hydrateRoot } from 'react-dom/client' @@ -8,10 +8,10 @@ import { WebContextProvider } from './context/WebContext' import { uncompressData } from './context/compress' import CoursePage from './pages/CoursePage' import CourseStatisticsPage from './pages/CourseStatisticsPage' -import ExperimentCoursePage from './pages/ExperimentCoursePage' import '../../css/kursinfo-web.scss' function ErrorFallback({ error, resetErrorBoundary }) { + // eslint-disable-next-line no-console console.error(error) return (
@@ -34,7 +34,6 @@ function appFactory(applicationStore, context) { } /> - } /> } /> } /> diff --git a/public/js/app/components/__tests__/BankIdAlert.test.js b/public/js/app/components/__tests__/BankIdAlert.test.js index d968596f..1c61002d 100644 --- a/public/js/app/components/__tests__/BankIdAlert.test.js +++ b/public/js/app/components/__tests__/BankIdAlert.test.js @@ -1,6 +1,6 @@ /* eslint-disable react/jsx-props-no-spreading */ import React from 'react' -import { render, screen, waitFor } from '@testing-library/react' +import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { WebContextProvider } from '../../context/WebContext' import i18n from '../../../../../i18n' @@ -20,7 +20,7 @@ describe('Comoponent ', () => { fundingType: 'LL', contextLang: 'en', roundSpecified: true, - translation: translation, + translation, } render( @@ -28,13 +28,13 @@ describe('Comoponent ', () => { ) - const alert = screen.getByText( + const expectedAlert = screen.getByText( new RegExp( `You could meet obstacles if you're required to pay fees or if you do not have a Swedish Mobile BankID.`, 'i' ) ) - expect(alert).toBeInTheDocument() + expect(expectedAlert).toBeInTheDocument() const link = screen.getByRole('link', { name: 'Students not located in Sweden may have problems attending a course at KTH.', @@ -50,7 +50,7 @@ describe('Comoponent ', () => { fundingType: 'LL', contextLang: 'sv', roundSpecified: true, - translation: translation, + translation, } render( @@ -58,10 +58,10 @@ describe('Comoponent ', () => { ) - const alert = screen.getByText( + const expectedAlert = screen.getByText( `Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.` ) - expect(alert).toBeInTheDocument() + expect(expectedAlert).toBeInTheDocument() }) test('does not render BankIdAlert for a Swedish non-distance course', () => { @@ -72,7 +72,7 @@ describe('Comoponent ', () => { fundingType: 'LL', contextLang: 'sv', roundSpecified: true, - translation: translation, + translation, } render( @@ -80,10 +80,10 @@ describe('Comoponent ', () => { ) - const alert = screen.queryByText( + const expectedAlert = screen.queryByText( `Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.` ) - expect(alert).not.toBeInTheDocument() + expect(expectedAlert).not.toBeInTheDocument() }) test('does not render BankIdAlert without roundSpecified', () => { @@ -94,7 +94,7 @@ describe('Comoponent ', () => { fundingType: 'LL', contextLang: 'sv', roundSpecified: false, - translation: translation, + translation, } render( @@ -102,10 +102,10 @@ describe('Comoponent ', () => { ) - const alert = screen.queryByText( + const expectedAlert = screen.queryByText( `Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.` ) - expect(alert).not.toBeInTheDocument() + expect(expectedAlert).not.toBeInTheDocument() }) test('does not render BankIdAlert with non LL fundingType', () => { @@ -116,7 +116,7 @@ describe('Comoponent ', () => { fundingType: 'VV', contextLang: 'sv', roundSpecified: true, - translation: translation, + translation, } render( @@ -124,10 +124,10 @@ describe('Comoponent ', () => { ) - const alert = screen.queryByText( + const expectedAlert = screen.queryByText( `Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.` ) - expect(alert).not.toBeInTheDocument() + expect(expectedAlert).not.toBeInTheDocument() }) test('does not render BankIdAlert without contextLang', () => { const translation = i18n.messages[TRANSLATION_SWEDISH_INDEX] @@ -137,7 +137,7 @@ describe('Comoponent ', () => { fundingType: 'LL', contextLang: undefined, roundSpecified: true, - translation: translation, + translation, } render( @@ -146,9 +146,9 @@ describe('Comoponent ', () => { ) - const alert = screen.queryByText( + const expectedAlert = screen.queryByText( `Du behöver ett KTH-konto för att läsa en kurs på KTH, kontot aktiveras med Mobilt BankID eller genom att besöka KTH:s campus. Det enda sättet att starta en kurs utan att besöka campus, är om du har Mobilt BankID.` ) - expect(alert).not.toBeInTheDocument() + expect(expectedAlert).not.toBeInTheDocument() }) }) diff --git a/public/js/app/components/__tests__/CourseFileLinks.test.js b/public/js/app/components/__tests__/CourseFileLinks.test.js index a4eacb62..2775a8d1 100644 --- a/public/js/app/components/__tests__/CourseFileLinks.test.js +++ b/public/js/app/components/__tests__/CourseFileLinks.test.js @@ -7,13 +7,7 @@ import CourseFileLinks from '../CourseFileLinks' import i18n from '../../../../../i18n' import { INFORM_IF_IMPORTANT_INFO_IS_MISSING } from '../../util/constants' -const { getByText } = screen - describe('Component ', () => { - test('renders course file links', () => { - render() - }) - test('renders course offering schedule correctly', () => { const language = 'en' const [translate] = i18n.messages // en @@ -27,11 +21,11 @@ describe('Component ', () => { } const { rerender } = render() - const scheduleLink = getByText(translate.courseLabels.label_schedule) + const scheduleLink = screen.getByText(translate.courseLabels.label_schedule) expect(scheduleLink).toBeInTheDocument() rerender() - const scheduleText = getByText(translate.courseLabels.no_schedule_published) + const scheduleText = screen.getByText(translate.courseLabels.no_schedule_published) expect(scheduleText).toBeInTheDocument() }) @@ -45,7 +39,7 @@ describe('Component ', () => { } render() - const memoLink = getByText(`${translate.courseLabels.label_link_course_memo}`) + const memoLink = screen.getByText(`${translate.courseLabels.label_link_course_memo}`) expect(memoLink).toBeInTheDocument() expect(memoLink.href).toBe('https://test.com/testedMemo') }) @@ -69,11 +63,11 @@ describe('Component ', () => { } const { rerender } = render() - const memoLink = getByText(`${translate.courseLabels.label_link_course_memo}`) + const memoLink = screen.getByText(`${translate.courseLabels.label_link_course_memo}`) expect(memoLink).toBeInTheDocument() rerender() - const linkToMemoWebPage = getByText(translate.courseLabels.label_link_course_memo) + const linkToMemoWebPage = screen.getByText(translate.courseLabels.label_link_course_memo) expect(linkToMemoWebPage).toBeInTheDocument() expect(linkToMemoWebPage.href).toBe('http://localhost/kurs-pm/KIP1111/19701/7') }) @@ -92,8 +86,8 @@ describe('Component ', () => { }, } - const { rerender } = render() - const memoLink = getByText(`${translate.courseLabels.label_link_course_memo}`) + render() + const memoLink = screen.getByText(`${translate.courseLabels.label_link_course_memo}`) expect(memoLink).toBeInTheDocument() }) }) diff --git a/public/js/app/components/__tests__/CourseSectionList.test.js b/public/js/app/components/__tests__/CourseSectionList.test.js index c0466017..ae977938 100644 --- a/public/js/app/components/__tests__/CourseSectionList.test.js +++ b/public/js/app/components/__tests__/CourseSectionList.test.js @@ -8,15 +8,6 @@ import CourseSectionList from '../CourseSectionList' const INFORM_IF_IMPORTANT_INFO_IS_MISSING = ['No information inserted', 'Ingen information tillagd'] describe('Component ', () => { - test('renders a course section list', () => { - const context = {} - render( - - - - ) - }) - test('renders course literature correctly', () => { const language = 'en' const [courseLiteratureNoTitle] = INFORM_IF_IMPORTANT_INFO_IS_MISSING // en @@ -65,7 +56,7 @@ describe('Component ', () => { const literatureText = screen.getByText(courseLiteratureTitle) expect(literatureText).toBeInTheDocument() let syllabusText = screen.queryByText(syllabusLiteratureTitle) - expect(syllabusText).toBeNull() + expect(syllabusText).not.toBeInTheDocument() // Course hasn't literature, syllabus does without comment – Show only literature (no comment) from syllabus rerender( @@ -79,7 +70,7 @@ describe('Component ', () => { syllabusText = screen.getByText(syllabusLiteratureTitle, { exact: false }) expect(syllabusText).toBeInTheDocument() syllabusText = screen.queryByText(syllabusLiteratureNoComment) - expect(syllabusText).toBeNull() + expect(syllabusText).not.toBeInTheDocument() // Course hasn't literature, syllabus does with comment – Show literature and literature comment from syllabus rerender( diff --git a/public/js/app/components/__tests__/CourseSections.test.js b/public/js/app/components/__tests__/CourseSections.test.js index 978f93a6..23b0bec6 100644 --- a/public/js/app/components/__tests__/CourseSections.test.js +++ b/public/js/app/components/__tests__/CourseSections.test.js @@ -1,17 +1,14 @@ +/* eslint-disable testing-library/no-node-access */ import React from 'react' +import '@testing-library/jest-dom' +import { render, screen } from '@testing-library/react' import CourseSections from '../CourseSections' import i18n from '../../../../../i18n' -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -const { getByText } = screen + const [translationEN] = i18n.messages describe('Component ', () => { - test('renders course sections', () => { - render() - }) - test('render text with a syllabus marker correctly', () => { const mockData = [{ header: 'First test header', text: 'Text for test from test syllabus', syllabusMarker: true }] render( @@ -24,12 +21,12 @@ describe('Component ', () => { /> ) - const header = getByText(mockData[0].header) + const header = screen.getByText(mockData[0].header) expect(header).toBeInTheDocument() expect(header.querySelector('sup')).toBeInTheDocument() expect(header.querySelector('sup').querySelector('svg')).toBeInTheDocument() - const syllabusText = getByText(mockData[0].text) + const syllabusText = screen.getByText(mockData[0].text) expect(syllabusText).toBeInTheDocument() }) @@ -44,9 +41,9 @@ describe('Component ', () => { syllabusMarkerAriaLabel={translationEN.courseLabels.syllabus_marker_aria_label} /> ) - const header = getByText(mockData[0].header) + const header = screen.getByText(mockData[0].header) expect(header).toBeInTheDocument() - const syllabusText = getByText(mockData[0].text) + const syllabusText = screen.getByText(mockData[0].text) expect(syllabusText).toBeInTheDocument() expect(header.querySelector('sup')).toBeNull() @@ -67,14 +64,14 @@ describe('Component ', () => { /> ) - const text1 = getByText(mockData[0].header) + const text1 = screen.getByText(mockData[0].header) expect(text1).toBeInTheDocument() - const syllabusText1 = getByText(mockData[0].text) + const syllabusText1 = screen.getByText(mockData[0].text) expect(syllabusText1).toBeInTheDocument() - const text2 = getByText(mockData[1].header) + const text2 = screen.getByText(mockData[1].header) expect(text2).toBeInTheDocument() - const syllabusText2 = getByText(mockData[1].text) + const syllabusText2 = screen.getByText(mockData[1].text) expect(syllabusText2).toBeInTheDocument() }) }) diff --git a/public/js/app/components/__tests__/CourseTitle.test.js b/public/js/app/components/__tests__/CourseTitle.test.js index b67bc05e..8d5fa2ba 100644 --- a/public/js/app/components/__tests__/CourseTitle.test.js +++ b/public/js/app/components/__tests__/CourseTitle.test.js @@ -9,11 +9,7 @@ import '@testing-library/jest-dom' const [translationEN, translationSV] = i18n.messages describe('Component ', () => { - test('renders a course title', () => { - render() - }) - - test('renders a course title with data and use correct credit unit in English', done => { + test('renders a course title with data and use correct credit unit in English', () => { const courseTitleData = { course_code: 'KIP1111', course_title: 'Project in Plasma Physics', @@ -41,11 +37,9 @@ describe('Component ', () => { const adminLinkName = screen.queryByText('Administer About course') expect(adminLinkName).toBeInTheDocument() - - done() }) - test('renders a course title with data and use correct credit unit in Swedish', done => { + test('renders a course title with data and use correct credit unit in Swedish', () => { const courseTitleData = { course_code: 'KIP1111', course_title: 'Projekt i plasmafysik', @@ -73,6 +67,5 @@ describe('Component ', () => { const adminLinkName = screen.queryByText('Administrera Om kursen') expect(adminLinkName).toBeInTheDocument() - done() }) }) diff --git a/public/js/app/components/__tests__/InfoModal.test.js b/public/js/app/components/__tests__/InfoModal.test.js index 96d84df8..d6b5e3bc 100644 --- a/public/js/app/components/__tests__/InfoModal.test.js +++ b/public/js/app/components/__tests__/InfoModal.test.js @@ -5,111 +5,102 @@ import InfoModal from '../InfoModal' import '@testing-library/jest-dom' -const { queryByText, getByRole, getAllByRole } = screen - describe('Component without data 1I', () => { - test('renders an info modal', () => { + test('renders modal button', () => { render() + const modalBtn = screen.getByRole('button') + expect(modalBtn).toBeInTheDocument() }) }) -describe('Component with html text 2I', () => { - beforeEach(() => - render( - - ) +const renderInfoModal = () => + render( + ) - test('renders modal button with aria label', done => { - const modalBtn = getByRole('button') +describe('Component with html text 2I', () => { + test('renders modal button with aria label', () => { + renderInfoModal() + const modalBtn = screen.getByRole('button') expect(modalBtn).toBeInTheDocument() expect(modalBtn).toHaveAttribute('aria-label', 'Information about choosing semester and course offering') - - done() }) test('renders modal 2 close buttons if modal is open', async () => { - const modalBtn = getByRole('button') + renderInfoModal() + const modalBtn = screen.getByRole('button') // Open modal fireEvent.click(modalBtn) await waitFor(() => { - const allBtns = getAllByRole('button') + const allBtns = screen.getAllByRole('button') expect(allBtns[1]).toHaveTextContent('×') - expect(allBtns[2]).toHaveTextContent('Close') }) + const allBtns = screen.getAllByRole('button') + expect(allBtns[2]).toHaveTextContent('Close') }) test('renders modal heading and text included as html if modal is open', async () => { - const modalBtn = getByRole('button') + renderInfoModal() + const modalBtn = screen.getByRole('button') // Open modal fireEvent.click(modalBtn) await waitFor(() => { - const heading = getByRole('heading', { level: 5 }) + const heading = screen.getByRole('heading', { level: 5 }) expect(heading).toHaveTextContent('Valid for') - - const stringFromHtml = queryByText( - '• A course goes different course offerings. To see information about a specific course offering, choose semester and course offering.' - ) - expect(stringFromHtml).toBeInTheDocument() }) + + const stringFromHtml = screen.queryByText( + '• A course goes different course offerings. To see information about a specific course offering, choose semester and course offering.' + ) + expect(stringFromHtml).toBeInTheDocument() }) }) describe('Component and its functionality 3I', () => { - beforeEach(() => - render( - - ) - ) - test('open modal and close by clicking ×', async () => { - const modalBtn = getByRole('button') + renderInfoModal() + const modalBtn = screen.getByRole('button') // Open modal i fireEvent.click(modalBtn) await waitFor(() => { - expect(queryByText('Valid for')).toBeInTheDocument() + expect(screen.getByText('Valid for')).toBeInTheDocument() }) // Close modal using × - const modalCrossBtn = getByRole('button', { name: '×' }) + const modalCrossBtn = screen.getByRole('button', { name: '×' }) fireEvent.click(modalCrossBtn) - setTimeout(async () => waitForElementToBeRemoved(() => queryByText('Valid for')), 1000) + setTimeout(async () => waitForElementToBeRemoved(() => screen.queryByText('Valid for')), 1000) }) test('open modal and close by clicking button "Close"', async () => { - const modalBtn = getByRole('button') + renderInfoModal() + const modalBtn = screen.getByRole('button') // Open modal i fireEvent.click(modalBtn) await waitFor(() => { - expect(queryByText('Valid for')).toBeInTheDocument() + expect(screen.getByText('Valid for')).toBeInTheDocument() }) // Close modal using "Close" - const modalCloseBtn = getByRole('button', { name: /close/i }) + const modalCloseBtn = screen.getByRole('button', { name: /close/i }) fireEvent.click(modalCloseBtn) - setTimeout(async () => waitForElementToBeRemoved(() => queryByText('Valid for')), 1000) + setTimeout(async () => waitForElementToBeRemoved(() => screen.queryByText('Valid for')), 1000) }) }) describe('Component with non-html text 4I', () => { - beforeEach(() => + test('renders modal heading if modal is open', async () => { render( with non-html text 4I', () => { closeLabel="Close" /> ) - ) - - test('renders modal heading if modal is open', async () => { - const modalBtn = getByRole('button') + const modalBtn = screen.getByRole('button') // Open modal fireEvent.click(modalBtn) await waitFor(() => { - const heading = getByRole('heading', { level: 5 }) + const heading = screen.getByRole('heading', { level: 5 }) expect(heading).toHaveTextContent('Valid for') - - const string = queryByText( - '• A course goes different course offerings. To see information about a specific course offering, choose semester and course offering.' - ) - expect(string).toBeInTheDocument() }) + + const string = screen.queryByText( + '• A course goes different course offerings. To see information about a specific course offering, choose semester and course offering.' + ) + expect(string).toBeInTheDocument() }) }) diff --git a/public/js/app/components/__tests__/RoundInformationOneCol.test.js b/public/js/app/components/__tests__/RoundInformationOneCol.test.js index 103351ef..6b6b54a5 100644 --- a/public/js/app/components/__tests__/RoundInformationOneCol.test.js +++ b/public/js/app/components/__tests__/RoundInformationOneCol.test.js @@ -1,6 +1,6 @@ /* eslint-disable react/jsx-props-no-spreading */ import React from 'react' -import { render, screen, waitFor } from '@testing-library/react' +import { render, screen, waitFor, within } from '@testing-library/react' import '@testing-library/jest-dom' import { WebContextProvider } from '../../context/WebContext' @@ -10,13 +10,6 @@ const INFORM_IF_IMPORTANT_INFO_IS_MISSING = ['No information inserted', 'Ingen i const context = { browserConfig: {}, sellingText: { en: '', sv: '' }, imageFromAdmin: '' } describe('Component ', () => { - test('renders a course information column', () => { - render( - - - - ) - }) test('renders study pace correctly', () => { const propsWithStudyPace = { language: 'en', @@ -135,25 +128,27 @@ describe('Component ', () => { {' '} ) + const label = screen.getByText('Number of places') expect(label).toBeInTheDocument() - expect(label.querySelector('button')).toBeInTheDocument() + + const button = within(label).getByRole('button') const seatsNum = screen.getByText('Max: 10') expect(seatsNum).toBeInTheDocument() - label.querySelector('button').click() + button.click() await waitFor(() => { expect( screen.getByText( 'Course offering may be cancelled if number of admitted are less than minimum of places. If there are more applicants than number of places selection will be made. The selection results are based on:' ) ).toBeInTheDocument() - expect(screen.getByText('English. Spicy jalapeno bacon ipsum')).toBeInTheDocument() }) + expect(screen.getByText('English. Spicy jalapeno bacon ipsum')).toBeInTheDocument() }) - test('renders default text and hide info icon if a course offering number of places is not provided', done => { + test('renders default text and hide info icon if a course offering number of places is not provided', () => { const propsWithoutSeatsNum = { language: 'en', showRoundData: true, @@ -175,12 +170,12 @@ describe('Component ', () => { const label = screen.getByText('Number of places') expect(label).toBeInTheDocument() - expect(label.querySelector('button')).toBeFalsy() + const button = within(label).queryByRole('button') + + expect(button).not.toBeInTheDocument() const seatsNum = screen.getByText('Places are not limited') expect(seatsNum).toBeInTheDocument() - - done() }) test('renders course offering number of places correctly and default text in modal if selection criteria is empty', async () => { @@ -205,20 +200,22 @@ describe('Component ', () => { const label = screen.getByText('Number of places') expect(label).toBeInTheDocument() - expect(label.querySelector('button')).toBeInTheDocument() + const button = within(label).getByRole('button') + + expect(button).toBeInTheDocument() const seatsNum = screen.getByText('5-10') expect(seatsNum).toBeInTheDocument() - label.querySelector('button').click() + button.click() await waitFor(() => { expect( screen.getByText( 'Course offering may be cancelled if number of admitted are less than minimum of places. If there are more applicants than number of places selection will be made.' ) ).toBeInTheDocument() - const criteriaText = screen.queryByText('The selection results are based on:') - expect(criteriaText).not.toBeInTheDocument() }) + const criteriaText = screen.queryByText('The selection results are based on:') + expect(criteriaText).not.toBeInTheDocument() }) }) diff --git a/public/js/app/components/__tests__/SideMenu.test.js b/public/js/app/components/__tests__/SideMenu.test.js index beb49ca7..0f1455cb 100644 --- a/public/js/app/components/__tests__/SideMenu.test.js +++ b/public/js/app/components/__tests__/SideMenu.test.js @@ -6,18 +6,13 @@ import SideMenu from '../SideMenu' import i18n from '../../../../../i18n' import '@testing-library/jest-dom' -const { getAllByRole, queryByText } = screen const [translationEN, translationSV] = i18n.messages describe('Component ', () => { - test('renders a side menu', () => { - render() - }) - test('renders a side menu for a course and with labels. English', () => { render() - const links = getAllByRole('link') + const links = screen.getAllByRole('link') expect(links.length).toBe(5) expect(links[0].href).toBe('http://localhost/student/kurser/kurser-inom-program?l=en') @@ -35,13 +30,13 @@ describe('Component ', () => { expect(links[4].href).toBe('http://localhost/kursutveckling/KIP1111/arkiv?l=en') expect(links[4].title).toBe('Archive') - expect(queryByText('About course KIP1111')).toBeInTheDocument() + expect(screen.getByText('About course KIP1111')).toBeInTheDocument() }) test('renders a side menu for a course and with labels. Swedish', () => { render() - const links = getAllByRole('link') + const links = screen.getAllByRole('link') expect(links.length).toBe(5) expect(links[0].href).toBe('http://localhost/student/kurser/kurser-inom-program') @@ -59,6 +54,6 @@ describe('Component ', () => { expect(links[4].href).toBe('http://localhost/kursutveckling/KIP1111/arkiv?l=sv') expect(links[4].title).toBe('Arkiv') - expect(queryByText('Om kursen KIP1111')).toBeInTheDocument() + expect(screen.getByText('Om kursen KIP1111')).toBeInTheDocument() }) }) diff --git a/public/js/app/components/statistics/__tests__/StatisticsDataTable.test.js b/public/js/app/components/statistics/__tests__/StatisticsDataTable.test.js index f45e658a..43f0b45f 100644 --- a/public/js/app/components/statistics/__tests__/StatisticsDataTable.test.js +++ b/public/js/app/components/statistics/__tests__/StatisticsDataTable.test.js @@ -1,7 +1,7 @@ import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { WebContextProvider } from '../../../context/WebContext' import StatisticsDataTable from '../StatisticsDataTable' @@ -93,7 +93,7 @@ describe('Component in english', () => { expect(screen.getByText('No statistics data found!')).toBeInTheDocument() }) - test('Renders a table for a statistics page for course memo', () => { + test('Renders a table for a statistics page for course memo', async () => { render() expect(screen.getByText('A31REA')).toBeInTheDocument() expect(screen.getByText('CDE, Gru 1-2-3')).toBeInTheDocument() @@ -102,13 +102,13 @@ describe('Component in english', () => { expect(screen.getByText('26 Aug 2019')).toBeInTheDocument() const csvDownloadButton = screen.getByRole('button', { name: /Download table as csv file/i }) expect(csvDownloadButton).toBeInTheDocument() - userEvent.click(csvDownloadButton) + await userEvent.click(csvDownloadButton) const excelDownloadButton = screen.getByRole('button', { name: /Download table as excel file/i }) expect(excelDownloadButton).toBeInTheDocument() - userEvent.click(excelDownloadButton) + await userEvent.click(excelDownloadButton) }) - test('Renders a table for a statistics page for course analysis', () => { + test('Renders a table for a statistics page for course analysis', async () => { render() expect(screen.getByText('A31REA')).toBeInTheDocument() expect(screen.getByText('CDE, Gru 1-2-3')).toBeInTheDocument() @@ -117,9 +117,9 @@ describe('Component in english', () => { expect(screen.getByText('14 Jan 2020')).toBeInTheDocument() const csvDownloadButton = screen.getByRole('button', { name: /Download table as csv file/i }) expect(csvDownloadButton).toBeInTheDocument() - userEvent.click(csvDownloadButton) + await userEvent.click(csvDownloadButton) const excelDownloadButton = screen.getByRole('button', { name: /Download table as excel file/i }) expect(excelDownloadButton).toBeInTheDocument() - userEvent.click(excelDownloadButton) + await userEvent.click(excelDownloadButton) }) }) diff --git a/public/js/app/hooks/statisticsUseAsync.js b/public/js/app/hooks/statisticsUseAsync.js index c9541923..1f918f38 100644 --- a/public/js/app/hooks/statisticsUseAsync.js +++ b/public/js/app/hooks/statisticsUseAsync.js @@ -41,6 +41,7 @@ function asyncReducer(state, action) { return { status: STATUS.resolved, data: action.data, error: {} } } case 'rejected': { + // eslint-disable-next-line no-console console.error(`Error: ${action.error}`) return { status: STATUS.rejected, data: null, error: { errorType: ERROR_ASYNC.rejected } } // for debug use: action.error } diff --git a/public/js/app/pages/ExperimentCoursePage.jsx b/public/js/app/pages/ExperimentCoursePage.jsx deleted file mode 100644 index c4d554f2..00000000 --- a/public/js/app/pages/ExperimentCoursePage.jsx +++ /dev/null @@ -1,172 +0,0 @@ -/* eslint-disable react/no-danger */ -import React, { useEffect } from 'react' -// import DOMPurify from 'isomorphic-dompurify' -import sanitizeHtml from 'sanitize-html' - -import { Row, Col, Alert, Breadcrumb, BreadcrumbItem } from 'reactstrap' - -import i18n from '../../../../i18n' -import { INFORM_IF_IMPORTANT_INFO_IS_MISSING, FORSKARUTB_URL, SYLLABUS_URL } from '../util/constants' -import { breadcrumbLinks, aboutCourseLink } from '../util/links' - -import RoundInformationOneCol from '../components/RoundInformationOneCol' -import CourseTitle from '../components/CourseTitle' -import CourseSectionList from '../components/CourseSectionList' -import DropdownRounds from '../components/DropdownRounds' -import DropdownSemesters from '../components/DropdownSemesters' -import InfoModal from '../components/InfoModal' -import SideMenu from '../components/SideMenu' -import { useWebContext } from '../context/WebContext' - -const aboutCourseStr = (translate, courseCode = '') => `${translate.site_name} ${courseCode}` - -const Breadcrumbs = ({ translation, language, courseCode }) => ( - - - {translation.breadCrumbLabels.university} - - - {translation.breadCrumbLabels.student} - - - {translation.breadCrumbLabels.directory} - - - {`${translation.breadCrumbLabels.aboutCourse} ${courseCode}`} - - -) - -function getCourseIntroduction(sellingText = {}, courseInfo = {}, language) { - const { course_recruitment_text: courseDefaultIntro = '

' } = courseInfo - return sellingText[language] && sellingText[language].length > 0 ? sellingText[language] : courseDefaultIntro -} - -function ExperimentCoursePage() { - const [context, setWebContext] = useWebContext() - // const context = React.useMemo(() => webContext, [webContext]) - - const { - browserConfig, - courseCode, - courseData = { - courseInfo: { course_application_info: '' }, - syllabusSemesterList: [], - }, - imageFromAdmin, - sellingText = {}, - } = context - // * * // - - const { courseInfo, language = 'sv' } = courseData - const translation = i18n.messages[language === 'en' ? 0 : 1] - const introText = getCourseIntroduction(sellingText, courseInfo, language) - const sanitizedIntroText = sanitizeHtml(introText) - let courseImage = '' - if (imageFromAdmin.length > 4) { - courseImage = imageFromAdmin - } else { - const cms = courseInfo.course_main_subject || '' - let mainSubjects = cms.split(',').map(s => s.trim()) - if (mainSubjects && mainSubjects.length > 0 && language === 'en') { - mainSubjects = mainSubjects.map(subject => i18n.messages[0].courseMainSubjects[subject]) - } - courseImage = i18n.messages[1].courseImage[mainSubjects.sort()[0]] - if (courseImage === undefined) { - courseImage = translation.courseImage.default - } - } - courseImage = `${browserConfig.imageStorageUri}${courseImage}` - - if (!courseData.syllabusList) courseData.syllabusList = [{}] - - useEffect(() => { - let isMounted = true - if (isMounted) { - const siteNameElement = document.querySelector('.block.siteName a') - if (siteNameElement) { - siteNameElement.textContent = aboutCourseStr(translation.messages, courseCode) - siteNameElement.href = aboutCourseLink(courseCode, language) - } - } - return () => (isMounted = false) - }, []) - - return ( -
- - - - - -
- {/** ************************************************************************************************************ */} - {/* INTRO */} - {/** ************************************************************************************************************ */} - {/* ---COURSE TITEL--- */} - - {/* ---INTRO TEXT--- */} -
- - - - -
-
-

What is Lorem Ipsum?

-

- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the - industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and - scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into - electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release - of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software - like Aldus PageMaker including versions of Lorem Ipsum. -

- -

Why do we use it?

-

- It is a long established fact that a reader will be distracted by the readable content of a page when - looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of - letters, as opposed to using 'Content here, content here', making it look like readable English. Many - desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a - search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved - over the years, sometimes by accident, sometimes on purpose (injected humour and the like). -

- -

Where does it come from?

-

- Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical - Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at - Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a - Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the - undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" - (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of - ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit - amet..", comes from a line in section 1.10.32. -

- -

- The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections - 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact - original form, accompanied by English versions from the 1914 translation by H. Rackham. -

-
-
-
-
- ) -} - -export default ExperimentCoursePage diff --git a/public/js/app/pages/__tests__/CoursePage.test.js b/public/js/app/pages/__tests__/CoursePage.test.js index 01e6833f..bfecb665 100644 --- a/public/js/app/pages/__tests__/CoursePage.test.js +++ b/public/js/app/pages/__tests__/CoursePage.test.js @@ -3,8 +3,7 @@ import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { faker } from '@faker-js/faker' import axios from 'axios' -import { act } from 'react-dom/test-utils' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { WebContextProvider } from '../../context/WebContext' import CoursePage from '../CoursePage' @@ -30,16 +29,8 @@ const context = { const [translate] = i18n.messages // en describe('Component ', () => { - test('renders a course page', () => { - render( - - - - ) - }) - test('renders course syllabus link correctly', () => { - const { rerender } = render( + render( @@ -399,12 +390,10 @@ describe('Component ', () => { }, } - await act(async () => - render( - - - - ) + render( + + + ) expect(screen.getByText('MF1016 Basic Electrical Engineering 9.0 credits')).toBeInTheDocument() expect(screen.getByText('Valid for')).toBeInTheDocument() diff --git a/public/js/app/pages/__tests__/CourseStatisticsPageCompilationSV.test.js b/public/js/app/pages/__tests__/CourseStatisticsPageCompilationSV.test.js index 31ada2cc..c6eaee6c 100644 --- a/public/js/app/pages/__tests__/CourseStatisticsPageCompilationSV.test.js +++ b/public/js/app/pages/__tests__/CourseStatisticsPageCompilationSV.test.js @@ -1,7 +1,7 @@ import React from 'react' import { render, screen, within } from '@testing-library/react' import '@testing-library/jest-dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import axios from 'axios' import { WebContextProvider } from '../../context/WebContext' @@ -180,13 +180,13 @@ describe('Component show compilation data in for memos', expect(axios.get).toHaveBeenCalledWith(url, paramsPeriod1) expect( screen.getByRole('heading', { - name: /sammanställning av antalet publicerade kurs\-pm/i, + name: /sammanställning av antalet publicerade kurs-pm/i, }) ).toBeInTheDocument() expect( screen.getByRole('heading', { - name: /andel kurser som har publicerade kurs\-pm/i, + name: /andel kurser som har publicerade kurs-pm/i, }) ).toBeInTheDocument() const periodsLabel = /Sommar, 1 HT, 2 HT, 3 VT, 4 VT/i diff --git a/public/js/app/pages/__tests__/CourseStatisticsPageEN.test.js b/public/js/app/pages/__tests__/CourseStatisticsPageEN.test.js index 75c56d7a..89ef2c7b 100644 --- a/public/js/app/pages/__tests__/CourseStatisticsPageEN.test.js +++ b/public/js/app/pages/__tests__/CourseStatisticsPageEN.test.js @@ -1,17 +1,13 @@ import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { WebContextProvider } from '../../context/WebContext' import CourseStatisticsPage from '../CourseStatisticsPage' -// import i18n from '../../../../../../i18n' - const language_en = 'en' const mockDate = new Date('2022-03-23 16:00') -let submittedResults - const context_en = { language: language_en, languageIndex: language_en === 'en' ? 0 : 1, @@ -20,7 +16,7 @@ const context_en = { function CourseStatisticsPageWithContext({ context }) { return ( - (submittedResults = props)} /> + {}} /> ) } diff --git a/public/js/app/pages/__tests__/CourseStatisticsPageInitFormSV.test.js b/public/js/app/pages/__tests__/CourseStatisticsPageInitFormSV.test.js index 06eda690..4fb48c47 100644 --- a/public/js/app/pages/__tests__/CourseStatisticsPageInitFormSV.test.js +++ b/public/js/app/pages/__tests__/CourseStatisticsPageInitFormSV.test.js @@ -1,7 +1,7 @@ import React from 'react' import { render, screen } from '@testing-library/react' import '@testing-library/jest-dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import { WebContextProvider } from '../../context/WebContext' diff --git a/public/js/app/pages/__tests__/CourseStatisticsPageSubmitFormSV.test.js b/public/js/app/pages/__tests__/CourseStatisticsPageSubmitFormSV.test.js index db546408..28524beb 100644 --- a/public/js/app/pages/__tests__/CourseStatisticsPageSubmitFormSV.test.js +++ b/public/js/app/pages/__tests__/CourseStatisticsPageSubmitFormSV.test.js @@ -1,7 +1,7 @@ import React from 'react' import { render, screen, within } from '@testing-library/react' import '@testing-library/jest-dom' -import userEvent from '@testing-library/user-event' +import { userEvent } from '@testing-library/user-event' import axios from 'axios' import { WebContextProvider } from '../../context/WebContext' diff --git a/public/js/app/util/constants.js b/public/js/app/util/constants.js index 106f06fa..c8056829 100644 --- a/public/js/app/util/constants.js +++ b/public/js/app/util/constants.js @@ -1,6 +1,6 @@ export const INFORM_IF_IMPORTANT_INFO_IS_MISSING = [ 'No information inserted', - 'Ingen information tillagd' + 'Ingen information tillagd', ] export const FORSKARUTB_URL = '/utbildning/forskarutbildning/kurser/org/' export const SYLLABUS_URL = '/student/kurser/kurs/kursplan/' @@ -8,5 +8,5 @@ export const COURSE_DEVELOPMENT_URL = '/kursutveckling/' export const COURSE_MEMO_URL = '/kurs-pm/' export const SIDE_MENU_LINK_URL = { en: '/student/kurser/kurser-inom-program?l=en', - sv: '/student/kurser/kurser-inom-program' + sv: '/student/kurser/kurser-inom-program', } diff --git a/public/js/app/util/links.js b/public/js/app/util/links.js index 4ca8ad4f..5f8868d3 100644 --- a/public/js/app/util/links.js +++ b/public/js/app/util/links.js @@ -3,8 +3,8 @@ const breadcrumbLinks = { student: { en: '/en/student', sv: '/student' }, directory: { en: '/student/kurser/kurser-inom-program?l=en', - sv: '/student/kurser/kurser-inom-program' - } + sv: '/student/kurser/kurser-inom-program', + }, } function aboutCourseLink(courseCode, language) { @@ -14,5 +14,5 @@ function aboutCourseLink(courseCode, language) { module.exports = { breadcrumbLinks, - aboutCourseLink + aboutCourseLink, } diff --git a/public/js/app/util/pathUtil.js b/public/js/app/util/pathUtil.js index 8a2d7a6a..81560bbd 100644 --- a/public/js/app/util/pathUtil.js +++ b/public/js/app/util/pathUtil.js @@ -1,8 +1,8 @@ -function _addParamToPath (path, param, value) { - var paramToReplace = ':' + param +function _addParamToPath(path, param, value) { + const paramToReplace = ':' + param return path.replace(paramToReplace, value) } module.exports = { - addParamToPath: _addParamToPath + addParamToPath: _addParamToPath, } diff --git a/server/api.js b/server/api.js index bdd7c719..6973463c 100644 --- a/server/api.js +++ b/server/api.js @@ -1,9 +1,9 @@ 'use strict' const log = require('@kth/log') -const config = require('./configuration').server const redis = require('kth-node-redis') const connections = require('@kth/api-call').Connections +const config = require('./configuration').server const opts = { log, @@ -11,7 +11,7 @@ const opts = { cache: config.cache, timeout: 5000, retryOnESOCKETTIMEDOUT: true, - checkAPIs: true // performs api-key checks against the apis, if a "required" check fails, the app will exit. Required apis are specified in the config + checkAPIs: true, // performs api-key checks against the apis, if a "required" check fails, the app will exit. Required apis are specified in the config } module.exports = connections.setup(config.nodeApi, config.apiKey, opts) diff --git a/server/apiCalls/memoApi.js b/server/apiCalls/memoApi.js index 8bb1f8c5..d610326f 100644 --- a/server/apiCalls/memoApi.js +++ b/server/apiCalls/memoApi.js @@ -18,6 +18,7 @@ async function getPrioritizedCourseMemos(courseCode) { courseCode, { err } ) + return undefined } } diff --git a/server/apiCalls/transformers/offerings.js b/server/apiCalls/transformers/offerings.js index ec48e2ab..5280214d 100644 --- a/server/apiCalls/transformers/offerings.js +++ b/server/apiCalls/transformers/offerings.js @@ -1,6 +1,5 @@ const { labelSeason, seasonConstants } = require('../../../domain/statistics/seasons') const { isCorrectSchool, SCHOOL_MAP } = require('./schools') -const { formatTimeToLocaleDateSV } = require('./dates') /** * Creates string of programs in list. @@ -66,11 +65,14 @@ function _sortOfferedSemesters(offeredSemesters) { */ function _findCourseStartEndDates(courseOfferedSemesters) { const offeredSemesters = Array.isArray(courseOfferedSemesters) ? courseOfferedSemesters : [] - const { length, 0: firstOffering = {}, [length - 1]: lastOffering = {} } = _sortOfferedSemesters(offeredSemesters) + const sortedArray = _sortOfferedSemesters(offeredSemesters) - const { start_date: courseStartDate = '' } = firstOffering + const firstOffering = sortedArray.at(0) ?? {} + const lastOffering = sortedArray.at(-1) ?? {} + const { start_date: courseStartDate = '' } = firstOffering const { semester: lastSemester = '', end_date: courseEndDate = '', end_week: courseEndWeek } = lastOffering + return { endDate: courseEndDate, endWeek: courseEndWeek, lastSemester, startDate: courseStartDate } } diff --git a/server/apiCalls/ugRestApi.js b/server/apiCalls/ugRestApi.js index 6d104aad..39135696 100644 --- a/server/apiCalls/ugRestApi.js +++ b/server/apiCalls/ugRestApi.js @@ -20,7 +20,7 @@ const _groupNames = (courseCode, semester, ladokRoundIds) => ({ const _removeDuplicates = personListWithDublicates => personListWithDublicates .map(person => JSON.stringify(person)) - .filter((person, index, self) => self.indexOf(person) === index) + .filter((person, index, array) => array.indexOf(person) === index) .map(personStr => JSON.parse(personStr)) const _createPersonHtml = (personList = []) => { diff --git a/server/configuration.js b/server/configuration.js index 3bee8652..415ec405 100644 --- a/server/configuration.js +++ b/server/configuration.js @@ -2,17 +2,11 @@ const { generateConfig } = require('kth-node-configuration') // These settings are used by the server -const serverConfig = generateConfig([ - require('../config/commonSettings'), - require('../config/serverSettings') -]) +const serverConfig = generateConfig([require('../config/commonSettings'), require('../config/serverSettings')]) module.exports.server = serverConfig // These settings are passed to the browser -const browserConfig = generateConfig([ - require('../config/commonSettings'), - require('../config/browserSettings') -]) +const browserConfig = generateConfig([require('../config/commonSettings'), require('../config/browserSettings')]) module.exports.browser = browserConfig diff --git a/server/controllers/__tests__/courseCtrl.test.js b/server/controllers/__tests__/courseCtrl.test.js index e6eadfd5..d91769dc 100644 --- a/server/controllers/__tests__/courseCtrl.test.js +++ b/server/controllers/__tests__/courseCtrl.test.js @@ -58,7 +58,7 @@ jest.mock('../../apiCalls/koppsCourseData', () => ({ getKoppsCourseData: () => ( jest.mock('../../apiCalls/ugRestApi', () => ({ getCourseEmployees: jest.fn(() => ({ examiners: '

Examiner 1

' })), })) -let testResponse, errorResponse +let testResponse jest.mock('../../utils/serverSideRendering', () => ({ getServerSideFunctions: jest.fn(() => ({ @@ -76,7 +76,6 @@ const courseCtrl = require('../courseCtrl') let response beforeEach(() => { testResponse = {} - errorResponse = null response = { render: jest.fn().mockImplementation((name, values) => (testResponse = values)) } }) @@ -96,10 +95,9 @@ describe('Discontinued course to test', () => { }, language: 'sv', }) - const next = jest.fn().mockImplementation(error => (errorResponse = error)) + const next = jest.fn() await courseCtrl.getIndex(req, response, next) - if (errorResponse) console.error('errorResponse', errorResponse) expect(response.render).toHaveBeenCalled() expect(testResponse.title).toBe(mockedDiscontinuedCourse.course.courseCode) diff --git a/server/controllers/__tests__/systemCtrl.test.js b/server/controllers/__tests__/systemCtrl.test.js index 78160c13..0d695d4a 100644 --- a/server/controllers/__tests__/systemCtrl.test.js +++ b/server/controllers/__tests__/systemCtrl.test.js @@ -3,18 +3,17 @@ jest.mock('../../api', () => {}) const systemCtrl = require('../systemCtrl') +const next = jest.fn() + describe('Not found', () => { - test('Gets correct error code', (done) => { + test('Gets correct error code', () => { const req = { originalUrl: 'http://localhost' } - const next = (err) => { - expect(err).toBeInstanceOf(Error) - expect(err.status).toBeDefined() - expect(err.status).toEqual(404) - expect(err.message).toMatch('http://localhost') - done() - } - systemCtrl.notFound(req, {}, next) + + const expectedError = new Error('Not Found: http://localhost') + expectedError.status = 404 + + expect(next).toHaveBeenCalledWith(expectedError) }) -}) \ No newline at end of file +}) diff --git a/server/controllers/courseCtrl.js b/server/controllers/courseCtrl.js index 802c91e8..966c04c1 100644 --- a/server/controllers/courseCtrl.js +++ b/server/controllers/courseCtrl.js @@ -39,13 +39,13 @@ function parceContactName(infoContactName, language) { return contact } -async function getCourseEmployees(req, res, next) { +async function getCourseEmployees(req, res) { const apiMemoData = req.body const courseEmployees = await ugRestApi.getCourseEmployees(apiMemoData) res.send(courseEmployees) } -async function getKoppsCourseData(req, res, next) { +async function getKoppsCourseData(req, res) { const { courseCode } = req.params const language = req.params.language || 'sv' log.debug('Get Kopps course data for: ', courseCode, language) @@ -59,14 +59,14 @@ async function getKoppsCourseData(req, res, next) { log.debug('NOK response from Kopps API for: ', courseCode, language) res.status(statusCode) res.statusCode = statusCode - res.send(courseCode) + return res.send(courseCode) } catch (err) { return err } } function _parseCourseDefaultInformation(courseDetails, language) { - const { course, formattedGradeScales, mainSubjects, socialCoursePageUrl } = courseDetails + const { course, formattedGradeScales, mainSubjects } = courseDetails return { course_application_info: parseOrSetEmpty(course.applicationInfo, language, true), course_code: parseOrSetEmpty(course.courseCode), diff --git a/server/controllers/noCourseCtrl.js b/server/controllers/noCourseCtrl.js index ee56b87e..4913d249 100644 --- a/server/controllers/noCourseCtrl.js +++ b/server/controllers/noCourseCtrl.js @@ -2,7 +2,7 @@ const languageUtils = require('@kth/kth-node-web-common/lib/language') -function getIndex(req, res, next) { +function getIndex(req, res) { const lang = languageUtils.getLanguage(res) || 'sv' const html = lang === 'en' diff --git a/server/controllers/statisticsCtrl.js b/server/controllers/statisticsCtrl.js index 49c6b0ef..6266436e 100644 --- a/server/controllers/statisticsCtrl.js +++ b/server/controllers/statisticsCtrl.js @@ -133,7 +133,7 @@ async function fetchMemoStatistics(req, res, next) { }) } catch (error) { log.debug(` Exception`, { error }) - next(error) + return next(error) } } /** @@ -196,7 +196,7 @@ async function fetchAnalysisStatistics(req, res, next) { }) } catch (error) { log.debug(` Exception`, { error }) - next(error) + return next(error) } } diff --git a/server/controllers/systemCtrl.js b/server/controllers/systemCtrl.js index 438e9129..e64e7b40 100644 --- a/server/controllers/systemCtrl.js +++ b/server/controllers/systemCtrl.js @@ -61,7 +61,7 @@ function _getFriendlyErrorMessage(lang, statusCode) { } // this function must keep this signature for it to work properly -function _final(err, req, res, next) { +function _final(err, req, res) { const debugStatusCodes = [403, 404] let statusCode diff --git a/server/middleware/index.js b/server/middleware/index.js index ced4a574..552cb00c 100644 --- a/server/middleware/index.js +++ b/server/middleware/index.js @@ -1,5 +1,5 @@ 'use strict' module.exports = { - SyllabusPdf: require('./syllabusPdfProxy') + SyllabusPdf: require('./syllabusPdfProxy'), } diff --git a/server/server.js b/server/server.js index 52934214..ca65fa79 100644 --- a/server/server.js +++ b/server/server.js @@ -1,13 +1,14 @@ +/* eslint-disable import/order */ const server = require('@kth/server') // Now read the server config etc. const config = require('./configuration').server require('./api') const AppRouter = require('kth-node-express-routing').PageRouter -const getPaths = require('kth-node-express-routing').getPaths +const { getPaths } = require('kth-node-express-routing') if (config.appInsights && config.appInsights.instrumentationKey) { - let appInsights = require('applicationinsights') + const appInsights = require('applicationinsights') appInsights .setup(config.appInsights.instrumentationKey) .setAutoDependencyCorrelation(true) @@ -31,7 +32,7 @@ module.exports.getPaths = () => getPaths() const log = require('@kth/log') const packageFile = require('../package.json') -let logConfiguration = { +const logConfiguration = { name: packageFile.name, app: packageFile.name, env: process.env.NODE_ENV, @@ -70,6 +71,7 @@ require('./views/helpers') * ****************************** */ const accessLog = require('kth-node-access-log') + server.use(accessLog(config.logging.accessLog)) /* **************************** @@ -80,14 +82,6 @@ const browserConfig = require('./configuration').browser const browserConfigHandler = require('kth-node-configuration').getHandler(browserConfig, getPaths()) const express = require('express') -// helper -function setCustomCacheControl(res, path) { - if (express.static.mime.lookup(path) === 'text/html') { - // Custom Cache-Control for HTML files - res.setHeader('Cache-Control', 'no-cache') - } -} - // Files/statics routes-- // Map components HTML files as static content, but set custom cache control header, currently no-cache to force If-modified-since/Etag check. // server.use( @@ -105,8 +99,8 @@ server.use(config.proxyPrefixPath.uri + '/static/kth-style', express.static('./n // Map static content like images, css and js. server.use(config.proxyPrefixPath.uri + '/static', express.static('./dist')) // Return 404 if static file isn't found so we don't go through the rest of the pipeline -server.use(config.proxyPrefixPath.uri + '/static', function (req, res, next) { - var error = new Error('File not found: ' + req.originalUrl) +server.use(config.proxyPrefixPath.uri + '/static', (req, res, next) => { + const error = new Error('File not found: ' + req.originalUrl) error.statusCode = 404 next(error) }) @@ -121,6 +115,7 @@ server.set('case sensitive routing', true) */ const bodyParser = require('body-parser') const cookieParser = require('cookie-parser') + server.use(bodyParser.json()) server.use(bodyParser.urlencoded({ extended: true })) server.use(cookieParser()) @@ -130,6 +125,7 @@ server.use(cookieParser()) * *********************** */ const session = require('@kth/session') + const options = config.session options.sessionOptions.secret = config.sessionSecret server.use(session(options)) @@ -139,6 +135,7 @@ server.use(session(options)) * ************************ */ const { languageHandler } = require('@kth/kth-node-web-common/lib/language') + server.use(config.proxyPrefixPath.uri, languageHandler) /* ****************************** diff --git a/server/util/__tests__/courseDepartmentUtils.test.js b/server/util/__tests__/courseDepartmentUtils.test.js index 7ead5d17..91a45e83 100644 --- a/server/util/__tests__/courseDepartmentUtils.test.js +++ b/server/util/__tests__/courseDepartmentUtils.test.js @@ -4,6 +4,7 @@ const { INFORM_IF_IMPORTANT_INFO_IS_MISSING } = require('../constants') function htmlStringToElement(html) { const template = document.createElement('template') template.innerHTML = html + // eslint-disable-next-line prefer-destructuring const htmlElement = template.content.children[0] return htmlElement } @@ -28,9 +29,9 @@ describe('course department link utils', () => { test.each([undefined, { name: undefined }])('returns fallback text if department is %p', department => { const resultSv = buildCourseDepartmentLink(department, 'sv') - expect(resultSv).toBe(INFORM_IF_IMPORTANT_INFO_IS_MISSING['sv']) + expect(resultSv).toBe(INFORM_IF_IMPORTANT_INFO_IS_MISSING.sv) const resultEn = buildCourseDepartmentLink(department, 'en') - expect(resultEn).toBe(INFORM_IF_IMPORTANT_INFO_IS_MISSING['en']) + expect(resultEn).toBe(INFORM_IF_IMPORTANT_INFO_IS_MISSING.en) }) }) diff --git a/server/views/helpers/index.js b/server/views/helpers/index.js index a8c089c5..346ab4ae 100644 --- a/server/views/helpers/index.js +++ b/server/views/helpers/index.js @@ -24,7 +24,7 @@ try { */ registerHeaderContentHelper({ proxyPrefixPath: config.proxyPrefixPath.uri, - version + version, }) /**