From 90fcca45c2c3460abc0fd1249e19e23b54c8af41 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Thu, 3 Jan 2019 10:41:17 -0500 Subject: [PATCH 01/11] Add routes and roles --- constants/role.constant.js | 3 +++ constants/routes.constant.js | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/constants/role.constant.js b/constants/role.constant.js index bee2a6f2..34c1dedd 100644 --- a/constants/role.constant.js +++ b/constants/role.constant.js @@ -41,6 +41,7 @@ const hackerRole = { Constants.Routes.hackerRoutes.getSelf, Constants.Routes.teamRoutes.join, + Constants.Routes.teamRoutes.get ] }; @@ -52,6 +53,8 @@ const volunteerRole = { Constants.Routes.hackerRoutes.patchAnyCheckInById, Constants.Routes.hackerRoutes.patchSelfCheckInById, + + Constants.Routes.teamRoutes.get ] }; diff --git a/constants/routes.constant.js b/constants/routes.constant.js index 224e915c..ab0b9499 100644 --- a/constants/routes.constant.js +++ b/constants/routes.constant.js @@ -138,13 +138,9 @@ const sponsorRoutes = { }; const teamRoutes = { - "getSelfById": { - requestType: Constants.REQUEST_TYPES.GET, - uri: "/api/team/" + Constants.ROLE_CATEGORIES.SELF, - }, - "getAnyById": { + "get": { requestType: Constants.REQUEST_TYPES.GET, - uri: "/api/team/" + Constants.ROLE_CATEGORIES.ALL, + uri: "/api/team/" }, "post": { requestType: Constants.REQUEST_TYPES.POST, From 9c2277e44356db91542b9f93c831190ddad5d80f Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Thu, 3 Jan 2019 10:41:30 -0500 Subject: [PATCH 02/11] add showTeam with member names --- controllers/team.controller.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/controllers/team.controller.js b/controllers/team.controller.js index 3e5ab3a0..d84d9acd 100644 --- a/controllers/team.controller.js +++ b/controllers/team.controller.js @@ -19,9 +19,27 @@ const Constants = { * @description Returns the JSON of team object located in req.body.team */ function showTeam(req, res) { + const teamData = req.body.team.toJSON(); + delete teamData.members; + + const memberNames = []; + for (const member of req.body.teamMembers) { + const strippedMemberJSON = member.toStrippedJSON(); + + const memberName = { + "firstName": strippedMemberJSON.firstName, + "lastName": strippedMemberJSON.lastName, + }; + + memberNames.push(memberName); + } + return res.status(200).json({ message: Constants.Success.TEAM_READ, - data: req.body.team.toJSON() + data: { + team: teamData, + members: memberNames, + } }); } From 88080a5f0dd62949380fe584ca2b6929804c2db9 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Thu, 3 Jan 2019 10:43:54 -0500 Subject: [PATCH 03/11] create tests --- tests/team.test.js | 62 +++++++++++++++++++++++++++++---- tests/util/account.test.util.js | 10 +++--- tests/util/team.test.util.js | 1 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/tests/team.test.js b/tests/team.test.js index d48cae35..f6c63d58 100644 --- a/tests/team.test.js +++ b/tests/team.test.js @@ -21,21 +21,71 @@ const Constants = { const agent = chai.request.agent(server.app); describe("GET team", function () { - it("should SUCCEED and list a team's information from /api/team/:id GET", function (done) { + it("should FAIL to list a team's information due to lack of authentication", function (done) { chai.request(server.app) - .get(`/api/team/` + util.team.Team1._id) + .get(`/api/team/`) + .type("application/json") + .send({ + id: util.team.Team3._id + }) .end(function (err, res) { - res.should.have.status(200); + res.should.have.status(401); res.should.be.json; res.body.should.have.property("message"); - res.body.message.should.equal(Constants.Success.TEAM_READ); + res.body.message.should.equal(Constants.Error.AUTH_401_MESSAGE); res.body.should.have.property("data"); - let team = new Team(util.team.Team1); - chai.assert.equal(JSON.stringify(res.body.data), JSON.stringify(team.toJSON())); done(); }); }); + + it("should Fail and list a team's information from /api/team/ GET due to non existant team id", function (done) { + util.auth.login(agent, util.account.Hacker4, (error) => { + if (error) { + agent.close(); + return done(error); + } + return agent + .get(`/api/team/`) + .type("application/json") + .send({ + id: util.team.newTeam1._id + }) + .end(function (err, res) { + res.should.have.status(404); + res.should.be.json; + res.body.should.have.property("message"); + res.body.message.should.equal(Constants.Error.TEAM_404_MESSAGE); + res.body.should.have.property("data"); + + done(); + }); + }); + }); + + it("should SUCCEED and list a team's information from /api/team/ GET", function (done) { + util.auth.login(agent, util.account.Hacker3, (error) => { + if (error) { + agent.close(); + return done(error); + } + return agent + .get(`/api/team/`) + .type("application/json") + .send({ + id: util.team.Team3._id + }) + .end(function (err, res) { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property("message"); + res.body.message.should.equal(Constants.Success.TEAM_READ); + res.body.should.have.property("data"); + + done(); + }); + }); + }); }); describe("POST create team", function () { diff --git a/tests/util/account.test.util.js b/tests/util/account.test.util.js index 872d8fd8..d5628a57 100644 --- a/tests/util/account.test.util.js +++ b/tests/util/account.test.util.js @@ -152,7 +152,7 @@ const NonConfirmedAccount2 = { const Hacker3 = { "_id": mongoose.Types.ObjectId(), "firstName": "abcd", - "lastName": "defg", + "lastName": "defg3", "pronoun": "They/Them", "email": "abc.def7@blahblah.com", "password": "probsShouldBeHashed2", @@ -167,7 +167,7 @@ const Hacker3 = { const Hacker4 = { "_id": mongoose.Types.ObjectId(), "firstName": "abcd", - "lastName": "defg", + "lastName": "defg4", "pronoun": "They/Them", "email": "abc.def.hacker4@blahblah.com", "password": "probsShouldBeHashed2", @@ -181,7 +181,7 @@ const Hacker4 = { const Hacker5 = { "_id": mongoose.Types.ObjectId(), "firstName": "abcd", - "lastName": "defg", + "lastName": "defg5", "pronoun": "They/Them", "email": "abc.def.hacker5@blahblah.com", "password": "probsShouldBeHashed2", @@ -195,7 +195,7 @@ const Hacker5 = { const Hacker6 = { "_id": mongoose.Types.ObjectId(), "firstName": "abcd", - "lastName": "defg", + "lastName": "defg6", "pronoun": "They/Them", "email": "abc.def.hacker6@blahblah.com", "password": "probsShouldBeHashed2", @@ -209,7 +209,7 @@ const Hacker6 = { const Hacker7 = { "_id": mongoose.Types.ObjectId(), "firstName": "abcd", - "lastName": "defg", + "lastName": "defg7", "pronoun": "They/Them", "email": "abc.def.hacker7@blahblah.com", "password": "probsShouldBeHashed2", diff --git a/tests/util/team.test.util.js b/tests/util/team.test.util.js index abbe81ea..0fc98a90 100644 --- a/tests/util/team.test.util.js +++ b/tests/util/team.test.util.js @@ -7,6 +7,7 @@ const mongoose = require("mongoose"); const logger = require("../../services/logger.service"); const newTeam1 = { + "_id": mongoose.Types.ObjectId(), "name": "BronzeTeam", "members": [Util.Hacker.HackerB._id], "projectName": "YetAnotherProject" From 1c40d0c94aef119e6d39e916f08e340260a5d61f Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Thu, 3 Jan 2019 10:44:34 -0500 Subject: [PATCH 04/11] Create middleware to display member names and add auth --- middlewares/team.middleware.js | 41 +++++++++++++++++++++++- middlewares/validators/team.validator.js | 4 +++ routes/api/team.js | 8 +++-- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/middlewares/team.middleware.js b/middlewares/team.middleware.js index 1619424f..19c9cb60 100644 --- a/middlewares/team.middleware.js +++ b/middlewares/team.middleware.js @@ -5,7 +5,8 @@ const mongoose = require("mongoose"); const Services = { Logger: require("../services/logger.service"), Team: require("../services/team.service"), - Hacker: require("../services/hacker.service") + Hacker: require("../services/hacker.service"), + Account: require("../services/account.service"), }; const Util = require("./util.middleware"); const Constants = { @@ -185,6 +186,43 @@ async function findById(req, res, next) { next(); } +async function findMembersNames(req, res, next) { + const team = req.body.team; + + if (!team) { + return res.status(404).json({ + message: Constants.Error.TEAM_404_MESSAGE, + data: {} + }); + } + + let teamMembers = []; + + for (const memberId of team.members) { + const hacker = await Services.Hacker.findById(memberId); + + if (!hacker) { + return res.status(404).json({ + message: Constants.Error.TEAM_404_MESSAGE, + data: memberId + }); + } + const acc = await Services.Account.findById(hacker.accountId); + + if (!acc) { + return res.status(404).json({ + message: Constants.Error.ACCOUNT_404_MESSAGE, + data: hacker.accountId, + }); + } + + teamMembers.push(acc); + } + + req.body.teamMembers = teamMembers; + return next(); +} + /** * @function parseTeam * @param {{body: {name: string, members: Object[], devpostURL: string, projectName: string}}} req @@ -221,4 +259,5 @@ module.exports = { ensureUniqueHackerId: Util.asyncMiddleware(ensureUniqueHackerId), ensureSpace: Util.asyncMiddleware(ensureSpace), updateHackerTeam: Util.asyncMiddleware(updateHackerTeam), + findMembersNames: Util.asyncMiddleware(findMembersNames), }; \ No newline at end of file diff --git a/middlewares/validators/team.validator.js b/middlewares/validators/team.validator.js index da38c675..73057aad 100644 --- a/middlewares/validators/team.validator.js +++ b/middlewares/validators/team.validator.js @@ -13,5 +13,9 @@ module.exports = { joinTeamValidator: [ VALIDATOR.asciiValidator("body", "teamName", false), + ], + + getTeamValidator: [ + VALIDATOR.mongoIdValidator("body", "id", false), ] }; \ No newline at end of file diff --git a/routes/api/team.js b/routes/api/team.js index 1add551b..44f387bf 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -113,11 +113,15 @@ module.exports = { * @apiErrorExample {object} Error-Response: * {"message": "Team not found", "data": {}} */ - teamRouter.route("/:id").get( - Middleware.Validator.RouteParam.idValidator, + teamRouter.route("/").get( + Middleware.Auth.ensureAuthenticated(), + Middleware.Auth.ensureAuthorized(), + + Middleware.Validator.Team.getTeamValidator, Middleware.parseBody.middleware, Middleware.Team.findById, + Middleware.Team.findMembersNames, Controllers.Team.showTeam ); From 0cd66eb85984eed93c1bc40ee11f5e86de0d0fcd Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Thu, 3 Jan 2019 10:49:27 -0500 Subject: [PATCH 05/11] documentation and function commenting --- docs/api/api_data.js | 14 +++++++------- docs/api/api_data.json | 14 +++++++------- docs/api/api_project.js | 30 +++++++++++++++--------------- docs/api/api_project.json | 30 +++++++++++++++--------------- middlewares/team.middleware.js | 8 ++++++++ routes/api/team.js | 4 ++-- 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/docs/api/api_data.js b/docs/api/api_data.js index ba617857..b2c3cd4d 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -2209,19 +2209,19 @@ define({ }, { "type": "get", - "url": "/team/:id", + "url": "/team/", "title": "get a team's information", "name": "getTeam", "group": "Team", "version": "0.0.8", "parameter": { "fields": { - "param": [{ - "group": "param", - "type": "ObjectId", + "body": [{ + "group": "body", + "type": "MongoId", "optional": false, - "field": "id", - "description": "

a team's unique mongoId

" + "field": "MongoId", + "description": "

of the team

" }] } }, @@ -2276,7 +2276,7 @@ define({ "filename": "routes/api/team.js", "groupTitle": "Team", "sampleRequest": [{ - "url": "https://api.mchacks.ca/api/team/:id" + "url": "https://api.mchacks.ca/api/team/" }] }, { diff --git a/docs/api/api_data.json b/docs/api/api_data.json index bc480a83..9768490a 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -2208,19 +2208,19 @@ }, { "type": "get", - "url": "/team/:id", + "url": "/team/", "title": "get a team's information", "name": "getTeam", "group": "Team", "version": "0.0.8", "parameter": { "fields": { - "param": [{ - "group": "param", - "type": "ObjectId", + "body": [{ + "group": "body", + "type": "MongoId", "optional": false, - "field": "id", - "description": "

a team's unique mongoId

" + "field": "MongoId", + "description": "

of the team

" }] } }, @@ -2275,7 +2275,7 @@ "filename": "routes/api/team.js", "groupTitle": "Team", "sampleRequest": [{ - "url": "https://api.mchacks.ca/api/team/:id" + "url": "https://api.mchacks.ca/api/team/" }] }, { diff --git a/docs/api/api_project.js b/docs/api/api_project.js index 4528aab8..a1474a1e 100644 --- a/docs/api/api_project.js +++ b/docs/api/api_project.js @@ -1,16 +1,16 @@ -define({ - "name": "hackerAPI", - "version": "0.0.8", - "description": "Documentation for the API used for mchacks", - "defaultVersion": "0.0.8", - "title": "hackerAPI documentation", - "url": "https://api.mchacks.ca/api", - "sampleUrl": "https://api.mchacks.ca/api", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2018-12-29T03:29:50.185Z", - "url": "http://apidocjs.com", - "version": "0.17.7" - } +define({ + "name": "hackerAPI", + "version": "0.0.8", + "description": "Documentation for the API used for mchacks", + "defaultVersion": "0.0.8", + "title": "hackerAPI documentation", + "url": "https://api.mchacks.ca/api", + "sampleUrl": "https://api.mchacks.ca/api", + "apidoc": "0.3.0", + "generator": { + "name": "apidoc", + "time": "2019-01-03T15:48:47.168Z", + "url": "http://apidocjs.com", + "version": "0.17.7" + } }); \ No newline at end of file diff --git a/docs/api/api_project.json b/docs/api/api_project.json index b5623483..3d4665fa 100644 --- a/docs/api/api_project.json +++ b/docs/api/api_project.json @@ -1,16 +1,16 @@ -{ - "name": "hackerAPI", - "version": "0.0.8", - "description": "Documentation for the API used for mchacks", - "defaultVersion": "0.0.8", - "title": "hackerAPI documentation", - "url": "https://api.mchacks.ca/api", - "sampleUrl": "https://api.mchacks.ca/api", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2018-12-29T03:29:50.185Z", - "url": "http://apidocjs.com", - "version": "0.17.7" - } +{ + "name": "hackerAPI", + "version": "0.0.8", + "description": "Documentation for the API used for mchacks", + "defaultVersion": "0.0.8", + "title": "hackerAPI documentation", + "url": "https://api.mchacks.ca/api", + "sampleUrl": "https://api.mchacks.ca/api", + "apidoc": "0.3.0", + "generator": { + "name": "apidoc", + "time": "2019-01-03T15:48:47.168Z", + "url": "http://apidocjs.com", + "version": "0.17.7" + } } \ No newline at end of file diff --git a/middlewares/team.middleware.js b/middlewares/team.middleware.js index 19c9cb60..2c057597 100644 --- a/middlewares/team.middleware.js +++ b/middlewares/team.middleware.js @@ -186,6 +186,14 @@ async function findById(req, res, next) { next(); } +/** + * @async + * @function findMembersNames + * @param {{body: {team: Model}}} req + * @param {*} res + * @return {JSON} Success or error status + * @description Finds the names of the members of a team located in req.body.team. + */ async function findMembersNames(req, res, next) { const team = req.body.team; diff --git a/routes/api/team.js b/routes/api/team.js index 44f387bf..418c1f0d 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -93,12 +93,12 @@ module.exports = { ); /** - * @api {get} /team/:id get a team's information + * @api {get} /team/ get a team's information * @apiName getTeam * @apiGroup Team * @apiVersion 0.0.8 * - * @apiParam (param) {ObjectId} id a team's unique mongoId + * @apiParam (body) {MongoId} MongoId of the team * * @apiSuccess {String} message Success message * @apiSuccess {Object} data Sponsor object From 8fd242950c3c75bc55053405886dd79829dc6676 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Fri, 4 Jan 2019 11:47:14 -0500 Subject: [PATCH 06/11] add some more test details --- tests/team.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/team.test.js b/tests/team.test.js index f6c63d58..85bbeb49 100644 --- a/tests/team.test.js +++ b/tests/team.test.js @@ -81,6 +81,8 @@ describe("GET team", function () { res.body.should.have.property("message"); res.body.message.should.equal(Constants.Success.TEAM_READ); res.body.should.have.property("data"); + res.body.data.should.have.property("team"); + res.body.data.should.have.property("members"); done(); }); From a30c077c46d8c6d181611d3dcb09a707456b3b00 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Fri, 4 Jan 2019 15:42:54 -0500 Subject: [PATCH 07/11] docs and typo --- docs/api/api_data.js | 2 +- docs/api/api_data.json | 2 +- docs/api/api_project.js | 4 ++-- docs/api/api_project.json | 4 ++-- docs/api/locales/locale.js | 1 + routes/api/role.js | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/api/api_data.js b/docs/api/api_data.js index 44d1ef08..7a5c3e34 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -1737,7 +1737,7 @@ define({ { "type": "post", "url": "/api/role/", - "title": "create a new hacker", + "title": "create a new role", "name": "createRole", "group": "Role", "version": "1.1.1", diff --git a/docs/api/api_data.json b/docs/api/api_data.json index c589b60e..358e0078 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -1736,7 +1736,7 @@ { "type": "post", "url": "/api/role/", - "title": "create a new hacker", + "title": "create a new role", "name": "createRole", "group": "Role", "version": "1.1.1", diff --git a/docs/api/api_project.js b/docs/api/api_project.js index 0f667d8e..1b662414 100644 --- a/docs/api/api_project.js +++ b/docs/api/api_project.js @@ -9,8 +9,8 @@ define({ "apidoc": "0.3.0", "generator": { "name": "apidoc", - "time": "2019-01-04T16:52:33.543Z", + "time": "2019-01-04T20:42:05.523Z", "url": "http://apidocjs.com", - "version": "0.17.6" + "version": "0.17.7" } }); \ No newline at end of file diff --git a/docs/api/api_project.json b/docs/api/api_project.json index e895397b..df1a32a7 100644 --- a/docs/api/api_project.json +++ b/docs/api/api_project.json @@ -9,8 +9,8 @@ "apidoc": "0.3.0", "generator": { "name": "apidoc", - "time": "2019-01-04T16:52:33.543Z", + "time": "2019-01-04T20:42:05.523Z", "url": "http://apidocjs.com", - "version": "0.17.6" + "version": "0.17.7" } } \ No newline at end of file diff --git a/docs/api/locales/locale.js b/docs/api/locales/locale.js index c7f34916..880a96cf 100644 --- a/docs/api/locales/locale.js +++ b/docs/api/locales/locale.js @@ -1,5 +1,6 @@ define([ './locales/ca.js', + './locales/cs.js', './locales/de.js', './locales/es.js', './locales/fr.js', diff --git a/routes/api/role.js b/routes/api/role.js index eb428f8f..02dcfdb7 100644 --- a/routes/api/role.js +++ b/routes/api/role.js @@ -18,7 +18,7 @@ module.exports = { const roleRouter = express.Router(); /** - * @api {post} /api/role/ create a new hacker + * @api {post} /api/role/ create a new role * @apiName createRole * @apiGroup Role * @apiVersion 1.1.1 From 8e79107a553ff959e04cb3cb70ac5fb63049e107 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Sat, 5 Jan 2019 21:42:36 -0500 Subject: [PATCH 08/11] Change findMemberNames to use Mongoose.populate --- middlewares/team.middleware.js | 41 +++++++++++++--------------------- routes/api/team.js | 3 +-- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/middlewares/team.middleware.js b/middlewares/team.middleware.js index 08565721..3bc4b7a2 100644 --- a/middlewares/team.middleware.js +++ b/middlewares/team.middleware.js @@ -195,14 +195,21 @@ async function findById(req, res, next) { /** * @async - * @function findMembersNames - * @param {{body: {team: Model}}} req + * @function populateMemberAccountsById + * @param {{body: {id: ObjectId}}} req * @param {*} res * @return {JSON} Success or error status - * @description Finds the names of the members of a team located in req.body.team. + * @description + * Find the team by id and populates the accounts of the members. + * The team information is stored in req.body.team, and the member information is stored in req.body.teamMembers */ -async function findMembersNames(req, res, next) { - const team = req.body.team; +async function populateMemberAccountsById(req, res, next) { + const team = await Services.Team.findById(req.body.id).populate({ + path: "members", + populate: { + path: "accountId" + } + }); if (!team) { return res.status(404).json({ @@ -213,27 +220,11 @@ async function findMembersNames(req, res, next) { let teamMembers = []; - for (const memberId of team.members) { - const hacker = await Services.Hacker.findById(memberId); - - if (!hacker) { - return res.status(404).json({ - message: Constants.Error.TEAM_404_MESSAGE, - data: memberId - }); - } - const acc = await Services.Account.findById(hacker.accountId); - - if (!acc) { - return res.status(404).json({ - message: Constants.Error.ACCOUNT_404_MESSAGE, - data: hacker.accountId, - }); - } - - teamMembers.push(acc); + for (const member of team.members) { + teamMembers.push(member.accountId); } + req.body.team = team; req.body.teamMembers = teamMembers; return next(); } @@ -274,5 +265,5 @@ module.exports = { ensureUniqueHackerId: Util.asyncMiddleware(ensureUniqueHackerId), ensureSpace: Util.asyncMiddleware(ensureSpace), updateHackerTeam: Util.asyncMiddleware(updateHackerTeam), - findMembersNames: Util.asyncMiddleware(findMembersNames), + populateMemberAccountsById: Util.asyncMiddleware(populateMemberAccountsById), }; \ No newline at end of file diff --git a/routes/api/team.js b/routes/api/team.js index f2669201..90965f51 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -120,8 +120,7 @@ module.exports = { Middleware.Validator.Team.getTeamValidator, Middleware.parseBody.middleware, - Middleware.Team.findById, - Middleware.Team.findMembersNames, + Middleware.Team.populateMemberAccountsById, Controllers.Team.showTeam ); From 0c6fa96978e8a0fbc7716a629843435d76cf9739 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Sat, 5 Jan 2019 21:45:03 -0500 Subject: [PATCH 09/11] Change documentation to so param type is ObjectId --- routes/api/team.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/api/team.js b/routes/api/team.js index 90965f51..647c1b8a 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -98,7 +98,7 @@ module.exports = { * @apiGroup Team * @apiVersion 0.0.8 * - * @apiParam (body) {MongoId} MongoId of the team + * @apiParam (param) {ObjectId} id MongoId of the team * * @apiSuccess {String} message Success message * @apiSuccess {Object} data Sponsor object From 2206ade5ddc07a307b325b8980c57fb999a929d1 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Sat, 5 Jan 2019 21:58:44 -0500 Subject: [PATCH 10/11] Move id for get to be in req.param --- constants/routes.constant.js | 2 +- middlewares/validators/team.validator.js | 4 ---- routes/api/team.js | 16 ++++++++++++---- tests/team.test.js | 18 +++--------------- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/constants/routes.constant.js b/constants/routes.constant.js index ab0b9499..8ec49a6f 100644 --- a/constants/routes.constant.js +++ b/constants/routes.constant.js @@ -140,7 +140,7 @@ const sponsorRoutes = { const teamRoutes = { "get": { requestType: Constants.REQUEST_TYPES.GET, - uri: "/api/team/" + uri: "/api/team/" + Constants.ROLE_CATEGORIES.ALL, }, "post": { requestType: Constants.REQUEST_TYPES.POST, diff --git a/middlewares/validators/team.validator.js b/middlewares/validators/team.validator.js index 4937477b..9b248946 100644 --- a/middlewares/validators/team.validator.js +++ b/middlewares/validators/team.validator.js @@ -14,8 +14,4 @@ module.exports = { joinTeamValidator: [ VALIDATOR.asciiValidator("body", "name", false), ], - - getTeamValidator: [ - VALIDATOR.mongoIdValidator("body", "id", false), - ] }; \ No newline at end of file diff --git a/routes/api/team.js b/routes/api/team.js index 647c1b8a..bda1f539 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -113,11 +113,19 @@ module.exports = { * @apiErrorExample {object} Error-Response: * {"message": "Team not found", "data": {}} */ - teamRouter.route("/").get( + teamRouter.route("/:id").get( Middleware.Auth.ensureAuthenticated(), - Middleware.Auth.ensureAuthorized(), - - Middleware.Validator.Team.getTeamValidator, + // get is available for all teams, or no teams. No authorization is done on the :id parameter. + // However, a function is needed, so the identity function is put here. In reality, the route + // is /api/team/:all, so the id is not checked. The returned object places the id inside accountId + // to be consistent with other findById functions + Middleware.Auth.ensureAuthorized([(id) => { + return { + accountId: id + }; + }]), + + Middleware.Validator.RouteParam.idValidator, Middleware.parseBody.middleware, Middleware.Team.populateMemberAccountsById, diff --git a/tests/team.test.js b/tests/team.test.js index d48a1b3c..b940e2f5 100644 --- a/tests/team.test.js +++ b/tests/team.test.js @@ -23,11 +23,7 @@ const agent = chai.request.agent(server.app); describe("GET team", function () { it("should FAIL to list a team's information due to lack of authentication", function (done) { chai.request(server.app) - .get(`/api/team/`) - .type("application/json") - .send({ - id: util.team.Team3._id - }) + .get(`/api/team/${util.team.Team3._id}`) .end(function (err, res) { res.should.have.status(401); res.should.be.json; @@ -46,11 +42,7 @@ describe("GET team", function () { return done(error); } return agent - .get(`/api/team/`) - .type("application/json") - .send({ - id: util.team.newTeam1._id - }) + .get(`/api/team/${util.team.newTeam1._id}`) .end(function (err, res) { res.should.have.status(404); res.should.be.json; @@ -70,11 +62,7 @@ describe("GET team", function () { return done(error); } return agent - .get(`/api/team/`) - .type("application/json") - .send({ - id: util.team.Team3._id - }) + .get(`/api/team/${util.team.Team3._id}`) .end(function (err, res) { res.should.have.status(200); res.should.be.json; From d7f4aac85c0bd07520db66d71aba73b61ba84c56 Mon Sep 17 00:00:00 2001 From: Richard Zhang Date: Mon, 7 Jan 2019 14:14:45 -0500 Subject: [PATCH 11/11] Fix documentation, make test cases more detailed --- docs/api/api_data.js | 14 +++++++------- docs/api/api_data.json | 14 +++++++------- docs/api/api_project.js | 30 +++++++++++++++--------------- docs/api/api_project.json | 30 +++++++++++++++--------------- routes/api/team.js | 4 ++-- tests/team.test.js | 9 +++++++++ 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/docs/api/api_data.js b/docs/api/api_data.js index a71205fa..2368b7e0 100644 --- a/docs/api/api_data.js +++ b/docs/api/api_data.js @@ -2230,19 +2230,19 @@ define({ }, { "type": "get", - "url": "/team/", + "url": "/team/:id", "title": "get a team's information", "name": "getTeam", "group": "Team", "version": "0.0.8", "parameter": { "fields": { - "body": [{ - "group": "body", - "type": "MongoId", + "param": [{ + "group": "param", + "type": "ObjectId", "optional": false, - "field": "MongoId", - "description": "

of the team

" + "field": "id", + "description": "

MongoId of the team

" }] } }, @@ -2297,7 +2297,7 @@ define({ "filename": "routes/api/team.js", "groupTitle": "Team", "sampleRequest": [{ - "url": "https://api.mchacks.ca/api/team/" + "url": "https://api.mchacks.ca/api/team/:id" }] }, { diff --git a/docs/api/api_data.json b/docs/api/api_data.json index e17ef793..c7cce651 100644 --- a/docs/api/api_data.json +++ b/docs/api/api_data.json @@ -2229,19 +2229,19 @@ }, { "type": "get", - "url": "/team/", + "url": "/team/:id", "title": "get a team's information", "name": "getTeam", "group": "Team", "version": "0.0.8", "parameter": { "fields": { - "body": [{ - "group": "body", - "type": "MongoId", + "param": [{ + "group": "param", + "type": "ObjectId", "optional": false, - "field": "MongoId", - "description": "

of the team

" + "field": "id", + "description": "

MongoId of the team

" }] } }, @@ -2296,7 +2296,7 @@ "filename": "routes/api/team.js", "groupTitle": "Team", "sampleRequest": [{ - "url": "https://api.mchacks.ca/api/team/" + "url": "https://api.mchacks.ca/api/team/:id" }] }, { diff --git a/docs/api/api_project.js b/docs/api/api_project.js index c057e7dd..27ce5afa 100644 --- a/docs/api/api_project.js +++ b/docs/api/api_project.js @@ -1,16 +1,16 @@ -define({ - "name": "hackerAPI", - "version": "0.0.8", - "description": "Documentation for the API used for mchacks", - "defaultVersion": "0.0.8", - "title": "hackerAPI documentation", - "url": "https://api.mchacks.ca/api", - "sampleUrl": "https://api.mchacks.ca/api", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2019-01-04T20:42:05.523Z", - "url": "http://apidocjs.com", - "version": "0.17.7" - } +define({ + "name": "hackerAPI", + "version": "0.0.8", + "description": "Documentation for the API used for mchacks", + "defaultVersion": "0.0.8", + "title": "hackerAPI documentation", + "url": "https://api.mchacks.ca/api", + "sampleUrl": "https://api.mchacks.ca/api", + "apidoc": "0.3.0", + "generator": { + "name": "apidoc", + "time": "2019-01-07T19:14:21.760Z", + "url": "http://apidocjs.com", + "version": "0.17.7" + } }); \ No newline at end of file diff --git a/docs/api/api_project.json b/docs/api/api_project.json index 4c26f3cf..3c6ef37d 100644 --- a/docs/api/api_project.json +++ b/docs/api/api_project.json @@ -1,16 +1,16 @@ -{ - "name": "hackerAPI", - "version": "0.0.8", - "description": "Documentation for the API used for mchacks", - "defaultVersion": "0.0.8", - "title": "hackerAPI documentation", - "url": "https://api.mchacks.ca/api", - "sampleUrl": "https://api.mchacks.ca/api", - "apidoc": "0.3.0", - "generator": { - "name": "apidoc", - "time": "2019-01-04T20:42:05.523Z", - "url": "http://apidocjs.com", - "version": "0.17.7" - } +{ + "name": "hackerAPI", + "version": "0.0.8", + "description": "Documentation for the API used for mchacks", + "defaultVersion": "0.0.8", + "title": "hackerAPI documentation", + "url": "https://api.mchacks.ca/api", + "sampleUrl": "https://api.mchacks.ca/api", + "apidoc": "0.3.0", + "generator": { + "name": "apidoc", + "time": "2019-01-07T19:14:21.760Z", + "url": "http://apidocjs.com", + "version": "0.17.7" + } } \ No newline at end of file diff --git a/routes/api/team.js b/routes/api/team.js index bda1f539..ff255e9d 100644 --- a/routes/api/team.js +++ b/routes/api/team.js @@ -93,12 +93,12 @@ module.exports = { ); /** - * @api {get} /team/ get a team's information + * @api {get} /team/:id get a team's information * @apiName getTeam * @apiGroup Team * @apiVersion 0.0.8 * - * @apiParam (param) {ObjectId} id MongoId of the team + * @apiParam (param) {ObjectId} id MongoId of the team * * @apiSuccess {String} message Success message * @apiSuccess {Object} data Sponsor object diff --git a/tests/team.test.js b/tests/team.test.js index b940e2f5..db79ac31 100644 --- a/tests/team.test.js +++ b/tests/team.test.js @@ -70,7 +70,16 @@ describe("GET team", function () { res.body.message.should.equal(Constants.Success.TEAM_READ); res.body.should.have.property("data"); res.body.data.should.have.property("team"); + res.body.data.team.name.should.equal("FullTeam"); res.body.data.should.have.property("members"); + res.body.data.members[0].firstName.should.equal("abcd"); + res.body.data.members[0].lastName.should.equal("defg4"); + res.body.data.members[1].firstName.should.equal("abcd"); + res.body.data.members[1].lastName.should.equal("defg5"); + res.body.data.members[2].firstName.should.equal("abcd"); + res.body.data.members[2].lastName.should.equal("defg6"); + res.body.data.members[3].firstName.should.equal("abcd"); + res.body.data.members[3].lastName.should.equal("defg7"); done(); });