Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions constants/role.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const hackerRole = {
Constants.Routes.hackerRoutes.getSelf,

Constants.Routes.teamRoutes.join,
Constants.Routes.teamRoutes.get
]
};

Expand All @@ -52,6 +53,8 @@ const volunteerRole = {

Constants.Routes.hackerRoutes.patchAnyCheckInById,
Constants.Routes.hackerRoutes.patchSelfCheckInById,

Constants.Routes.teamRoutes.get
]
};

Expand Down
6 changes: 1 addition & 5 deletions constants/routes.constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,7 @@ 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,
},
Expand Down
20 changes: 19 additions & 1 deletion controllers/team.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
});
}

Expand Down
4 changes: 2 additions & 2 deletions docs/api/api_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -1779,7 +1779,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",
Expand Down Expand Up @@ -2263,7 +2263,7 @@ define({
"type": "ObjectId",
"optional": false,
"field": "id",
"description": "<p>a team's unique mongoId</p>"
"description": "<p>MongoId of the team</p>"
}]
}
},
Expand Down
4 changes: 2 additions & 2 deletions docs/api/api_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -1778,7 +1778,7 @@
{
"type": "post",
"url": "/api/role/",
"title": "create a new hacker",
"title": "create a new role",
"name": "createRole",
"group": "Role",
"version": "1.1.1",
Expand Down Expand Up @@ -2262,7 +2262,7 @@
"type": "ObjectId",
"optional": false,
"field": "id",
"description": "<p>a team's unique mongoId</p>"
"description": "<p>MongoId of the team</p>"
}]
}
},
Expand Down
30 changes: 15 additions & 15 deletions docs/api/api_project.js
Original file line number Diff line number Diff line change
@@ -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-04T19:05:11.619Z",
"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"
}
});
30 changes: 15 additions & 15 deletions docs/api/api_project.json
Original file line number Diff line number Diff line change
@@ -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-04T19:05:11.619Z",
"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"
}
}
40 changes: 39 additions & 1 deletion middlewares/team.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -192,6 +193,42 @@ async function findById(req, res, next) {
next();
}

/**
* @async
* @function populateMemberAccountsById
* @param {{body: {id: ObjectId}}} req
* @param {*} res
* @return {JSON} Success or error status
* @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 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({
message: Constants.Error.TEAM_404_MESSAGE,
data: {}
});
}

let teamMembers = [];

for (const member of team.members) {
teamMembers.push(member.accountId);
}

req.body.team = team;
req.body.teamMembers = teamMembers;
return next();
}

/**
* @function parseTeam
* @param {{body: {name: string, members: Object[], devpostURL: string, projectName: string}}} req
Expand Down Expand Up @@ -228,4 +265,5 @@ module.exports = {
ensureUniqueHackerId: Util.asyncMiddleware(ensureUniqueHackerId),
ensureSpace: Util.asyncMiddleware(ensureSpace),
updateHackerTeam: Util.asyncMiddleware(updateHackerTeam),
populateMemberAccountsById: Util.asyncMiddleware(populateMemberAccountsById),
};
2 changes: 1 addition & 1 deletion middlewares/validators/team.validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ module.exports = {

joinTeamValidator: [
VALIDATOR.asciiValidator("body", "name", false),
]
],
};
2 changes: 1 addition & 1 deletion routes/api/role.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 13 additions & 2 deletions routes/api/team.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ module.exports = {
* @apiGroup Team
* @apiVersion 0.0.8
*
* @apiParam (param) {ObjectId} id a team's unique mongoId
* @apiParam (param) {ObjectId} id MongoId of the team
*
* @apiSuccess {String} message Success message
* @apiSuccess {Object} data Sponsor object
Expand All @@ -114,10 +114,21 @@ module.exports = {
* {"message": "Team not found", "data": {}}
*/
teamRouter.route("/:id").get(
Middleware.Auth.ensureAuthenticated(),
// 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.findById,
Middleware.Team.populateMemberAccountsById,
Controllers.Team.showTeam
);

Expand Down
61 changes: 55 additions & 6 deletions tests/team.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,70 @@ 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/${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/${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/${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");
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();
});
});
});
});

describe("POST create team", function () {
Expand Down
10 changes: 5 additions & 5 deletions tests/util/account.test.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand Down
1 change: 1 addition & 0 deletions tests/util/team.test.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down