From 28ee0dadc54f6175fc0a88ce67683baa1376b1fe Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Mon, 17 Jun 2024 21:24:58 -0300 Subject: [PATCH 1/6] feat: create getProjectByPerson route and function --- src/controllers/userProfileController.js | 40 +++++++++++++++++++++++- src/routes/userProfileRouter.js | 6 ++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index 9d31098f5..ee2087f53 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -16,7 +16,7 @@ const cacheClosure = require('../utilities/nodeCache'); const followUp = require('../models/followUp'); // const { authorizedUserSara, authorizedUserJae } = process.env; -const authorizedUserSara = `sucheta_mu@test.com`; // To test this code please include your email here +const authorizedUserSara = `nathaliaowner@gmail.com`; // To test this code please include your email here const authorizedUserJae = `jae@onecommunityglobal.org`; const { hasPermission, canRequestorUpdateUser } = require('../utilities/permissions'); @@ -1221,6 +1221,43 @@ const userProfileController = function (UserProfile) { } }; + const getProjectsByPerson = async function (req, res) { + try { + const { name } = req.body; + + const match = name.trim().match(/^([A-Za-z]*)\s*([A-Za-z]*)$/i); + + console.log(match); + + const query = { + $or: [ + { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, + { + lastName: { + $regex: new RegExp( + `^${escapeRegExp(match[2].length > 0 ? match[2] : match[1])}`, + 'i', + ), + }, + }, + ], + }; + + const userProfile = await UserProfile.find(query); + + if (userProfile) { + const allProjects = userProfile + .map((user) => user.projects) + .filter((projects) => projects.length > 0); + + return res.status(200).send({ message: 'Found profile and related projects', allProjects }); + } + return res.status(400).send({ message: 'Projects not found' }); + } catch (error) { + return res.status(500).send({ massage: 'Encountered an error, please try again!' }); + } + }; + return { postUserProfile, getUserProfiles, @@ -1242,6 +1279,7 @@ const userProfileController = function (UserProfile) { getUserByFullName, changeUserRehireableStatus, authorizeUser, + getProjectsByPerson, }; }; diff --git a/src/routes/userProfileRouter.js b/src/routes/userProfileRouter.js index e6892026b..e8fd9d589 100644 --- a/src/routes/userProfileRouter.js +++ b/src/routes/userProfileRouter.js @@ -11,8 +11,8 @@ const routes = function (userProfile) { .route('/userProfile') .get(controller.getUserProfiles) .post( - body('firstName').customSanitizer((value) => value.trim()), - body('lastName').customSanitizer((value) => value.trim()), + body('firstName').customSanitizer((req) => req.trim()), + body('lastName').customSanitizer((req) => req.trim()), controller.postUserProfile, ); @@ -87,6 +87,8 @@ const routes = function (userProfile) { .route('/userProfile/authorizeUser/weeeklySummaries') .post(controller.authorizeUser); + userProfileRouter.route('/userProfile/projects/userProjects').get(controller.getProjectsByPerson); + return userProfileRouter; }; From acbdeda43c0f2bb0ccfd7d8fb1507cfc64a11403 Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Fri, 21 Jun 2024 09:28:48 -0300 Subject: [PATCH 2/6] fix: function getProjectByPerson now select projects when the user entered both first name and last name --- src/controllers/userProfileController.js | 35 +++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index ee2087f53..803ba5ff5 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -1229,19 +1229,28 @@ const userProfileController = function (UserProfile) { console.log(match); - const query = { - $or: [ - { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, - { - lastName: { - $regex: new RegExp( - `^${escapeRegExp(match[2].length > 0 ? match[2] : match[1])}`, - 'i', - ), - }, - }, - ], - }; + const query = + match[2].length > 0 + ? { + $and: [ + { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, + { + lastName: { + $regex: new RegExp(`^${escapeRegExp(match[2])}`, 'i'), + }, + }, + ], + } + : { + $or: [ + { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, + { + lastName: { + $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i'), + }, + }, + ], + }; const userProfile = await UserProfile.find(query); From 2204f2e280f498696140833c23873d96277c7413 Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Fri, 21 Jun 2024 18:34:54 -0300 Subject: [PATCH 3/6] fix: Adjust data retrieval to use parameters instead of body --- src/controllers/userProfileController.js | 7 +++---- src/routes/userProfileRouter.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index 803ba5ff5..be88bb6c9 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -1223,12 +1223,10 @@ const userProfileController = function (UserProfile) { const getProjectsByPerson = async function (req, res) { try { - const { name } = req.body; + const { name } = req.params; const match = name.trim().match(/^([A-Za-z]*)\s*([A-Za-z]*)$/i); - console.log(match); - const query = match[2].length > 0 ? { @@ -1257,7 +1255,8 @@ const userProfileController = function (UserProfile) { if (userProfile) { const allProjects = userProfile .map((user) => user.projects) - .filter((projects) => projects.length > 0); + .filter((projects) => projects.length > 0) + .flat(); return res.status(200).send({ message: 'Found profile and related projects', allProjects }); } diff --git a/src/routes/userProfileRouter.js b/src/routes/userProfileRouter.js index e8fd9d589..5a4f7a6e6 100644 --- a/src/routes/userProfileRouter.js +++ b/src/routes/userProfileRouter.js @@ -87,7 +87,7 @@ const routes = function (userProfile) { .route('/userProfile/authorizeUser/weeeklySummaries') .post(controller.authorizeUser); - userProfileRouter.route('/userProfile/projects/userProjects').get(controller.getProjectsByPerson); + userProfileRouter.route('/userProfile/projects/:name').get(controller.getProjectsByPerson); return userProfileRouter; }; From 674df728a5d74636adc900fae268b7278cb490d3 Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Thu, 27 Jun 2024 15:05:48 -0300 Subject: [PATCH 4/6] fix: return status 400 when no projects are found --- src/controllers/userProfileController.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index be88bb6c9..eccd2683b 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -1258,9 +1258,12 @@ const userProfileController = function (UserProfile) { .filter((projects) => projects.length > 0) .flat(); + if (allProjects.length === 0) { + return res.status(400).send({ message: 'Projects not found', allProjects }); + } + return res.status(200).send({ message: 'Found profile and related projects', allProjects }); } - return res.status(400).send({ message: 'Projects not found' }); } catch (error) { return res.status(500).send({ massage: 'Encountered an error, please try again!' }); } From 0a2583773b0a9d48ef57d76035e85569386cba82 Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Thu, 27 Jun 2024 16:31:52 -0300 Subject: [PATCH 5/6] fix: getProjectByPerson returns only a message when there are no projects --- src/controllers/userProfileController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index eccd2683b..c7d2eef1c 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -1259,7 +1259,7 @@ const userProfileController = function (UserProfile) { .flat(); if (allProjects.length === 0) { - return res.status(400).send({ message: 'Projects not found', allProjects }); + return res.status(400).send({ message: 'Projects not found' }); } return res.status(200).send({ message: 'Found profile and related projects', allProjects }); From 7de007ac7acab359019c7d816a7c57e3ff62c9e3 Mon Sep 17 00:00:00 2001 From: Nathalia Carnevalli Date: Thu, 4 Jul 2024 18:45:08 -0300 Subject: [PATCH 6/6] fix: query selection to properly select user's firstName and lastName --- package-lock.json | 42 +++++++++---------- src/controllers/userProfileController.js | 53 +++++++++++++----------- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 71c550c2c..b5a06be58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2857,7 +2857,7 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/methods": { @@ -5066,7 +5066,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "colorette": { "version": "2.0.19", @@ -5090,7 +5090,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "component-emitter": { "version": "1.3.1", @@ -5100,7 +5100,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "confusing-browser-globals": { "version": "1.0.11", @@ -5606,7 +5606,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { "version": "1.4.81", @@ -5628,7 +5628,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -5773,7 +5773,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", @@ -6708,7 +6708,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "event-target-shim": { "version": "5.0.1", @@ -6916,7 +6916,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-safe-stringify": { @@ -7135,7 +7135,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs-constants": { "version": "1.0.0", @@ -7458,7 +7458,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "has-property-descriptors": { "version": "1.0.0", @@ -7870,7 +7870,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -7990,7 +7990,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "istanbul-lib-coverage": { "version": "3.2.2", @@ -10841,7 +10841,7 @@ "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.merge": { "version": "4.6.2", @@ -11040,7 +11040,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -12365,7 +12365,7 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==" }, "parse-srcset": { "version": "1.0.2", @@ -12385,7 +12385,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -13154,7 +13154,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -13904,7 +13904,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-final-newline": { @@ -14119,7 +14119,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-regex-range": { "version": "5.0.1", @@ -14312,7 +14312,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { "version": "1.0.16", diff --git a/src/controllers/userProfileController.js b/src/controllers/userProfileController.js index 02e79ea55..5edd67022 100644 --- a/src/controllers/userProfileController.js +++ b/src/controllers/userProfileController.js @@ -1455,31 +1455,34 @@ const userProfileController = function (UserProfile) { const getProjectsByPerson = async function (req, res) { try { const { name } = req.params; - - const match = name.trim().match(/^([A-Za-z]*)\s*([A-Za-z]*)$/i); - - const query = - match[2].length > 0 - ? { - $and: [ - { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, - { - lastName: { - $regex: new RegExp(`^${escapeRegExp(match[2])}`, 'i'), - }, - }, - ], - } - : { - $or: [ - { firstName: { $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i') } }, - { - lastName: { - $regex: new RegExp(`^${escapeRegExp(match[1])}`, 'i'), - }, - }, - ], - }; + const match = name.trim().split(' '); + const firstName = match[0]; + const lastName = match[match.length - 1]; + + const query = match[1] + ? { + $or: [ + { + firstName: { $regex: new RegExp(`${escapeRegExp(name)}`, 'i') }, + }, + { + $and: [ + { firstName: { $regex: new RegExp(`${escapeRegExp(firstName)}`, 'i') } }, + { lastName: { $regex: new RegExp(`${escapeRegExp(lastName)}`, 'i') } }, + ], + }, + ], + } + : { + $or: [ + { + firstName: { $regex: new RegExp(`${escapeRegExp(name)}`, 'i') }, + }, + { + lastName: { $regex: new RegExp(`${escapeRegExp(name)}`, 'i') }, + }, + ], + }; const userProfile = await UserProfile.find(query);