diff --git a/docs/api/api_data.js b/docs/api/api_data.js index 25e0c5a6..36f55a34 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -62,8 +62,8 @@ define({ "api": [ "group": "body", "type": "String", "optional": false, - "field": "birthDate", - "description": "

a Date parsable string.

" + "field": "age", + "description": "

The user's age.

" }, { "group": "body", @@ -86,7 +86,7 @@ define({ "api": [ "examples": [ { "title": "Request-Example:", - "content": "{ \n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"password\":\"hunter2\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"birthDate\":\"10/30/1997\"\n}", + "content": "{ \n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"password\":\"hunter2\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"age\":23,\n}", "type": "json" } ] @@ -113,7 +113,7 @@ define({ "api": [ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account creation successful\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account creation successful\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -195,7 +195,7 @@ define({ "api": [ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account found by user id\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account found by user id\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -379,7 +379,7 @@ define({ "api": [ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account found by user email\", \n \"data\": {\n \t\"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account found by user email\", \n \"data\": {\n \t\"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -466,10 +466,10 @@ define({ "api": [ }, { "group": "body", - "type": "String", + "type": "Number", "optional": true, - "field": "birthDate", - "description": "

A Date parsable string.

" + "field": "age", + "description": "

The user's age.

" }, { "group": "body", @@ -517,7 +517,7 @@ define({ "api": [ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account update successful.\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\": \"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account update successful.\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\": \"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] diff --git a/docs/api/api_data.json b/docs/api/api_data.json index cfc8a3ab..685b3dec 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -60,10 +60,10 @@ }, { "group": "body", - "type": "String", + "type": "Number", "optional": false, - "field": "birthDate", - "description": "

a Date parsable string.

" + "field": "age", + "description": "

The user's age.

" }, { "group": "body", @@ -86,7 +86,7 @@ "examples": [ { "title": "Request-Example:", - "content": "{ \n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"password\":\"hunter2\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"birthDate\":\"10/30/1997\"\n}", + "content": "{ \n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"password\":\"hunter2\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"age\":23,\n}", "type": "json" } ] @@ -113,7 +113,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account creation successful\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account creation successful\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -195,7 +195,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account found by user id\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account found by user id\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -379,7 +379,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account found by user email\", \n \"data\": {\n \t\"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account found by user email\", \n \"data\": {\n \t\"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\":\"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] @@ -466,10 +466,10 @@ }, { "group": "body", - "type": "String", + "type": "Number", "optional": true, - "field": "birthDate", - "description": "

A Date parsable string.

" + "field": "age", + "description": "

The user's age.

" }, { "group": "body", @@ -517,7 +517,7 @@ "examples": [ { "title": "Success-Response: ", - "content": "{\n \"message\": \"Account update successful.\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\": \"Male\",\n \"birthDate\":Date(\"10/30/1997\")\n }\n }", + "content": "{\n \"message\": \"Account update successful.\", \n \"data\": {\n \"id\": ObjectId(\"5bff8b9f3274cf001bc71048\"),\n \t\"firstName\": \"Theo\",\n \"lastName\":\"Klein\",\n \"pronoun\":\"he/him\",\n \"email\":\"theo@klein.com\",\n \"phoneNumber\":1234567890,\n \t\"gender\": \"Male\",\n \"age\":23,\n }\n }", "type": "object" } ] diff --git a/docs/standards.md b/docs/standards.md index 08be5dc4..ea7c5bf4 100644 --- a/docs/standards.md +++ b/docs/standards.md @@ -352,7 +352,7 @@ module.exports = { VALIDATOR.regexValidator("body", "email", true, Constants.EMAIL_REGEX), VALIDATOR.alphaArrayValidator("body", "dietaryRestrictions", true), VALIDATOR.enumValidator("body", "shirtSize", Constants.SHIRT_SIZES, true), - VALIDATOR.dateValidator("body", "birthDate", true), + VALIDATOR.ageValidator("body", "age", true), VALIDATOR.phoneNumberValidator("body", "phoneNumber", true) ], }; diff --git a/middlewares/account.middleware.js b/middlewares/account.middleware.js index c57f9dfb..95763e02 100644 --- a/middlewares/account.middleware.js +++ b/middlewares/account.middleware.js @@ -55,7 +55,7 @@ function parseAccount(req, res, next) { password: Services.Account.hashPassword(req.body.password), dietaryRestrictions: req.body.dietaryRestrictions, gender: req.body.gender, - birthDate: req.body.birthDate, + age: req.body.age, phoneNumber: req.body.phoneNumber }; @@ -67,7 +67,7 @@ function parseAccount(req, res, next) { delete req.body.password; delete req.body.dietaryRestrictions; delete req.body.gender; - delete req.body.birthDate; + delete req.body.age; delete req.body.phoneNumber; req.body.accountDetails = accountDetails; diff --git a/middlewares/validators/account.validator.js b/middlewares/validators/account.validator.js index 51ada35b..b20a8221 100644 --- a/middlewares/validators/account.validator.js +++ b/middlewares/validators/account.validator.js @@ -18,7 +18,7 @@ module.exports = { process.env.JWT_CONFIRM_ACC_SECRET, true ), - VALIDATOR.dateValidator("body", "birthDate", false), + VALIDATOR.ageValidator("body", "age", false), VALIDATOR.phoneNumberValidator("body", "phoneNumber", true) ], updateAccountValidator: [ @@ -29,7 +29,7 @@ module.exports = { VALIDATOR.regexValidator("body", "email", true, Constants.EMAIL_REGEX), VALIDATOR.alphaArrayValidator("body", "dietaryRestrictions", true), VALIDATOR.stringValidator("body", "gender", true), - VALIDATOR.dateValidator("body", "birthDate", true), + VALIDATOR.ageValidator("body", "age", true), VALIDATOR.phoneNumberValidator("body", "phoneNumber", true) ], inviteAccountValidator: [ diff --git a/middlewares/validators/hacker.validator.js b/middlewares/validators/hacker.validator.js index 50078261..0199e2bd 100644 --- a/middlewares/validators/hacker.validator.js +++ b/middlewares/validators/hacker.validator.js @@ -251,6 +251,11 @@ module.exports = { "application.other.ethnicity", false ), + VALIDATOR.stringValidator( + "body", + "application.other.country", + false + ), VALIDATOR.booleanValidator( "body", "application.other.privacyPolicy", diff --git a/middlewares/validators/validator.helper.js b/middlewares/validators/validator.helper.js index 5e293648..54d0b7e8 100644 --- a/middlewares/validators/validator.helper.js +++ b/middlewares/validators/validator.helper.js @@ -392,6 +392,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) { shirtSize: false, other: false, ethnicity: false, + country: false, codeOfConduct: false, privacyPolicy: false }; @@ -439,6 +440,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) { hasValid.other = app.hasOwnProperty("other"); if (hasValid.other) { hasValid.ethnicity = app.other.hasOwnProperty("ethnicity"); + hasValid.country = app.other.hasOwnProperty("country"); hasValid.codeOfConduct = app.other.hasOwnProperty( "codeOfConduct" ); @@ -497,6 +499,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) { hasValid.shirtSize && hasValid.other && hasValid.ethnicity && + hasValid.country && hasValid.privacyPolicy && hasValid.codeOfConduct ); @@ -545,6 +548,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) { hasValid.other = app.hasOwnProperty("other"); if (hasValid.other) { hasValid.ethnicity = app.other.hasOwnProperty("ethnicity"); + hasValid.country = app.other.hasOwnProperty("country"); hasValid.codeOfConduct = app.other.hasOwnProperty( "codeOfConduct" ); @@ -603,6 +607,7 @@ function applicationValidator(fieldLocation, fieldname, optional = true) { hasValid.shirtSize && hasValid.other && hasValid.ethnicity && + hasValid.country && hasValid.privacyPolicy && hasValid.codeOfConduct ); @@ -839,6 +844,50 @@ function dateValidator(fieldLocation, fieldname, optional = true) { isValid: date }); } +} + +/** + * Validates that field must be a valid age between 0 and 100. + * @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 ageValidator(fieldLocation, fieldname, optional = true) { + const age = setProperValidationChainBuilder( + fieldLocation, + fieldname, + "Invalid age" + ); + if (optional) { + return age + .optional({ + checkFalsy: true + }) + .custom((value) => { + // Check if the value is empty or undefined + if (!value) return true; // Allow empty values if optional + + // Validate age: must be a number between 0 and 100 + const ageNumber = Number(value); + return !isNaN(ageNumber) && ageNumber >= 0 && ageNumber <= 100; + }) + .withMessage({ + message: "Age is not valid. It must be between 0 and 100.", + isValid: age + }); + } else { + return age + .exists() + .withMessage("Age field must be specified") // Ensure field exists + .custom((value) => { + const ageNumber = Number(value); + return !isNaN(ageNumber) && ageNumber >= 0 && ageNumber <= 100; + }) + .withMessage({ + message: "Age is not valid. It must be between 0 and 100.", + isValid: age + }); + } } /** @@ -1027,6 +1076,7 @@ module.exports = { searchSortValidator: searchSortValidator, phoneNumberValidator: phoneNumberValidator, dateValidator: dateValidator, + ageValidator: ageValidator, enumValidator: enumValidator, routesValidator: routesValidator, stringValidator: stringValidator diff --git a/models/account.model.js b/models/account.model.js index 047c8bc0..fe83490f 100644 --- a/models/account.model.js +++ b/models/account.model.js @@ -46,8 +46,8 @@ const AccountSchema = new mongoose.Schema({ enum: Constants.EXTENDED_USER_TYPES, default: Constants.HACKER }, - birthDate: { - type: Date, + age: { + type: Number, required: true }, phoneNumber: { @@ -85,15 +85,16 @@ AccountSchema.methods.isSponsor = function() { this.accountType == Constants.SPONSOR ); }; + /** - * Calculates the user's age + * CHANGED BIRTHDATE TO AGE - Calculates the user's age */ -AccountSchema.methods.getAge = function() { - // birthday is a date - var ageDifMs = Date.now() - this.birthDate.getTime(); - var ageDate = new Date(ageDifMs); // miliseconds from epoch - return Math.abs(ageDate.getUTCFullYear() - 1970); -}; +// AccountSchema.methods.getAge = function() { +// // birthday is a date +// var ageDifMs = Date.now() - this.birthDate.getTime(); +// var ageDate = new Date(ageDifMs); // miliseconds from epoch +// return Math.abs(ageDate.getUTCFullYear() - 1970); +// }; //export the model module.exports = mongoose.model("Account", AccountSchema); diff --git a/models/hacker.model.js b/models/hacker.model.js index 291964e3..1b9fe608 100644 --- a/models/hacker.model.js +++ b/models/hacker.model.js @@ -103,6 +103,10 @@ const HackerSchema = new mongoose.Schema({ ], required: true }, + country: { + type: String, + required: true + }, privacyPolicy: { type: Boolean, required: true diff --git a/package-lock.json b/package-lock.json index e7587c64..b9331981 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-prettier": "5.1.3", - "mocha": "^10.0.0", + "mocha": "^10.2.0", "nodemon": "^3.0.2", "prettier": "3.1.1" } diff --git a/package.json b/package.json index cbc503c5..39c9d070 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,12 @@ "private": true, "scripts": { "start": "DEBUG=hackboard:* NODE_ENV=development nodemon --ignore gcp_creds.json ./bin/www.js", - "start-windows": "set DEBUG=hackboard:* && set NODE_ENV=development && nodemon --ignore gcp_creds.json ./bin/www.js", + "start-windows": "set DEBUG=hackboard:* && set NODE_ENV=test && nodemon --ignore gcp_creds.json ./bin/www.js", "deploy": "NODE_ENV=deployment node ./bin/www.js", - "debug": "DEBUG=hackboard:* NODE_ENV=test nodemon --ignore gcp_creds.json ./bin/www.js", - "test": "DEBUG=hackboard:* NODE_ENV=test mocha -r dotenv/config --reporter spec tests/**.js --exit", - "seed": "NODE_ENV=test node ./seed/index.js", + "debug": "DEBUG=hackboard:* NODE_ENV=development nodemon --ignore gcp_creds.json ./bin/www.js", + "test": "DEBUG=hackboard:* NODE_ENV=development mocha -r dotenv/config --reporter spec tests/**.js --exit", + "test-windows": "DEBUG=hackboard:* SET NODE_ENV=development & mocha -r dotenv/config --reporter spec tests/**.js --exit", + "seed": "NODE_ENV=development node ./seed/index.js", "docs": "apidoc -i ./routes -o ./docs/api/", "format": "prettier --write '**/*.js'", "lint": "eslint --fix '**/*.js'" diff --git a/results.txt b/results.txt new file mode 100644 index 00000000..fb191fef Binary files /dev/null and b/results.txt differ diff --git a/results2.txt b/results2.txt new file mode 100644 index 00000000..d4067efa Binary files /dev/null and b/results2.txt differ diff --git a/routes/api/account.js b/routes/api/account.js index 7a41dbea..9481051b 100644 --- a/routes/api/account.js +++ b/routes/api/account.js @@ -43,7 +43,7 @@ module.exports = { "email":"theo@klein.com", "phoneNumber":1234567890, "gender":"Male", - "birthDate":Date("10/30/1997") + "age":23") } } * @apiError {string} message Error message @@ -72,7 +72,7 @@ module.exports = { * @apiParam (body) {String} gender Gender of the account creator. * @apiParam (body) {String[]} dietaryRestrictions Any dietary restrictions for the user. 'None' if there are no restrictions * @apiParam (body) {String} password The password of the account. - * @apiParam (body) {String} birthDate a Date parsable string. + * @apiParam (body) {Number} age The user's age. * @apiParam (body) {Number} [phoneNumber] the user's phone number, represented as a string. * @apiParam (header) {JWT} [token] the user's invite token. * @@ -85,7 +85,7 @@ module.exports = { "password":"hunter2", "phoneNumber":1234567890, "gender":"Male", - "birthDate":"10/30/1997" + "age:23" * } * * @apiSuccess {string} message Success message @@ -101,7 +101,7 @@ module.exports = { "email":"theo@klein.com", "phoneNumber":1234567890, "gender":"Male", - "birthDate":Date("10/30/1997") + "age:23") } } @@ -212,9 +212,8 @@ module.exports = { * @apiParam (body) {String} [pronoun] The pronoun of the account creator. * @apiParam (body) {String} [email] Email of the account. * @apiParam (body) {String} [gender] Gender of the account creator. - * @apiParam (body) {String} [birthDate] A Date parsable string. + * @apiParam (body) {String} [age] Age of the account creator. * @apiParam (body) {Number} [phoneNumber] The user's phone number, represented as a string. - * @apiParam (body) {String} [birthDate] a Date parsable string. * @apiParam (body) {String[]} [dietaryRestrictions] Any dietary restrictions for the user. 'None' if there are no restrictions * @apiParamExample {json} Request-Example: * { "gender": "Male" } @@ -233,7 +232,7 @@ module.exports = { "email":"theo@klein.com", "phoneNumber":1234567890, "gender": "Male", - "birthDate":Date("10/30/1997") + "age:23") } } @@ -280,7 +279,7 @@ module.exports = { "email":"theo@klein.com", "phoneNumber":1234567890, "gender":"Male", - "birthDate":Date("10/30/1997") + "age:23") } } diff --git a/routes/api/hacker.js b/routes/api/hacker.js index 77cb1d43..8d64c255 100644 --- a/routes/api/hacker.js +++ b/routes/api/hacker.js @@ -56,6 +56,7 @@ module.exports = { }, "status":"Applied", "ethnicity":["White or Caucasian"," Asian or Pacific Islander"], + "country":"Canada", "accountId":"5bff2a35e533b0f6562b4998", "school":"McPherson College", "gender":"Female", @@ -90,6 +91,7 @@ module.exports = { * @apiParam (body) {String} gender Gender of the hacker * @apiParam (body) {Number} travel Whether the hacker requires a bus for transportation * @apiParam (body) {String[]} ethnicity the ethnicities of the hacker + * @apiParam (body) {String} country Name of the country of residence 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 @@ -122,6 +124,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } @@ -170,6 +173,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } @@ -235,6 +239,7 @@ module.exports = { gender: { "Male": 1, "Female": 9 }, travel: { "true": 7, "false": 3 }, ethnicity: { "White": 10, }, + country: {"Canada": 10}, jobInterest: { "Internship": 10 }, major: { "Computer Science": 10 }, graduationYear: { "2019": 10 }, @@ -435,6 +440,7 @@ module.exports = { * @apiParam (body) {String} [gender] Gender of the hacker * @apiParam (body) {Number} [travel] How much the hacker requires a bus for transportation * @apiParam (body) {String[]} [ethnicity] the ethnicities of the hacker + * @apiParam (body) {String} [country] Country of residence 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 @@ -466,6 +472,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } @@ -514,6 +521,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } @@ -591,6 +599,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } @@ -664,6 +673,7 @@ module.exports = { "other:" { "gender": "male", "ethnicity": "Asian or Pacific Islander", + "country": "Canada", "privacyPolicy": true, "codeOfConduct": true, } diff --git a/services/hacker.service.js b/services/hacker.service.js index f47b43da..37531700 100644 --- a/services/hacker.service.js +++ b/services/hacker.service.js @@ -132,6 +132,7 @@ function getStats(hackers) { gender: {}, travel: {}, ethnicity: {}, + country: {}, jobInterest: {}, fieldOfStudy: {}, graduationYear: {}, @@ -177,6 +178,12 @@ function getStats(hackers) { : 1; } + stats.country[hacker.application.other.country] = stats.country[ + hacker.application.other.country + ] + ? stats.country[hacker.application.other.country] + 1 + : 1; + stats.jobInterest[hacker.application.general.jobInterest] = stats .jobInterest[hacker.application.general.jobInterest] ? stats.jobInterest[hacker.application.general.jobInterest] + 1 @@ -201,8 +208,12 @@ function getStats(hackers) { .shirtSize[hacker.application.accommodation.shirtSize] ? stats.shirtSize[hacker.application.accommodation.shirtSize] + 1 : 1; - const age = hacker.accountId.getAge(); - stats.age[age] = stats.age[age] ? stats.age[age] + 1 : 1; + + // CHANGED BIRTHDATE TO AGE + // const age = hacker.accountId.getAge(); + // stats.age[age] = stats.age[age] ? stats.age[age] + 1 : 1; + + stats.age[hacker.accountId.age] = stats.age[hacker.accountId.age] ? stats.age[age] + 1 : 1; const applicationDate = hacker._id .getTimestamp() // diff --git a/tests/hacker.test.js b/tests/hacker.test.js index 6bd7bc69..b344e86d 100644 --- a/tests/hacker.test.js +++ b/tests/hacker.test.js @@ -1739,6 +1739,7 @@ describe("GET Hacker stats", function() { res.body.data.stats.should.have.property("gender"); res.body.data.stats.should.have.property("travel"); res.body.data.stats.should.have.property("ethnicity"); + res.body.data.stats.should.have.property("country"); res.body.data.stats.should.have.property("jobInterest"); res.body.data.stats.should.have.property("fieldOfStudy"); res.body.data.stats.should.have.property("graduationYear"); diff --git a/tests/util/account.test.util.js b/tests/util/account.test.util.js index ec521dee..4e8655f5 100644 --- a/tests/util/account.test.util.js +++ b/tests/util/account.test.util.js @@ -83,8 +83,9 @@ function generateRandomValue(atr) { return Constants.EXTENDED_USER_TYPES[ Math.floor(Math.random() * Constants.EXTENDED_USER_TYPES.length) ]; - case "birthDate": - return new Date(); + case "age": + // Generate a random age between 0 and 100 + return Math.floor(Math.random() * 101); // 0 to 100 case "phoneNumber": return Math.floor(Math.random() * 10000000000); } @@ -264,7 +265,7 @@ const waitlistedHacker0 = { gender: "Male", confirmed: true, accountType: Constants.HACKER, - birthDate: "1990-01-04", + age: 23, phoneNumber: 1000000004 }; @@ -280,7 +281,7 @@ const NonConfirmedAccount1 = { dietaryRestrictions: ["something1", "something2"], gender: "Male", confirmed: false, - birthDate: "1980-07-30", + age: 23, phoneNumber: 1001230236, accountType: Constants.HACKER }; @@ -315,7 +316,7 @@ const NoPhoneHackerAccount0 = { dietaryRestrictions: ["something1", "something2"], gender: "Male", confirmed: false, - birthDate: "1980-07-30", + age: "23", accountType: Constants.HACKER }; diff --git a/tests/util/hacker.test.util.js b/tests/util/hacker.test.util.js index 1eb310cb..98e36a1a 100644 --- a/tests/util/hacker.test.util.js +++ b/tests/util/hacker.test.util.js @@ -39,6 +39,7 @@ const TeamHacker0 = { }, other: { ethnicity: ["Native American"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -81,6 +82,7 @@ const TeamHacker1 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -123,6 +125,7 @@ const TeamHacker2 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -165,6 +168,7 @@ const TeamHacker3 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -207,6 +211,7 @@ const TeamHacker4 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -249,6 +254,7 @@ const NoTeamHacker0 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -288,6 +294,7 @@ const newHacker0 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -327,6 +334,7 @@ const newHacker1 = { }, other: { ethnicity: ["African American"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -367,6 +375,7 @@ const invalidHacker0 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", // must accept code of conduct to be valid codeOfConduct: false, privacyPolicy: false @@ -404,6 +413,7 @@ const invalidHacker1 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -446,6 +456,7 @@ const invalidHacker2 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -487,6 +498,7 @@ const invalidHacker3 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -529,6 +541,7 @@ const duplicateAccountLinkHacker0 = { }, other: { ethnicity: ["Caucasian"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -570,6 +583,7 @@ const waitlistedHacker0 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -612,6 +626,7 @@ const unconfirmedAccountHacker0 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true }, @@ -653,6 +668,7 @@ const unconfirmedAccountHacker1 = { }, other: { ethnicity: ["European"], + country: "Canada", codeOfConduct: true, privacyPolicy: true },