From 026b6e5cf1dfb363ec59b3f16ddab0d2296f962e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 05:24:23 +0000 Subject: [PATCH 01/26] build(deps): bump passport from 0.3.2 to 0.6.0 Bumps [passport](https://github.com/jaredhanson/passport) from 0.3.2 to 0.6.0. - [Changelog](https://github.com/jaredhanson/passport/blob/master/CHANGELOG.md) - [Commits](https://github.com/jaredhanson/passport/compare/v0.3.2...v0.6.0) --- updated-dependencies: - dependency-name: passport dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 15 ++++++++++----- package.json | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fa941fe..6c00c6ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", "morgan": "^1.10.0", - "passport": "^0.4.1", + "passport": "^0.6.0", "passport-local": "^1.0.0", "serve-favicon": "^2.5.0" }, @@ -4731,15 +4731,20 @@ } }, "node_modules/passport": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", - "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", + "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", "dependencies": { "passport-strategy": "1.x.x", - "pause": "0.0.1" + "pause": "0.0.1", + "utils-merge": "^1.0.1" }, "engines": { "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" } }, "node_modules/passport-local": { diff --git a/package.json b/package.json index 1b7aee83..d7f59ccd 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", "morgan": "^1.10.0", - "passport": "^0.4.1", + "passport": "^0.6.0", "passport-local": "^1.0.0", "serve-favicon": "^2.5.0" }, From 5196596b7aa66b231be37d44c88d01e4e797579f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 05:24:42 +0000 Subject: [PATCH 02/26] build(deps): bump validator and express-validator Bumps [validator](https://github.com/validatorjs/validator.js) to 13.11.0 and updates ancestor dependency [express-validator](https://github.com/express-validator/express-validator). These dependencies need to be updated together. Updates `validator` from 5.7.0 to 13.11.0 - [Release notes](https://github.com/validatorjs/validator.js/releases) - [Changelog](https://github.com/validatorjs/validator.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/validatorjs/validator.js/compare/5.7.0...13.11.0) Updates `express-validator` from 2.21.0 to 7.0.1 - [Release notes](https://github.com/express-validator/express-validator/releases) - [Commits](https://github.com/express-validator/express-validator/compare/v2.21.0...v7.0.1) --- updated-dependencies: - dependency-name: validator dependency-type: indirect - dependency-name: express-validator dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package-lock.json | 100 ++++------------------------------------------ package.json | 2 +- 2 files changed, 8 insertions(+), 94 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fa941fe..e6a02826 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "ejs": "~3.1.7", "express": "^4.17.1", "express-session": "^1.17.1", - "express-validator": "^4.0.0", + "express-validator": "^7.0.1", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", @@ -1139,15 +1139,6 @@ "@babel/types": "^7.20.7" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, "node_modules/@types/bson": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", @@ -1156,35 +1147,6 @@ "@types/node": "*" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.0.39", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", - "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1194,11 +1156,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1223,11 +1180,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, "node_modules/@types/mongodb": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", @@ -1245,35 +1197,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/qs": { - "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2601,24 +2524,15 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" }, "node_modules/express-validator": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-4.3.0.tgz", - "integrity": "sha512-EYU+JJ2EoLpcw+GKwbB1K8UGb/w1A70Wf3gD/zE9QScQxeSt8qad93lxGtsLwZFoiYM0EByVoSzHJnskp+eVHQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", + "integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==", "dependencies": { - "@types/express": "~4.0.34", - "lodash": "^4.16.0", - "validator": "~8.2.0" + "lodash": "^4.17.21", + "validator": "^13.9.0" }, "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/express-validator/node_modules/validator": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", - "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", - "engines": { - "node": ">= 0.10" + "node": ">= 8.0.0" } }, "node_modules/express/node_modules/body-parser": { diff --git a/package.json b/package.json index 1b7aee83..ed5bd61d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "ejs": "~3.1.7", "express": "^4.17.1", "express-session": "^1.17.1", - "express-validator": "^4.0.0", + "express-validator": "^7.0.1", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", From 792e549f89307bd29115e864ac45d94dd3d7b119 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 07:50:02 +0500 Subject: [PATCH 03/26] chore(automated-tests): Add CI workflow for HRMS and specify Node.js engine version --- .github/workflows/hrms.yml | 32 ++++++++++++++++++++++++++++++++ package-lock.json | 3 +++ package.json | 4 ++++ 3 files changed, 39 insertions(+) create mode 100644 .github/workflows/hrms.yml diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml new file mode 100644 index 00000000..9969931e --- /dev/null +++ b/.github/workflows/hrms.yml @@ -0,0 +1,32 @@ +name: HRMS CI + +on: + push: + branches: + - main # Run tests on push to the main branch + pull_request: + branches: + - main # Run tests on pull requests to the main branch + +jobs: + test: + runs-on: ubuntu-latest + + steps: + # Step 1: Check out the repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Step 2: Set up Node.js + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 # Use the Node.js version your project requires + + # Step 3: Install dependencies + - name: Install dependencies + run: npm install + + # Step 4: Run tests + - name: Run tests + run: npm test \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4fa941fe..6ccf9dba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,9 @@ "cheerio": "^1.0.0-rc.12", "jest": "^29.7.0", "supertest": "^6.3.4" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@ampproject/remapping": { diff --git a/package.json b/package.json index 1b7aee83..ac83b840 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,12 @@ "!/public/**", "!/coverage/**", "!/test/**", + "!/seed/**", "!/node_modules/**" ], "coverageProvider": "v8" + }, + "engines": { + "node": ">=18.0.0" } } From d5526ae44a784d7e97b4d0517878e20072687352 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 07:51:53 +0500 Subject: [PATCH 04/26] chore(automated-tests): Add CI workflow for HRMS and specify Node.js engine version --- .github/workflows/hrms.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml index 9969931e..5c310e46 100644 --- a/.github/workflows/hrms.yml +++ b/.github/workflows/hrms.yml @@ -3,10 +3,10 @@ name: HRMS CI on: push: branches: - - main # Run tests on push to the main branch + - master # Run tests on push to the main branch pull_request: branches: - - main # Run tests on pull requests to the main branch + - master # Run tests on pull requests to the main branch jobs: test: From 239cf83a5257f327709ba1c251ba4af4bed06cce Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 08:07:40 +0500 Subject: [PATCH 05/26] chore(ci): Add MongoDB service to CI workflow for testing --- .github/workflows/hrms.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml index 5c310e46..d510bac9 100644 --- a/.github/workflows/hrms.yml +++ b/.github/workflows/hrms.yml @@ -12,6 +12,17 @@ jobs: test: runs-on: ubuntu-latest + services: + mongo: + image: mongo:5.0 # Use the MongoDB version you need + ports: + - 27017:27017 + options: >- + --health-cmd "mongo --eval 'db.runCommand({ ping: 1 })'" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: # Step 1: Check out the repository - name: Checkout repository From 3ca1ae152d2ff11680234b9ef2814383ce21f0f5 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 08:18:54 +0500 Subject: [PATCH 06/26] chore(tests): Enhance test setup with error handling and logging --- test/setupTests.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/test/setupTests.js b/test/setupTests.js index c56b60b7..c8deb3b8 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -9,18 +9,27 @@ global.pm_agent = null; global.csrfToken = null; module.exports = async () => { - await db.connect().then(() => { + try { + console.log("Connecting to the database..."); + await db.connect(); + console.log("Database connected. Seeding data..."); execSync("NODE_ENV=test node seed/user-seeder.js"); + console.log("Data seeded. Initializing agents..."); + const app = require("../app"); admin_agent = request.agent(app); employee_agent = request.agent(app); pm_agent = request.agent(app); - csrfToken = null; - }); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); + await loginAs(admin_agent, "admin@admin.com", "admin123"); + await loginAs(employee_agent, "employee1@employee.com", "123456"); + await loginAs(pm_agent, "pm@pm.com", "pm1234"); + + console.log("Test setup completed successfully."); + } catch (error) { + console.error("Error during test setup:", error); + process.exit(1); + } }; async function loginAs(agent, email, password) { From 413506f6e7c675dfb2330376b1c50a774042df7d Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 08:34:50 +0500 Subject: [PATCH 07/26] chore(ci): Add test database URL to HRMS CI workflow --- .github/workflows/hrms.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml index d510bac9..a1ac673e 100644 --- a/.github/workflows/hrms.yml +++ b/.github/workflows/hrms.yml @@ -8,6 +8,9 @@ on: branches: - master # Run tests on pull requests to the main branch +env: + DB_URL_TEST: mongodb://localhost:27017/test-db + jobs: test: runs-on: ubuntu-latest @@ -22,7 +25,7 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 - + steps: # Step 1: Check out the repository - name: Checkout repository From 24bbeb175afb6abf5cd40ba6b82dee08844d7f5a Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 08:40:27 +0500 Subject: [PATCH 08/26] chore(tests): Refactor test setup to improve database connection and seeding process --- test/setupTests.js | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/test/setupTests.js b/test/setupTests.js index c8deb3b8..a6ec042f 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -9,27 +9,21 @@ global.pm_agent = null; global.csrfToken = null; module.exports = async () => { - try { - console.log("Connecting to the database..."); - await db.connect(); - console.log("Database connected. Seeding data..."); + await db.connect().then(() => { + console.log("Database connected"); execSync("NODE_ENV=test node seed/user-seeder.js"); - console.log("Data seeded. Initializing agents..."); - + execSync("NODE_ENV=test node seed/user-seeder.js"); + console.log("Database seeded"); const app = require("../app"); admin_agent = request.agent(app); employee_agent = request.agent(app); pm_agent = request.agent(app); + csrfToken = null; + }); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); - - console.log("Test setup completed successfully."); - } catch (error) { - console.error("Error during test setup:", error); - process.exit(1); - } + await loginAs(admin_agent, "admin@admin.com", "admin123"); + await loginAs(employee_agent, "employee1@employee.com", "123456"); + await loginAs(pm_agent, "pm@pm.com", "pm1234"); }; async function loginAs(agent, email, password) { From 41e3e606f4e9cd6497a91fb82b694d2e74071448 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 08:44:11 +0500 Subject: [PATCH 09/26] chore(tests): Update user seeder execution to display command output in console --- test/setupTests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/setupTests.js b/test/setupTests.js index a6ec042f..c8e41518 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -11,8 +11,8 @@ global.csrfToken = null; module.exports = async () => { await db.connect().then(() => { console.log("Database connected"); - execSync("NODE_ENV=test node seed/user-seeder.js"); - execSync("NODE_ENV=test node seed/user-seeder.js"); + //{ stdio: "inherit" } will show the output of the command in the console + execSync("NODE_ENV=test node seed/user-seeder.js", { stdio: "inherit" }); console.log("Database seeded"); const app = require("../app"); admin_agent = request.agent(app); From c47718daa0be3bef4d7eb1411ba19d9814922f2e Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 09:03:31 +0500 Subject: [PATCH 10/26] chore(seeding): Refactor user seeder to improve error handling and logging --- seed/user-seeder.js | 84 ++++++++++++++++++++++++------------------- test/setupTests.js | 34 ++++++++++-------- test/teardownTests.js | 3 ++ 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/seed/user-seeder.js b/seed/user-seeder.js index ffb77325..0f434797 100644 --- a/seed/user-seeder.js +++ b/seed/user-seeder.js @@ -1,31 +1,14 @@ /** * This script seeds the User collection in the MongoDB database. - * - * It first connects to the MongoDB database using Mongoose. - * Then, it creates an array of new User instances with predefined data. - * Each User instance represents a document that will be inserted into the User collection. - * - * Each User document has the following fields: - * - type: The role of the user (e.g., "project_manager", "accounts_manager", "employee"). - * - email: The email address of the user. - * - password: The hashed password of the user. The password is hashed using bcrypt. - * - name: The name of the user. - * - dateOfBirth: The date of birth of the user. - * - contactNumber: The contact number of the user. - * + * It can be run as a standalone script or imported as a module. */ -let User = require("../models/user"); -let bcrypt = require("bcrypt-nodejs"); -let mongoose = require("mongoose"); - +const User = require("../models/user"); +const bcrypt = require("bcrypt-nodejs"); +const mongoose = require("mongoose"); const db = require("../db"); -db.connect() - .then(() => console.log("Database connected")) - .catch((err) => console.error("Database connection error", err)); - -let users = [ +const users = [ new User({ type: "project_manager", email: "pm@pm.com", @@ -68,20 +51,49 @@ let users = [ }), ]; -(async function () { - for (let user of users) { - let existingUser = await User.findOne({ email: user.email }); - if (existingUser) { - console.log(`User with email ${user.email} already exists.`); - break; - } else { - await user.save(); +/** + * Seeds the database with predefined users. + */ +const seedUsers = async (closeConn = true) => { + try { + console.log("Connecting to the database..."); + await db.connect(); + console.log("Database connected."); + + for (let user of users) { + const existingUser = await User.findOne({ email: user.email }); + if (existingUser) { + console.log(`User with email ${user.email} already exists.`); + } else { + await user.save(); + console.log(`User with email ${user.email} added.`); + } + } + + console.log("All users seeded successfully."); + } catch (error) { + console.error("Error seeding users:", error); + throw error; + } finally { + if (closeConn) { + await mongoose.disconnect(); + console.log("Database connection closed."); } } - exit(); -})(); +}; + +// Export the function for use in other scripts +module.exports = seedUsers; -function exit() { - mongoose.disconnect(); - console.log("Users Added...") -} +// If the script is run directly, execute the seeding process +if (require.main === module) { + seedUsers() + .then(() => { + console.log("Seeding completed successfully."); + process.exit(0); // Exit with success + }) + .catch((error) => { + console.error("Seeding failed:", error); + process.exit(1); // Exit with failure + }); +} \ No newline at end of file diff --git a/test/setupTests.js b/test/setupTests.js index c8e41518..8520d677 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -1,7 +1,7 @@ const db = require("../db"); const request = require("supertest"); const cheerio = require("cheerio"); -const execSync = require("child_process").execSync; +const seedUsers = require("../seed/user-seeder"); global.admin_agent = null; global.employee_agent = null; @@ -9,21 +9,27 @@ global.pm_agent = null; global.csrfToken = null; module.exports = async () => { - await db.connect().then(() => { - console.log("Database connected"); - //{ stdio: "inherit" } will show the output of the command in the console - execSync("NODE_ENV=test node seed/user-seeder.js", { stdio: "inherit" }); - console.log("Database seeded"); + try { + // seedUsers will create connection with db and will not close it + await seedUsers(closeConn = false); + const app = require("../app"); - admin_agent = request.agent(app); - employee_agent = request.agent(app); - pm_agent = request.agent(app); - csrfToken = null; - }); + global.admin_agent = request.agent(app); + global.employee_agent = request.agent(app); + global.pm_agent = request.agent(app); + + console.log("Logging in as admin..."); + await loginAs(admin_agent, "admin@admin.com", "admin123"); + console.log("Logging in as employee..."); + await loginAs(employee_agent, "employee1@employee.com", "123456"); + console.log("Logging in as project manager..."); + await loginAs(pm_agent, "pm@pm.com", "pm1234"); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); + console.log("Test setup completed successfully."); + } catch (error) { + console.error("Error during test setup:", error); + process.exit(1); // Exit with failure + } }; async function loginAs(agent, email, password) { diff --git a/test/teardownTests.js b/test/teardownTests.js index 46beb5dc..8a296db1 100644 --- a/test/teardownTests.js +++ b/test/teardownTests.js @@ -2,11 +2,14 @@ const app = require("../app"); const db = require("../db"); module.exports = async () => { + console.log("Tearing down tests..."); + console.log("Logging out all users..."); await admin_agent.get("/logout"); await employee_agent.get("/logout"); await pm_agent.get("/logout"); await db.close(); + console.log("Database connection closed."); // If your app doesn't close the server automatically, you can do it manually if (app && app.close) { app.close(); From a9e1b62f47359d01fb03977fe76bc82025d9f1dc Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 09:07:35 +0500 Subject: [PATCH 11/26] chore(tests): Update test setup logging for clarity and consistency --- test/setupTests.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/setupTests.js b/test/setupTests.js index 8520d677..7020d716 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -18,11 +18,9 @@ module.exports = async () => { global.employee_agent = request.agent(app); global.pm_agent = request.agent(app); - console.log("Logging in as admin..."); + console.log("Logging users."); await loginAs(admin_agent, "admin@admin.com", "admin123"); - console.log("Logging in as employee..."); await loginAs(employee_agent, "employee1@employee.com", "123456"); - console.log("Logging in as project manager..."); await loginAs(pm_agent, "pm@pm.com", "pm1234"); console.log("Test setup completed successfully."); From 65828a74f04b9a30f592fc8d3782035e64ec9999 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 09:08:57 +0500 Subject: [PATCH 12/26] chore(tests): Update Jest configuration to use setupFilesAfterEnv for test setup --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ac83b840..ccbb3b80 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "supertest": "^6.3.4" }, "jest": { - "globalSetup": "./test/setupTests.js", + "setupFilesAfterEnv": ["./test/setupTests.js"], "globalTeardown": "./test/teardownTests.js", "collectCoverage": true, "collectCoverageFrom": [ From 9c03fdb6b6422fbf31b759c75954a64a3cbbca19 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 09:19:06 +0500 Subject: [PATCH 13/26] chore(tests): Update test setup to use global agents and improve logging --- package.json | 2 +- test/routes/admin.test.js | 6 +++--- test/setupTests.js | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index ccbb3b80..ac83b840 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "supertest": "^6.3.4" }, "jest": { - "setupFilesAfterEnv": ["./test/setupTests.js"], + "globalSetup": "./test/setupTests.js", "globalTeardown": "./test/teardownTests.js", "collectCoverage": true, "collectCoverageFrom": [ diff --git a/test/routes/admin.test.js b/test/routes/admin.test.js index b3f51abe..881ead4c 100644 --- a/test/routes/admin.test.js +++ b/test/routes/admin.test.js @@ -5,7 +5,7 @@ const User = require("../../models/user"); describe("Admin Routes", () => { test("GET / should render admin home page", async () => { - const res = await admin_agent.get("/admin/"); + const res = await global.admin_agent.get("/admin/"); expect(res.statusCode).toBe(200); @@ -20,7 +20,7 @@ describe("Admin Routes", () => { }); test("GET /admin/view-all-employees should return all employees", async () => { - const res = await admin_agent.get("/admin/view-all-employees"); + const res = await global.admin_agent.get("/admin/view-all-employees"); expect(res.statusCode).toBe(200); const $ = cheerio.load(res.text); @@ -42,7 +42,7 @@ describe("Admin Routes", () => { db.close(); }); - const res = await admin_agent.get(`/admin/employee-profile/${employeeId}`); + const res = await global.admin_agent.get(`/admin/employee-profile/${employeeId}`); expect(res.statusCode).toBe(200); const $ = cheerio.load(res.text); diff --git a/test/setupTests.js b/test/setupTests.js index 7020d716..962ce62e 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -18,10 +18,10 @@ module.exports = async () => { global.employee_agent = request.agent(app); global.pm_agent = request.agent(app); - console.log("Logging users."); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); + console.log("Logging in users..."); + await loginAs(global.admin_agent, "admin@admin.com", "admin123"); + await loginAs(global.employee_agent, "employee1@employee.com", "123456"); + await loginAs(global.pm_agent, "pm@pm.com", "pm1234"); console.log("Test setup completed successfully."); } catch (error) { From b9444f327b525ca5955d6beb1218bc7077384465 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 10:35:08 +0500 Subject: [PATCH 14/26] chore(tests): Remove unused csrfToken and simplify agent login references in test setup --- test/setupTests.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/setupTests.js b/test/setupTests.js index 962ce62e..463110d4 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -6,7 +6,6 @@ const seedUsers = require("../seed/user-seeder"); global.admin_agent = null; global.employee_agent = null; global.pm_agent = null; -global.csrfToken = null; module.exports = async () => { try { @@ -19,9 +18,9 @@ module.exports = async () => { global.pm_agent = request.agent(app); console.log("Logging in users..."); - await loginAs(global.admin_agent, "admin@admin.com", "admin123"); - await loginAs(global.employee_agent, "employee1@employee.com", "123456"); - await loginAs(global.pm_agent, "pm@pm.com", "pm1234"); + await loginAs(admin_agent, "admin@admin.com", "admin123"); + await loginAs(employee_agent, "employee1@employee.com", "123456"); + await loginAs(pm_agent, "pm@pm.com", "pm1234"); console.log("Test setup completed successfully."); } catch (error) { From 47cea834684d6ccb3d39d4a9c40dba9d9119d8fb Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 10:39:42 +0500 Subject: [PATCH 15/26] chore(tests): Add console log for admin agent in test setup for debugging --- test/setupTests.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/setupTests.js b/test/setupTests.js index 463110d4..491c2b95 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -17,6 +17,8 @@ module.exports = async () => { global.employee_agent = request.agent(app); global.pm_agent = request.agent(app); + console.log(global.admin_agent) + console.log("Logging in users..."); await loginAs(admin_agent, "admin@admin.com", "admin123"); await loginAs(employee_agent, "employee1@employee.com", "123456"); From 97ac24f99916a23dd2c1840daa7445e51eed76ca Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 11:56:55 +0500 Subject: [PATCH 16/26] chore(tests): Refactor user seeder and test setup for improved clarity and efficiency --- db.js | 2 - seed/user-seeder.js | 82 +++++++++++++++--------------------- test/routes/admin.test.js | 8 ++-- test/routes/employee.test.js | 2 +- test/routes/manager.test.js | 4 +- test/setupTests.js | 34 ++++++--------- test/teardownTests.js | 5 +-- 7 files changed, 56 insertions(+), 81 deletions(-) diff --git a/db.js b/db.js index e18beb2c..ca651ab0 100644 --- a/db.js +++ b/db.js @@ -3,8 +3,6 @@ require("dotenv").config(); mongoose.Promise = global.Promise; -mongoose.Promise = global.Promise; - const connect = (opts = {}) => { let url; switch (process.env.NODE_ENV) { diff --git a/seed/user-seeder.js b/seed/user-seeder.js index 0f434797..8aecfcc0 100644 --- a/seed/user-seeder.js +++ b/seed/user-seeder.js @@ -1,14 +1,31 @@ /** * This script seeds the User collection in the MongoDB database. - * It can be run as a standalone script or imported as a module. + * + * It first connects to the MongoDB database using Mongoose. + * Then, it creates an array of new User instances with predefined data. + * Each User instance represents a document that will be inserted into the User collection. + * + * Each User document has the following fields: + * - type: The role of the user (e.g., "project_manager", "accounts_manager", "employee"). + * - email: The email address of the user. + * - password: The hashed password of the user. The password is hashed using bcrypt. + * - name: The name of the user. + * - dateOfBirth: The date of birth of the user. + * - contactNumber: The contact number of the user. + * */ -const User = require("../models/user"); -const bcrypt = require("bcrypt-nodejs"); -const mongoose = require("mongoose"); +let User = require("../models/user"); +let bcrypt = require("bcrypt-nodejs"); +let mongoose = require("mongoose"); + const db = require("../db"); -const users = [ +db.connect() + .then(() => console.log("Database connected")) + .catch((err) => console.error("Database connection error", err)); + +let users = [ new User({ type: "project_manager", email: "pm@pm.com", @@ -51,49 +68,20 @@ const users = [ }), ]; -/** - * Seeds the database with predefined users. - */ -const seedUsers = async (closeConn = true) => { - try { - console.log("Connecting to the database..."); - await db.connect(); - console.log("Database connected."); - - for (let user of users) { - const existingUser = await User.findOne({ email: user.email }); - if (existingUser) { - console.log(`User with email ${user.email} already exists.`); - } else { - await user.save(); - console.log(`User with email ${user.email} added.`); - } - } - - console.log("All users seeded successfully."); - } catch (error) { - console.error("Error seeding users:", error); - throw error; - } finally { - if (closeConn) { - await mongoose.disconnect(); - console.log("Database connection closed."); +(async function () { + for (let user of users) { + let existingUser = await User.findOne({ email: user.email }); + if (existingUser) { + console.log(`User with email ${user.email} already exists.`); + break; + } else { + await user.save(); } } -}; - -// Export the function for use in other scripts -module.exports = seedUsers; + exit(); +})(); -// If the script is run directly, execute the seeding process -if (require.main === module) { - seedUsers() - .then(() => { - console.log("Seeding completed successfully."); - process.exit(0); // Exit with success - }) - .catch((error) => { - console.error("Seeding failed:", error); - process.exit(1); // Exit with failure - }); +function exit() { + mongoose.disconnect(); + console.log("Users Added...") } \ No newline at end of file diff --git a/test/routes/admin.test.js b/test/routes/admin.test.js index 881ead4c..ed78f239 100644 --- a/test/routes/admin.test.js +++ b/test/routes/admin.test.js @@ -5,7 +5,7 @@ const User = require("../../models/user"); describe("Admin Routes", () => { test("GET / should render admin home page", async () => { - const res = await global.admin_agent.get("/admin/"); + const res = await admin_agent.get("/admin/"); expect(res.statusCode).toBe(200); @@ -20,7 +20,7 @@ describe("Admin Routes", () => { }); test("GET /admin/view-all-employees should return all employees", async () => { - const res = await global.admin_agent.get("/admin/view-all-employees"); + const res = await admin_agent.get("/admin/view-all-employees"); expect(res.statusCode).toBe(200); const $ = cheerio.load(res.text); @@ -42,7 +42,7 @@ describe("Admin Routes", () => { db.close(); }); - const res = await global.admin_agent.get(`/admin/employee-profile/${employeeId}`); + const res = await admin_agent.get(`/admin/employee-profile/${employeeId}`); expect(res.statusCode).toBe(200); const $ = cheerio.load(res.text); @@ -52,4 +52,4 @@ describe("Admin Routes", () => { expect(title.trim()).toBe("HRMS|Employee Profile"); expect(_employeeName.trim()).toBe(employeeName); }); -}); +}); \ No newline at end of file diff --git a/test/routes/employee.test.js b/test/routes/employee.test.js index 7819ca38..91b1005e 100644 --- a/test/routes/employee.test.js +++ b/test/routes/employee.test.js @@ -16,4 +16,4 @@ describe("Employee Routes", () => { expect(icon).toHaveLength(1); expect(text).toBe("Employee One"); }); -}); +}); \ No newline at end of file diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 0e6c3f84..3bea96ab 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -1,7 +1,7 @@ const { expect } = require("@jest/globals"); const cheerio = require("cheerio"); -describe("Employee Routes", () => { +describe("Project Manager Routes", () => { test("GET / should render project manager home page", async () => { const res = await pm_agent.get("/manager/"); @@ -16,4 +16,4 @@ describe("Employee Routes", () => { expect(icon).toHaveLength(1); expect(text).toBe("Project manager"); }); -}); +}); \ No newline at end of file diff --git a/test/setupTests.js b/test/setupTests.js index 491c2b95..0445cd7a 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -1,34 +1,26 @@ const db = require("../db"); const request = require("supertest"); const cheerio = require("cheerio"); -const seedUsers = require("../seed/user-seeder"); +const execSync = require("child_process").execSync; global.admin_agent = null; global.employee_agent = null; global.pm_agent = null; +global.csrfToken = null; module.exports = async () => { - try { - // seedUsers will create connection with db and will not close it - await seedUsers(closeConn = false); - + await db.connect().then(() => { + execSync("NODE_ENV=test node seed/user-seeder.js"); const app = require("../app"); - global.admin_agent = request.agent(app); - global.employee_agent = request.agent(app); - global.pm_agent = request.agent(app); - - console.log(global.admin_agent) - - console.log("Logging in users..."); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); + admin_agent = request.agent(app); + employee_agent = request.agent(app); + pm_agent = request.agent(app); + csrfToken = null; + }); - console.log("Test setup completed successfully."); - } catch (error) { - console.error("Error during test setup:", error); - process.exit(1); // Exit with failure - } + await loginAs(admin_agent, "admin@admin.com", "admin123"); + await loginAs(employee_agent, "employee1@employee.com", "123456"); + await loginAs(pm_agent, "pm@pm.com", "pm1234"); }; async function loginAs(agent, email, password) { @@ -43,4 +35,4 @@ async function loginAs(agent, email, password) { }); return agent; -} +} \ No newline at end of file diff --git a/test/teardownTests.js b/test/teardownTests.js index 8a296db1..f871bc12 100644 --- a/test/teardownTests.js +++ b/test/teardownTests.js @@ -2,16 +2,13 @@ const app = require("../app"); const db = require("../db"); module.exports = async () => { - console.log("Tearing down tests..."); - console.log("Logging out all users..."); await admin_agent.get("/logout"); await employee_agent.get("/logout"); await pm_agent.get("/logout"); await db.close(); - console.log("Database connection closed."); // If your app doesn't close the server automatically, you can do it manually if (app && app.close) { app.close(); } -}; +}; \ No newline at end of file From 4cd09cbb13d145a23dff893e62d45451ed14c783 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 12:27:06 +0500 Subject: [PATCH 17/26] chore(tests): Enhance CI workflow with MongoDB connection debugging and update agent references --- .github/workflows/hrms.yml | 39 ++++++++++++++++++++----------------- test/routes/manager.test.js | 2 +- test/setupTests.js | 31 ++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml index a1ac673e..fa42309c 100644 --- a/.github/workflows/hrms.yml +++ b/.github/workflows/hrms.yml @@ -3,10 +3,10 @@ name: HRMS CI on: push: branches: - - master # Run tests on push to the main branch + - master pull_request: branches: - - master # Run tests on pull requests to the main branch + - master env: DB_URL_TEST: mongodb://localhost:27017/test-db @@ -16,31 +16,34 @@ jobs: runs-on: ubuntu-latest services: - mongo: - image: mongo:5.0 # Use the MongoDB version you need - ports: - - 27017:27017 - options: >- - --health-cmd "mongo --eval 'db.runCommand({ ping: 1 })'" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + mongo: + image: mongo:5.0 + ports: + - 27017:27017 + options: >- + --health-cmd "mongo --eval 'db.runCommand({ ping: 1 })'" + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - # Step 1: Check out the repository - name: Checkout repository uses: actions/checkout@v3 - # Step 2: Set up Node.js - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: 18 # Use the Node.js version your project requires + node-version: 18 - # Step 3: Install dependencies - name: Install dependencies run: npm install - # Step 4: Run tests - - name: Run tests - run: npm test \ No newline at end of file + - name: Debug MongoDB Connection + run: | + npm install mongoose + node -e 'require("mongoose").connect(process.env.DB_URL_TEST).then(() => console.log("MongoDB connection successful")).catch(err => console.error("MongoDB connection error:", err))' + + - name: Run tests with debugging + run: | + echo "Running tests..." + npm test \ No newline at end of file diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 3bea96ab..03e42b9c 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -3,7 +3,7 @@ const cheerio = require("cheerio"); describe("Project Manager Routes", () => { test("GET / should render project manager home page", async () => { - const res = await pm_agent.get("/manager/"); + const res = await global.pm_agent.get("/manager/"); expect(res.statusCode).toBe(200); diff --git a/test/setupTests.js b/test/setupTests.js index 0445cd7a..e181208a 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -1,3 +1,4 @@ +// setupTests.js const db = require("../db"); const request = require("supertest"); const cheerio = require("cheerio"); @@ -9,18 +10,30 @@ global.pm_agent = null; global.csrfToken = null; module.exports = async () => { - await db.connect().then(() => { + try { + await db.connect(); + console.log("Database connected"); + execSync("NODE_ENV=test node seed/user-seeder.js"); + console.log("Database seeded"); + const app = require("../app"); - admin_agent = request.agent(app); - employee_agent = request.agent(app); - pm_agent = request.agent(app); - csrfToken = null; - }); + global.admin_agent = request.agent(app); + global.employee_agent = request.agent(app); + global.pm_agent = request.agent(app); + global.csrfToken = null; + console.log("Agents created"); - await loginAs(admin_agent, "admin@admin.com", "admin123"); - await loginAs(employee_agent, "employee1@employee.com", "123456"); - await loginAs(pm_agent, "pm@pm.com", "pm1234"); + await loginAs(global.admin_agent, "admin@admin.com", "admin123"); + console.log("Admin logged in"); + await loginAs(global.employee_agent, "employee1@employee.com", "123456"); + console.log("Employee logged in"); + await loginAs(global.pm_agent, "pm@pm.com", "pm1234"); + console.log("PM logged in"); + } catch (error) { + console.error("Setup failed:", error); + throw error; + } }; async function loginAs(agent, email, password) { From 17a6e26bc477a16440dcd7e91026bcb88dd7ec8d Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 12:30:49 +0500 Subject: [PATCH 18/26] chore(tests): Remove MongoDB connection debugging from CI workflow --- .github/workflows/hrms.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/hrms.yml b/.github/workflows/hrms.yml index fa42309c..00b3cec1 100644 --- a/.github/workflows/hrms.yml +++ b/.github/workflows/hrms.yml @@ -38,12 +38,7 @@ jobs: - name: Install dependencies run: npm install - - name: Debug MongoDB Connection - run: | - npm install mongoose - node -e 'require("mongoose").connect(process.env.DB_URL_TEST).then(() => console.log("MongoDB connection successful")).catch(err => console.error("MongoDB connection error:", err))' - - - name: Run tests with debugging + - name: Run tests run: | echo "Running tests..." npm test \ No newline at end of file From 814b647bebc902ccc0e5d4d6c37d33ebcd479bd9 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 12:41:34 +0500 Subject: [PATCH 19/26] chore(tests): Refactor project manager agent setup and cleanup in test files --- test/routes/manager.test.js | 25 +++++++++++++++++++++++-- test/setupTests.js | 7 ++----- test/teardownTests.js | 3 +-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 03e42b9c..426063af 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -1,9 +1,30 @@ -const { expect } = require("@jest/globals"); +const { expect, beforeAll, afterAll } = require("@jest/globals"); const cheerio = require("cheerio"); describe("Project Manager Routes", () => { + let pm_agent = null; + + beforeAll(async () => { + const request = require("supertest"); + pm_agent = request.agent(global.app); + const getRes = await pm_agent.get("/"); + const $ = cheerio.load(getRes.text); + const csrfToken = $('input[name="_csrf"]').val(); + + await pm_agent.post("/login").send({ + _csrf: csrfToken, + email: "pm@pm.com", + password: "pm1234", + }); + + }); + + afterAll(async () => { + await pm_agent.get("/logout"); + }); + test("GET / should render project manager home page", async () => { - const res = await global.pm_agent.get("/manager/"); + const res = await pm_agent.get("/manager/"); expect(res.statusCode).toBe(200); diff --git a/test/setupTests.js b/test/setupTests.js index e181208a..cc56c577 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -6,8 +6,8 @@ const execSync = require("child_process").execSync; global.admin_agent = null; global.employee_agent = null; -global.pm_agent = null; global.csrfToken = null; +global.app = null; module.exports = async () => { try { @@ -17,10 +17,9 @@ module.exports = async () => { execSync("NODE_ENV=test node seed/user-seeder.js"); console.log("Database seeded"); - const app = require("../app"); + global.app = require("../app"); global.admin_agent = request.agent(app); global.employee_agent = request.agent(app); - global.pm_agent = request.agent(app); global.csrfToken = null; console.log("Agents created"); @@ -28,8 +27,6 @@ module.exports = async () => { console.log("Admin logged in"); await loginAs(global.employee_agent, "employee1@employee.com", "123456"); console.log("Employee logged in"); - await loginAs(global.pm_agent, "pm@pm.com", "pm1234"); - console.log("PM logged in"); } catch (error) { console.error("Setup failed:", error); throw error; diff --git a/test/teardownTests.js b/test/teardownTests.js index f871bc12..a136acaa 100644 --- a/test/teardownTests.js +++ b/test/teardownTests.js @@ -4,8 +4,7 @@ const db = require("../db"); module.exports = async () => { await admin_agent.get("/logout"); await employee_agent.get("/logout"); - await pm_agent.get("/logout"); - + await db.close(); // If your app doesn't close the server automatically, you can do it manually if (app && app.close) { From 8c301559904786b17faa8a8734caa80f5b130811 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 13:11:19 +0500 Subject: [PATCH 20/26] chore(tests): Update project manager agent initialization in tests for consistency --- test/routes/manager.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 426063af..62b8f4ca 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -3,10 +3,10 @@ const cheerio = require("cheerio"); describe("Project Manager Routes", () => { let pm_agent = null; - + beforeAll(async () => { const request = require("supertest"); - pm_agent = request.agent(global.app); + pm_agent = request.agent(app); const getRes = await pm_agent.get("/"); const $ = cheerio.load(getRes.text); const csrfToken = $('input[name="_csrf"]').val(); From 38752548cea2b997bd42560c63f23719ff2088aa Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 13:15:02 +0500 Subject: [PATCH 21/26] chore(tests): Refactor project manager route tests to include database connection management --- test/routes/manager.test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 62b8f4ca..84c89a91 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -1,11 +1,16 @@ const { expect, beforeAll, afterAll } = require("@jest/globals"); const cheerio = require("cheerio"); +const db = require("../../db"); +const request = require("supertest"); + + describe("Project Manager Routes", () => { let pm_agent = null; beforeAll(async () => { - const request = require("supertest"); + await db.connect(); + const app = require("../../app"); pm_agent = request.agent(app); const getRes = await pm_agent.get("/"); const $ = cheerio.load(getRes.text); @@ -21,6 +26,7 @@ describe("Project Manager Routes", () => { afterAll(async () => { await pm_agent.get("/logout"); + await db.close(); }); test("GET / should render project manager home page", async () => { From d41267e14ac249b162a8e73d4f0c5c972c32ac9f Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 13:18:23 +0500 Subject: [PATCH 22/26] chore(tests): Implement employee agent setup and teardown in employee route tests --- test/routes/employee.test.js | 26 +++++++++++++++++++++++++- test/routes/manager.test.js | 1 - test/setupTests.js | 4 ---- test/teardownTests.js | 1 - 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/test/routes/employee.test.js b/test/routes/employee.test.js index 91b1005e..6aa1ee09 100644 --- a/test/routes/employee.test.js +++ b/test/routes/employee.test.js @@ -1,7 +1,31 @@ const { expect } = require("@jest/globals"); const cheerio = require("cheerio"); +const db = require("../../db"); +const request = require("supertest"); describe("Employee Routes", () => { + let employee_agent = null; + + beforeAll(async () => { + await db.connect(); + const app = require("../../app"); + employee_agent = request.agent(app); + const getRes = await employee_agent.get("/"); + const $ = cheerio.load(getRes.text); + const csrfToken = $('input[name="_csrf"]').val(); + + await employee_agent.post("/login").send({ + _csrf: csrfToken, + email: "pm@pm.com", + password: "pm1234", + }); + }); + + afterAll(async () => { + await employee_agent.get("/logout"); + await db.close(); + }); + test("GET / should render employee home page", async () => { const res = await employee_agent.get("/employee/"); @@ -16,4 +40,4 @@ describe("Employee Routes", () => { expect(icon).toHaveLength(1); expect(text).toBe("Employee One"); }); -}); \ No newline at end of file +}); diff --git a/test/routes/manager.test.js b/test/routes/manager.test.js index 84c89a91..fb1ca58e 100644 --- a/test/routes/manager.test.js +++ b/test/routes/manager.test.js @@ -1,6 +1,5 @@ const { expect, beforeAll, afterAll } = require("@jest/globals"); const cheerio = require("cheerio"); - const db = require("../../db"); const request = require("supertest"); diff --git a/test/setupTests.js b/test/setupTests.js index cc56c577..9d09f27f 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -5,7 +5,6 @@ const cheerio = require("cheerio"); const execSync = require("child_process").execSync; global.admin_agent = null; -global.employee_agent = null; global.csrfToken = null; global.app = null; @@ -19,14 +18,11 @@ module.exports = async () => { global.app = require("../app"); global.admin_agent = request.agent(app); - global.employee_agent = request.agent(app); global.csrfToken = null; console.log("Agents created"); await loginAs(global.admin_agent, "admin@admin.com", "admin123"); console.log("Admin logged in"); - await loginAs(global.employee_agent, "employee1@employee.com", "123456"); - console.log("Employee logged in"); } catch (error) { console.error("Setup failed:", error); throw error; diff --git a/test/teardownTests.js b/test/teardownTests.js index a136acaa..70c17047 100644 --- a/test/teardownTests.js +++ b/test/teardownTests.js @@ -3,7 +3,6 @@ const db = require("../db"); module.exports = async () => { await admin_agent.get("/logout"); - await employee_agent.get("/logout"); await db.close(); // If your app doesn't close the server automatically, you can do it manually From e65c26c8cc7e0f3590e954c659318d152b23f4c8 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 13:47:35 +0500 Subject: [PATCH 23/26] chore(tests): Enhance admin and employee route tests with agent setup and teardown --- test/routes/admin.test.js | 37 ++++++++++++++++++++++++++++-------- test/routes/employee.test.js | 4 ++-- test/setupTests.js | 37 ++---------------------------------- test/teardownTests.js | 13 ++++++------- 4 files changed, 39 insertions(+), 52 deletions(-) diff --git a/test/routes/admin.test.js b/test/routes/admin.test.js index ed78f239..7896c5f2 100644 --- a/test/routes/admin.test.js +++ b/test/routes/admin.test.js @@ -1,9 +1,32 @@ const { expect } = require("@jest/globals"); const db = require("../../db"); +const request = require("supertest"); const cheerio = require("cheerio"); const User = require("../../models/user"); describe("Admin Routes", () => { + let admin_agent = null; + + beforeAll(async () => { + await db.connect(); + const app = require("../../app"); + admin_agent = request.agent(app); + const getRes = await admin_agent.get("/"); + const $ = cheerio.load(getRes.text); + const csrfToken = $('input[name="_csrf"]').val(); + + await admin_agent.post("/login").send({ + _csrf: csrfToken, + email: "admin@admin.com", + password: "admin123", + }); + }); + + afterAll(async () => { + await admin_agent.get("/logout"); + await db.close(); + }); + test("GET / should render admin home page", async () => { const res = await admin_agent.get("/admin/"); @@ -35,13 +58,11 @@ describe("Admin Routes", () => { test("GET /admin/employee-profile/:id should return employee profile", async () => { let employeeId; let employeeName; - await db.connect().then(async () => { - const employee = await User.findOne({ type: "accounts_manager" }); - employeeId = employee._id; - employeeName = employee.name; - db.close(); - }); - + + const employee = await User.findOne({ type: "accounts_manager" }); + employeeId = employee._id; + employeeName = employee.name; + const res = await admin_agent.get(`/admin/employee-profile/${employeeId}`); expect(res.statusCode).toBe(200); @@ -52,4 +73,4 @@ describe("Admin Routes", () => { expect(title.trim()).toBe("HRMS|Employee Profile"); expect(_employeeName.trim()).toBe(employeeName); }); -}); \ No newline at end of file +}); diff --git a/test/routes/employee.test.js b/test/routes/employee.test.js index 6aa1ee09..4b7d3d67 100644 --- a/test/routes/employee.test.js +++ b/test/routes/employee.test.js @@ -16,8 +16,8 @@ describe("Employee Routes", () => { await employee_agent.post("/login").send({ _csrf: csrfToken, - email: "pm@pm.com", - password: "pm1234", + email: "employee1@employee.com", + password: "123456", }); }); diff --git a/test/setupTests.js b/test/setupTests.js index 9d09f27f..7667eb48 100644 --- a/test/setupTests.js +++ b/test/setupTests.js @@ -1,44 +1,11 @@ -// setupTests.js -const db = require("../db"); -const request = require("supertest"); -const cheerio = require("cheerio"); const execSync = require("child_process").execSync; -global.admin_agent = null; -global.csrfToken = null; -global.app = null; - module.exports = async () => { try { - await db.connect(); - console.log("Database connected"); - execSync("NODE_ENV=test node seed/user-seeder.js"); - console.log("Database seeded"); - - global.app = require("../app"); - global.admin_agent = request.agent(app); - global.csrfToken = null; - console.log("Agents created"); - - await loginAs(global.admin_agent, "admin@admin.com", "admin123"); - console.log("Admin logged in"); + console.log("Database seeded") } catch (error) { console.error("Setup failed:", error); throw error; } -}; - -async function loginAs(agent, email, password) { - const getRes = await agent.get("/"); - const $ = cheerio.load(getRes.text); - const csrfToken = $('input[name="_csrf"]').val(); - - await agent.post("/login").send({ - _csrf: csrfToken, - email: email, - password: password, - }); - - return agent; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/test/teardownTests.js b/test/teardownTests.js index 70c17047..4dfc2168 100644 --- a/test/teardownTests.js +++ b/test/teardownTests.js @@ -1,12 +1,11 @@ -const app = require("../app"); -const db = require("../db"); +//const app = require("../app"); +//const db = require("../db"); module.exports = async () => { - await admin_agent.get("/logout"); - await db.close(); + //await db.close(); // If your app doesn't close the server automatically, you can do it manually - if (app && app.close) { - app.close(); - } + // if (app && app.close) { + // //app.close(); + // } }; \ No newline at end of file From feaed50faa128856125d5c63ae8a57b63c77a525 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 14:02:19 +0500 Subject: [PATCH 24/26] chore(dependencies): downgrade express-validator to version 4.0.0 --- package-lock.json | 100 ++++++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f38da73..a5063659 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "ejs": "~3.1.7", "express": "^4.17.1", "express-session": "^1.17.1", - "express-validator": "^7.0.1", + "express-validator": "^4.0.0", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", @@ -1142,6 +1142,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, "node_modules/@types/bson": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", @@ -1150,6 +1159,35 @@ "@types/node": "*" } }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.0.39", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", + "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1159,6 +1197,11 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1183,6 +1226,11 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, "node_modules/@types/mongodb": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", @@ -1200,6 +1248,35 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/qs": { + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2527,15 +2604,24 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" }, "node_modules/express-validator": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", - "integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-4.3.0.tgz", + "integrity": "sha512-EYU+JJ2EoLpcw+GKwbB1K8UGb/w1A70Wf3gD/zE9QScQxeSt8qad93lxGtsLwZFoiYM0EByVoSzHJnskp+eVHQ==", "dependencies": { - "lodash": "^4.17.21", - "validator": "^13.9.0" + "@types/express": "~4.0.34", + "lodash": "^4.16.0", + "validator": "~8.2.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 6.0.0" + } + }, + "node_modules/express-validator/node_modules/validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "engines": { + "node": ">= 0.10" } }, "node_modules/express/node_modules/body-parser": { diff --git a/package.json b/package.json index c35e81a4..e7588773 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "ejs": "~3.1.7", "express": "^4.17.1", "express-session": "^1.17.1", - "express-validator": "^7.0.1", + "express-validator": "^4.0.0", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", From 498a00cf1a697fc5b1d2d6132efc3408143135f0 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 14:13:13 +0500 Subject: [PATCH 25/26] chore(dependencies): downgrade express and passport to earlier versions --- package-lock.json | 17 ++++++----------- package.json | 4 ++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 76cee9a4..898751ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "csurf": "^1.9.0", "dotenv": "^16.4.3", "ejs": "~3.1.7", - "express": "^4.19.2", + "express": "^4.17.1", "express-session": "^1.17.1", "express-validator": "^4.0.0", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", "morgan": "^1.10.0", - "passport": "^0.6.0", + "passport": "^0.4.1", "passport-local": "^1.0.0", "serve-favicon": "^2.5.0" }, @@ -4697,20 +4697,15 @@ } }, "node_modules/passport": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz", - "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", "dependencies": { "passport-strategy": "1.x.x", - "pause": "0.0.1", - "utils-merge": "^1.0.1" + "pause": "0.0.1" }, "engines": { "node": ">= 0.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jaredhanson" } }, "node_modules/passport-local": { diff --git a/package.json b/package.json index 2b31d65d..ac83b840 100644 --- a/package.json +++ b/package.json @@ -15,14 +15,14 @@ "csurf": "^1.9.0", "dotenv": "^16.4.3", "ejs": "~3.1.7", - "express": "^4.19.2", + "express": "^4.17.1", "express-session": "^1.17.1", "express-validator": "^4.0.0", "moment": "^2.27.0", "mongoose": "^5.7.5", "mongoose-type-email": "^1.0.2", "morgan": "^1.10.0", - "passport": "^0.6.0", + "passport": "^0.4.1", "passport-local": "^1.0.0", "serve-favicon": "^2.5.0" }, From ed76ff691424db978cb119495bb3eced6156c6c7 Mon Sep 17 00:00:00 2001 From: Muneeb Shahid Date: Tue, 13 May 2025 14:15:57 +0500 Subject: [PATCH 26/26] docs: update README to indicate repository is no longer maintained --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cbbe9444..1aaf0563 100644 --- a/README.md +++ b/README.md @@ -55,4 +55,8 @@ Accounts Manager is also an employee with the ability to generate pay slip, set 1. Browser will redirect to the home page of the application. ### Run Tests -1. To run tests, in the terminal, at the root folder of application, type command **npm test**. \ No newline at end of file +1. To run tests, in the terminal, at the root folder of application, type command **npm test**. + +
+ +**⚠️ Note: This repository is no longer maintained.** \ No newline at end of file