From 76ec217cdcd4d3694aee9cbd58513933ace74cf5 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Sat, 15 Dec 2018 17:27:16 -0500 Subject: [PATCH 1/2] allow booleanValidator to take comparator value for codeOfConduct --- middlewares/validators/hacker.validator.js | 2 +- middlewares/validators/validator.helper.js | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/middlewares/validators/hacker.validator.js b/middlewares/validators/hacker.validator.js index cbe2b984..bf90c54f 100644 --- a/middlewares/validators/hacker.validator.js +++ b/middlewares/validators/hacker.validator.js @@ -13,7 +13,7 @@ module.exports = { VALIDATOR.alphaArrayValidator("body", "ethnicity", false), VALIDATOR.nameValidator("body", "major", false), VALIDATOR.integerValidator("body", "graduationYear", false, 2019, 2030), - VALIDATOR.booleanValidator("body", "codeOfConduct", false), + VALIDATOR.booleanValidator("body", "codeOfConduct", false, true), ], updateConfirmationValidator: [ diff --git a/middlewares/validators/validator.helper.js b/middlewares/validators/validator.helper.js index 1d5dcbfa..4237d645 100644 --- a/middlewares/validators/validator.helper.js +++ b/middlewares/validators/validator.helper.js @@ -103,19 +103,29 @@ function mongoIdArrayValidator(fieldLocation, fieldname, optional = true) { } /** - * Validates that field must be boolean. + * Validates that field must be boolean. Optionally checks for desired boolean * @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 booleanValidator(fieldLocation, fieldname, optional = true) { +function booleanValidator(fieldLocation, fieldname, optional = true, desire = null) { const booleanField = setProperValidationChainBuilder(fieldLocation, fieldname, "invalid boolean"); if (optional) { // do not use check falsy option as a 'false' boolean will be skipped - return booleanField.optional().isBoolean().withMessage("must be boolean"); + return booleanField.optional().isBoolean().withMessage("must be boolean").custom((val) => { + if (desire !== null) { + return desire === val; + } + return true; + }).withMessage(`Must be equal to ${desire}`); } else { - return booleanField.exists().isBoolean().withMessage("must be boolean"); + return booleanField.exists().isBoolean().withMessage("must be boolean").custom((val) => { + if (desire !== null) { + return desire === val; + } + return true; + }).withMessage(`Must be equal to ${desire}`); } } From 6080057d0b051578152ac4c5e8ae628056b82834 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Sat, 15 Dec 2018 17:27:30 -0500 Subject: [PATCH 2/2] Create tests for false codeOfConduct in hacker --- tests/hacker.test.js | 27 +++++++++++++++++++++++++++ tests/util/hacker.test.util.js | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/tests/hacker.test.js b/tests/hacker.test.js index 8b18025d..5cefc53a 100644 --- a/tests/hacker.test.js +++ b/tests/hacker.test.js @@ -36,6 +36,9 @@ const storedAccount2 = util.account.Account2; const storedHacker2 = util.hacker.HackerB; const newHacker1 = util.hacker.newHacker1; +// badConductHacker1 is the same as newHacker1, even linking to the same account +// the difference is that badConductHacker1 does not accept the code of conducts +const badConductHacker1 = util.hacker.badCodeOfConductHacker1; const newHackerAccount1 = util.account.allAccounts[13]; const newHacker2 = util.hacker.newHacker2; @@ -288,6 +291,30 @@ describe("POST create hacker", function () { }); }); + // should fail due to 'false' on code of conduct + it("should FAIL if the new hacker does not accept code of conduct", function (done) { + util.auth.login(agent, newHackerAccount1, (error) => { + if (error) { + agent.close(); + return done(error); + } + return agent + .post(`/api/hacker/`) + .type("application/json") + .send(badConductHacker1) + .end(function (err, res) { + res.should.have.status(422); + res.should.be.json; + res.body.should.have.property("message"); + res.body.message.should.equal("Validation failed"); + res.body.should.have.property("data"); + res.body.data.should.have.property("codeOfConduct"); + res.body.data.codeOfConduct.msg.should.equal("Must be equal to true"); + done(); + }); + }); + }); + // fail on unconfirmed account, using admin it("should FAIL to create a new hacker if the account hasn't been confirmed", function (done) { util.auth.login(agent, Admin1, (error) => { diff --git a/tests/util/hacker.test.util.js b/tests/util/hacker.test.util.js index 8f32ff44..360a80e2 100644 --- a/tests/util/hacker.test.util.js +++ b/tests/util/hacker.test.util.js @@ -27,6 +27,32 @@ const invalidHacker1 = { "codeOfConduct": true, }; +// duplicate of newHack1, but with false for code of conduct +const badCodeOfConductHacker1 = { + "accountId": Util.Account.generatedAccounts[6]._id, + "school": "University of ASDF", + "degree": "Masters", + "gender": "Female", + "needsBus": true, + "application": { + "portfolioURL": { + //gcloud bucket link + "resume": "www.gcloud.com/myResume100", + "github": "www.github.com/Person1", + "dropler": undefined, + "personal": "www.person1.com", + "linkedIn": "www.linkedin.com/in/Person1", + "other": undefined + }, + "jobInterest": "Full-time", + "skills": ["CSS", "HTML", "JS"], + }, + "ethnicity": ["Caucasian"], + "major": "EE", + "graduationYear": 2019, + "codeOfConduct": false, +}; + const duplicateAccountLinkHacker1 = { "_id": mongoose.Types.ObjectId(), "accountId": Util.Account.Account1._id, @@ -195,6 +221,7 @@ module.exports = { invalidHacker1: invalidHacker1, newHacker1: newHacker1, newHacker2: newHacker2, + badCodeOfConductHacker1: badCodeOfConductHacker1, HackerA: HackerA, HackerB: HackerB, HackerC: HackerC,