From d543b204b3e3ac81435a74fefc4045798180bf2c Mon Sep 17 00:00:00 2001 From: Pierre Theo Klein Date: Mon, 11 Feb 2019 11:03:10 -0500 Subject: [PATCH 1/3] Convert major to list, convert ascii to string validation --- middlewares/validators/account.validator.js | 12 +++++----- middlewares/validators/hacker.validator.js | 16 ++++++------- middlewares/validators/sponsor.validator.js | 4 ++-- middlewares/validators/team.validator.js | 10 ++++---- middlewares/validators/validator.helper.js | 18 ++++++++++++++ models/hacker.model.js | 4 ++-- routes/api/hacker.js | 2 +- tests/util/hacker.test.util.js | 26 ++++++++++----------- 8 files changed, 55 insertions(+), 37 deletions(-) diff --git a/middlewares/validators/account.validator.js b/middlewares/validators/account.validator.js index 69ef5fb7..a1c86932 100644 --- a/middlewares/validators/account.validator.js +++ b/middlewares/validators/account.validator.js @@ -4,9 +4,9 @@ const Constants = require("../../constants/general.constant"); module.exports = { newAccountValidator: [ - VALIDATOR.asciiValidator("body", "firstName", false), - VALIDATOR.asciiValidator("body", "lastName", false), - VALIDATOR.asciiValidator("body", "pronoun", false), + VALIDATOR.stringValidator("body", "firstName", false), + VALIDATOR.stringValidator("body", "lastName", false), + VALIDATOR.stringValidator("body", "pronoun", false), VALIDATOR.regexValidator("body", "email", false, Constants.EMAIL_REGEX), VALIDATOR.alphaArrayValidator("body", "dietaryRestrictions", false), VALIDATOR.enumValidator("body", "shirtSize", Constants.SHIRT_SIZES, false), @@ -16,9 +16,9 @@ module.exports = { VALIDATOR.phoneNumberValidator("body", "phoneNumber", false) ], updateAccountValidator: [ - VALIDATOR.asciiValidator("body", "firstName", true), - VALIDATOR.asciiValidator("body", "lastName", true), - VALIDATOR.asciiValidator("body", "pronoun", true), + VALIDATOR.stringValidator("body", "firstName", true), + VALIDATOR.stringValidator("body", "lastName", true), + VALIDATOR.stringValidator("body", "pronoun", true), VALIDATOR.regexValidator("body", "email", true, Constants.EMAIL_REGEX), VALIDATOR.alphaArrayValidator("body", "dietaryRestrictions", true), VALIDATOR.enumValidator("body", "shirtSize", Constants.SHIRT_SIZES, true), diff --git a/middlewares/validators/hacker.validator.js b/middlewares/validators/hacker.validator.js index 0170fce6..63651371 100644 --- a/middlewares/validators/hacker.validator.js +++ b/middlewares/validators/hacker.validator.js @@ -6,13 +6,13 @@ module.exports = { newHackerValidator: [ // status will be added automatically VALIDATOR.mongoIdValidator("body", "accountId", false), - VALIDATOR.asciiValidator("body", "school", false), - VALIDATOR.asciiValidator("body", "degree", false), - VALIDATOR.asciiValidator("body", "gender", false), + VALIDATOR.stringValidator("body", "school", false), + VALIDATOR.stringValidator("body", "degree", false), + VALIDATOR.stringValidator("body", "gender", false), VALIDATOR.booleanValidator("body", "needsBus", false), VALIDATOR.applicationValidator("body", "application", false), VALIDATOR.alphaArrayValidator("body", "ethnicity", false), - VALIDATOR.asciiValidator("body", "major", false), + VALIDATOR.alphaArrayValidator("body", "major", false), VALIDATOR.integerValidator("body", "graduationYear", false, 2019, 2030), VALIDATOR.booleanValidator("body", "codeOfConduct", false, true), VALIDATOR.mongoIdValidator("body", "teamId", true) @@ -23,13 +23,13 @@ module.exports = { ], updateHackerValidator: [ - VALIDATOR.asciiValidator("body", "school", true), - VALIDATOR.asciiValidator("body", "degree", true), - VALIDATOR.asciiValidator("body", "gender", true), + VALIDATOR.stringValidator("body", "school", true), + VALIDATOR.stringValidator("body", "degree", true), + VALIDATOR.stringValidator("body", "gender", true), VALIDATOR.booleanValidator("body", "needsBus", true), VALIDATOR.applicationValidator("body", "application", true), VALIDATOR.alphaArrayValidator("body", "ethnicity", true), - VALIDATOR.asciiValidator("body", "major", true), + VALIDATOR.stringValidator("body", "major", true), VALIDATOR.integerValidator("body", "graduationYear", true, 2019, 2030), ], updateStatusValidator: [ diff --git a/middlewares/validators/sponsor.validator.js b/middlewares/validators/sponsor.validator.js index 60deab29..f2f9d8f5 100644 --- a/middlewares/validators/sponsor.validator.js +++ b/middlewares/validators/sponsor.validator.js @@ -10,13 +10,13 @@ module.exports = { // assuming that the tiers are between 0 and 5 (inclusive) // 5 is the custom class VALIDATOR.integerValidator("body", "tier", false, 0, 5), - VALIDATOR.asciiValidator("body", "company", false), + VALIDATOR.stringValidator("body", "company", false), VALIDATOR.regexValidator("body", "contractURL", false, Constants.URL_REGEX), VALIDATOR.mongoIdArrayValidator("body", "nominees", true), ], updateSponsorValidator: [ - VALIDATOR.asciiValidator("body", "company", true), + VALIDATOR.stringValidator("body", "company", true), VALIDATOR.regexValidator("body", "contractURL", true, Constants.URL_REGEX), VALIDATOR.mongoIdArrayValidator("body", "nominees", true), ], diff --git a/middlewares/validators/team.validator.js b/middlewares/validators/team.validator.js index c064fe00..bd18949a 100644 --- a/middlewares/validators/team.validator.js +++ b/middlewares/validators/team.validator.js @@ -4,18 +4,18 @@ const Constants = require("../../constants/general.constant"); module.exports = { newTeamValidator: [ - VALIDATOR.asciiValidator("body", "name", false), + VALIDATOR.stringValidator("body", "name", false), VALIDATOR.regexValidator("body", "devpostURL", true, Constants.DEVPOST_REGEX), - VALIDATOR.asciiValidator("body", "projectName", true) + VALIDATOR.stringValidator("body", "projectName", true) ], joinTeamValidator: [ - VALIDATOR.asciiValidator("body", "name", false), + VALIDATOR.stringValidator("body", "name", false), ], patchTeamValidator: [ - VALIDATOR.asciiValidator("body", "name", true), + VALIDATOR.stringValidator("body", "name", true), VALIDATOR.regexValidator("body", "devpostURL", true, Constants.DEVPOST_REGEX), - VALIDATOR.asciiValidator("body", "projectName", true) + VALIDATOR.stringValidator("body", "projectName", true) ], }; \ No newline at end of file diff --git a/middlewares/validators/validator.helper.js b/middlewares/validators/validator.helper.js index 1ebcf272..3fff34b4 100644 --- a/middlewares/validators/validator.helper.js +++ b/middlewares/validators/validator.helper.js @@ -124,6 +124,23 @@ function asciiValidator(fieldLocation, fieldname, optional = true) { } } +/** + * Validates that field name is string only. + * @param {"query" | "body" | "header" | "param"} fieldLocation the location where the field should be found + * @param {string} fieldname name of the field that needs to be validated. + * @param {boolean} optional whether the field is optional or not. + */ +function stringValidator(fieldLocation, fieldname, optional = true) { + const name = setProperValidationChainBuilder(fieldLocation, fieldname, "invalid string"); + if (optional) { + return name.optional({ + checkFalsy: true + }).isString().withMessage("must be a string"); + } else { + return name.exists().withMessage("name must exist").isString().withMessage("must be a string"); + } +} + /** * Validates the field against a regex * @param {"query" | "body" | "header" | "param"} fieldLocation the location where the field should be found @@ -614,4 +631,5 @@ module.exports = { dateValidator: dateValidator, enumValidator: enumValidator, routesValidator: routesValidator, + stringValidator: stringValidator }; \ No newline at end of file diff --git a/models/hacker.model.js b/models/hacker.model.js index d1536cf6..26316e6b 100644 --- a/models/hacker.model.js +++ b/models/hacker.model.js @@ -83,10 +83,10 @@ const HackerSchema = new mongoose.Schema({ }], required: true }, - major: { + major: [{ type: String, required: true - }, + }], graduationYear: { type: Number, required: true diff --git a/routes/api/hacker.js b/routes/api/hacker.js index 250a2c51..e1233416 100644 --- a/routes/api/hacker.js +++ b/routes/api/hacker.js @@ -59,7 +59,7 @@ module.exports = { "school":"McPherson College", "gender":"Female", "needsBus":false, - "major":"Accounting", + "major":["Accounting"], "graduationYear":2019, "codeOfConduct":true, } diff --git a/tests/util/hacker.test.util.js b/tests/util/hacker.test.util.js index a23e62bf..a34c6565 100644 --- a/tests/util/hacker.test.util.js +++ b/tests/util/hacker.test.util.js @@ -32,7 +32,7 @@ const TeamHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["Native American"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team1Id, @@ -60,7 +60,7 @@ const TeamHacker1 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team3Id, @@ -88,7 +88,7 @@ const TeamHacker2 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team3Id, @@ -116,7 +116,7 @@ const TeamHacker3 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team3Id, @@ -144,7 +144,7 @@ const TeamHacker4 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team3Id, @@ -172,7 +172,7 @@ const NoTeamHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, }; @@ -197,7 +197,7 @@ const newHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["Caucasian"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, }; @@ -222,7 +222,7 @@ const newHacker1 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["African American"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, }; @@ -248,7 +248,7 @@ const invalidHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["Caucasian"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": false, }; @@ -268,7 +268,7 @@ const invalidHacker1 = { "jobInterest": "ASDF", }, "ethnicity": ["Asian", "Caucasian"], - "major": "CS", + "major": ["CS"], "graduationYear": 2020, "codeOfConduct": true, }; @@ -295,7 +295,7 @@ const duplicateAccountLinkHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["Caucasian"], - "major": "CS", + "major": ["CS"], "graduationYear": 2019, "codeOfConduct": true, }; @@ -322,7 +322,7 @@ const waitlistedHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, "teamId": Constants.MongoId.team2Id, @@ -350,7 +350,7 @@ const unconfirmedAccountHacker0 = { "skills": ["CSS", "HTML", "JS"], }, "ethnicity": ["European"], - "major": "EE", + "major": ["EE"], "graduationYear": 2019, "codeOfConduct": true, }; From ea1ec2f0e5b2b716273ec144653e07ed7a58f055 Mon Sep 17 00:00:00 2001 From: Pierre Theo Klein Date: Mon, 11 Feb 2019 11:09:48 -0500 Subject: [PATCH 2/3] update docs --- docs/api/api_data.js | 6 +++--- docs/api/api_data.json | 6 +++--- docs/api/api_project.js | 2 +- docs/api/api_project.json | 2 +- routes/api/hacker.js | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/api/api_data.js b/docs/api/api_data.js index 78aec409..d5523a6e 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -1167,7 +1167,7 @@ define({ }, { "group": "body", - "type": "String", + "type": "String[]", "optional": false, "field": "major", "description": "

the major of the hacker

" @@ -1551,7 +1551,7 @@ define({ }, { "group": "body", - "type": "String", + "type": "String[]", "optional": true, "field": "major", "description": "

the major of the hacker

" @@ -1992,7 +1992,7 @@ define({ }, "examples": [{ "title": "Success-Response: ", - "content": "{\n \"message\": \"Hacker found by logged in account id\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"portfolioURL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n \"jobInterest\":\"Internship\",\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"comments\":\"hi!\",\n \"essay\":\"Pls accept me\"\n },\n \"status\":\"Applied\",\n \"ethnicity\":[\"White or Caucasian\",\" Asian or Pacific Islander\"],\n \"accountId\":\"5bff2a35e533b0f6562b4998\",\n \"school\":\"McPherson College\",\n \"gender\":\"Female\",\n \"needsBus\":false,\n \"major\":\"Accounting\",\n \"graduationYear\":2019,\n \"codeOfConduct\":true,\n } \n }", + "content": "{\n \"message\": \"Hacker found by logged in account id\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"portfolioURL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n \"jobInterest\":\"Internship\",\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"comments\":\"hi!\",\n \"essay\":\"Pls accept me\"\n },\n \"status\":\"Applied\",\n \"ethnicity\":[\"White or Caucasian\",\" Asian or Pacific Islander\"],\n \"accountId\":\"5bff2a35e533b0f6562b4998\",\n \"school\":\"McPherson College\",\n \"gender\":\"Female\",\n \"needsBus\":false,\n \"major\":[\"Accounting\"],\n \"graduationYear\":2019,\n \"codeOfConduct\":true,\n } \n }", "type": "object" }] }, diff --git a/docs/api/api_data.json b/docs/api/api_data.json index 75ac6685..49adf889 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -1166,7 +1166,7 @@ }, { "group": "body", - "type": "String", + "type": "String[]", "optional": false, "field": "major", "description": "

the major of the hacker

" @@ -1550,7 +1550,7 @@ }, { "group": "body", - "type": "String", + "type": "String[]", "optional": true, "field": "major", "description": "

the major of the hacker

" @@ -1991,7 +1991,7 @@ }, "examples": [{ "title": "Success-Response: ", - "content": "{\n \"message\": \"Hacker found by logged in account id\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"portfolioURL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n \"jobInterest\":\"Internship\",\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"comments\":\"hi!\",\n \"essay\":\"Pls accept me\"\n },\n \"status\":\"Applied\",\n \"ethnicity\":[\"White or Caucasian\",\" Asian or Pacific Islander\"],\n \"accountId\":\"5bff2a35e533b0f6562b4998\",\n \"school\":\"McPherson College\",\n \"gender\":\"Female\",\n \"needsBus\":false,\n \"major\":\"Accounting\",\n \"graduationYear\":2019,\n \"codeOfConduct\":true,\n } \n }", + "content": "{\n \"message\": \"Hacker found by logged in account id\", \n \"data\": {\n \"id\":\"5bff4d736f86be0a41badb91\",\n \"application\":{\n \"portfolioURL\":{\n \"resume\":\"resumes/1543458163426-5bff4d736f86be0a41badb91\",\n \"github\":\"https://github.com/abcd\",\n \"dropler\":\"https://dribbble.com/abcd\",\n \"personal\":\"https://www.hi.com/\",\n \"linkedIn\":\"https://linkedin.com/in/abcd\",\n \"other\":\"https://github.com/hackmcgill/hackerAPI/issues/168\"\n },\n \"jobInterest\":\"Internship\",\n \"skills\":[\"Javascript\",\"Typescript\"],\n \"comments\":\"hi!\",\n \"essay\":\"Pls accept me\"\n },\n \"status\":\"Applied\",\n \"ethnicity\":[\"White or Caucasian\",\" Asian or Pacific Islander\"],\n \"accountId\":\"5bff2a35e533b0f6562b4998\",\n \"school\":\"McPherson College\",\n \"gender\":\"Female\",\n \"needsBus\":false,\n \"major\":[\"Accounting\"],\n \"graduationYear\":2019,\n \"codeOfConduct\":true,\n } \n }", "type": "object" }] }, diff --git a/docs/api/api_project.js b/docs/api/api_project.js index a30d316c..ae37792b 100644 --- a/docs/api/api_project.js +++ b/docs/api/api_project.js @@ -9,7 +9,7 @@ define({ "apidoc": "0.3.0", "generator": { "name": "apidoc", - "time": "2019-02-02T19:22:47.311Z", + "time": "2019-02-11T16:09:25.604Z", "url": "http://apidocjs.com", "version": "0.17.7" } diff --git a/docs/api/api_project.json b/docs/api/api_project.json index 149ba493..0dfb71f7 100644 --- a/docs/api/api_project.json +++ b/docs/api/api_project.json @@ -9,7 +9,7 @@ "apidoc": "0.3.0", "generator": { "name": "apidoc", - "time": "2019-02-02T19:22:47.311Z", + "time": "2019-02-11T16:09:25.604Z", "url": "http://apidocjs.com", "version": "0.17.7" } diff --git a/routes/api/hacker.js b/routes/api/hacker.js index e1233416..2ce81ad9 100644 --- a/routes/api/hacker.js +++ b/routes/api/hacker.js @@ -89,7 +89,7 @@ module.exports = { * @apiParam (body) {String} gender Gender of the hacker * @apiParam (body) {Boolean} needsBus Whether the hacker requires a bus for transportation * @apiParam (body) {String[]} ethnicity the ethnicities of the hacker - * @apiParam (body) {String} major the major of the hacker + * @apiParam (body) {String[]} major the major of the hacker * @apiParam (body) {Number} graduationYear the graduation year of the hacker * @apiParam (body) {Boolean} codeOfConduct acceptance of the code of conduct * @apiParam (body) {Json} application The hacker's application. Resume and jobInterest fields are required. @@ -291,7 +291,7 @@ module.exports = { * @apiParam (body) {String} [gender] Gender of the hacker * @apiParam (body) {Boolean} [needsBus] Whether the hacker requires a bus for transportation * @apiParam (body) {String[]} [ethnicity] the ethnicities of the hacker - * @apiParam (body) {String} [major] the major of the hacker + * @apiParam (body) {String[]} [major] the major of the hacker * @apiParam (body) {Number} [graduationYear] the graduation year of the hacker * @apiParam (body) {Json} [application] The hacker's application * @apiParamExample {Json} application: From ef6e4b43ef0f3004efa2d396f2a9f6579eef7ea0 Mon Sep 17 00:00:00 2001 From: Pierre Theo Klein Date: Sat, 16 Feb 2019 18:21:19 -0500 Subject: [PATCH 3/3] Fix majors valdiation for edit --- middlewares/validators/hacker.validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middlewares/validators/hacker.validator.js b/middlewares/validators/hacker.validator.js index 63651371..6728a9f6 100644 --- a/middlewares/validators/hacker.validator.js +++ b/middlewares/validators/hacker.validator.js @@ -29,7 +29,7 @@ module.exports = { VALIDATOR.booleanValidator("body", "needsBus", true), VALIDATOR.applicationValidator("body", "application", true), VALIDATOR.alphaArrayValidator("body", "ethnicity", true), - VALIDATOR.stringValidator("body", "major", true), + VALIDATOR.alphaArrayValidator("body", "major", true), VALIDATOR.integerValidator("body", "graduationYear", true, 2019, 2030), ], updateStatusValidator: [