Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32 put project #47

Merged
merged 10 commits into from
Apr 1, 2020
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"dev": "NODE_ENV=development nodemon server/index.js",
"project-setup": "npm install && cd client && npm install",
"heroku-postbuild": "cd client && npm install && npm run build",
"test": "NODE_ENV=test jest --coverage",
"test": "NODE_ENV=test jest --runInBand --coverage",
"kill": "fuser -k 5000/tcp",
"lint": "eslint server/",
"lint-fix": "eslint server/ --fix",
Expand Down
3 changes: 2 additions & 1 deletion server/controllers/routes/admin/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const router = require('express').Router();
const { deleteCohort } = require('./cohort');
const { addProject } = require('./project');
const { addProject, editProject } = require('./project');

router
.route('/cohorts/:cohortId')
Expand All @@ -19,6 +19,7 @@ router
})
.delete(deleteCohort);

router.put('/projects/:projectId', editProject);
router.post('/projects', addProject);

module.exports = router;
27 changes: 27 additions & 0 deletions server/controllers/routes/admin/project/editProject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { editProjectQuery } = require('../../../../database/queries');
const { projectSchema } = require('../../../../validation');

const editProject = async (req, res, next) => {
try {
await projectSchema.validate(
{ ...req.body, projectId: req.params.projectId },
{ abortEarly: false },
);
await editProjectQuery(req.body);
res.json({
StatusCode: 200,
data: { message: 'project updated successfully' },
});
} catch (err) {
if (err.errors) {
res.json({
StatusCode: 400,
data: { message: err.errors },
});
} else {
next(err);
}
}
};

module.exports = editProject;
2 changes: 2 additions & 0 deletions server/controllers/routes/admin/project/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const addProject = require('./addProject');
const editProject = require('./editProject');

module.exports = {
addProject,
editProject,
};
16 changes: 16 additions & 0 deletions server/database/config/fakeData.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ INSERT INTO project (name , description , img_url , github_link , website_link ,
'https://lh3.googleusercontent.com/proxy/fp_bF_rbMIKyCfgdgWodyuM9LGt3HwGgM8AMnQ4qxjftKcvEdmhngdaeA8F6xFgRDHVzezPLT6YZarpBcqnMD5WtAvUhKJXcWS7qvS6Bn3CllitLttt_uA',
'https://github.com/GSG-G8/ca-wiki/tree/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3',
'https://github.com/GSG-G8/ca-wiki/blob/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3/%5Blink%5D','Internal project',1),
('ca-wiki',
'Ca-wiki is a web application which allows clients to view all cohorts that have been enrolled in Code Academy. Clients can view all students who graduated from the academy so that they can view every student and his/her projects he/she participated in, his/her github page',
'https://lh3.googleusercontent.com/proxy/fp_bF_rbMIKyCfgdgWodyuM9LGt3HwGgM8AMnQ4qxjftKcvEdmhngdaeA8F6xFgRDHVzezPLT6YZarpBcqnMD5WtAvUhKJXcWS7qvS6Bn3CllitLttt_uA',
'https://github.com/GSG-G8/ca-wiki/tree/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3',
'https://github.com/GSG-G8/ca-wiki/blob/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3/%5Blink%5D','Internal project',2),
('ca-wiki',
'Ca-wiki is a web application which allows clients to view all cohorts that have been enrolled in Code Academy. Clients can view all students who graduated from the academy so that they can view every student and his/her projects he/she participated in, his/her github page',
'https://lh3.googleusercontent.com/proxy/fp_bF_rbMIKyCfgdgWodyuM9LGt3HwGgM8AMnQ4qxjftKcvEdmhngdaeA8F6xFgRDHVzezPLT6YZarpBcqnMD5WtAvUhKJXcWS7qvS6Bn3CllitLttt_uA',
'https://github.com/GSG-G8/ca-wiki/tree/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3',
'https://github.com/GSG-G8/ca-wiki/blob/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3/%5Blink%5D','Internal project',1),
('ca-wiki',
'Ca-wiki is a web application which allows clients to view all cohorts that have been enrolled in Code Academy. Clients can view all students who graduated from the academy so that they can view every student and his/her projects he/she participated in, his/her github page',
'https://lh3.googleusercontent.com/proxy/fp_bF_rbMIKyCfgdgWodyuM9LGt3HwGgM8AMnQ4qxjftKcvEdmhngdaeA8F6xFgRDHVzezPLT6YZarpBcqnMD5WtAvUhKJXcWS7qvS6Bn3CllitLttt_uA',
'https://github.com/GSG-G8/ca-wiki/tree/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3',
'https://github.com/GSG-G8/ca-wiki/blob/ed9f4cd9b5dc428f5420fe9a880a27e63f5f04d3/%5Blink%5D','Internal project',2),

('events-booker',
'This app to help GSG organization in organizing the registration for the events that they do. So When they announced for an event, it will be known who would like to attend and they can ensure if this person attended or not. By this way, the GSG can have information about the people who attended and they can use it in the future as they want.',
'https://d2slcw3kip6qmk.cloudfront.net/marketing/blog/2017Q2/[email protected]',
Expand Down
3 changes: 2 additions & 1 deletion server/database/queries/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const { getCohortQuery } = require('./cohort');
const { deleteCohortQuery } = require('./cohort');
const { addProjectQuery } = require('./project');
const { addProjectQuery, editProjectQuery } = require('./project');

module.exports = {
deleteCohortQuery,
getCohortQuery,
addProjectQuery,
editProjectQuery,
};
28 changes: 28 additions & 0 deletions server/database/queries/project/editProject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const connection = require('../../config/connection');

const editProjectQuery = (data) => {
const {
name,
description,
imgUrl,
githubLink,
websiteLink,
projectType,
cohortId,
projectId,
} = data;
connection.query(
'UPDATE project SET name=$1, description=$2, img_url=$3, github_link=$4, website_link=$5, project_type=$6, cohort_id=$7 WHERE id = $8',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MohammedAlghazali In general it's best if PUT endpoints can handle requests that do not provide every argument, and can merge with existing data.
For example, it would be good if I could PUT /projects/1 {name: 'updated name'} and then it updates only the name, while leaving the rest of the data, like description and img_url, set to their previous values.
This is a good design because then you can add new columns to the table and endpoint in the future, and if old clients are still doing PUT requests that don't have that new column, they won't nullify data in the mysql table.
In other words, what if you release an iOS app which is PUTting these data columns, then next month you add a new column, project_owner, and your web app can update the project_owner but people are still using the old version of the iOS app to edit projects, and that app does not know about project_owner and is still making PUT requests without project_owner - you want your endpoint to still work for those old apps.

I think you could accomplish this by passing the request body object to this function, instead of all of the destructured arguments, and then doing UPDATE project SET ?. This link has more info:
https://stackoverflow.com/questions/59959755/update-data-with-nodejs/59960177#59960177

[
name,
description,
imgUrl,
githubLink,
websiteLink,
projectType,
cohortId,
projectId,
],
);
};
module.exports = editProjectQuery;
2 changes: 2 additions & 0 deletions server/database/queries/project/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const addProjectQuery = require('./addProject');
const editProjectQuery = require('./editProject');

module.exports = {
addProjectQuery,
editProjectQuery,
};
1 change: 1 addition & 0 deletions server/validation/projectSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const projectSchema = yup.object({
websiteLink: yup.string().url().required(),
projectType: yup.mixed().oneOf(['internal', 'remotely']),
cohortId: yup.number().integer().positive().required(),
projectId: yup.number().integer().positive(),
});

module.exports = projectSchema;
27 changes: 26 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Admin, Project', () => {
const { message } = res.body.data;
if (err) return done(err);
const { rows } = await connection.query(
'SELECT * from project WHERE id = 3',
'SELECT * from project WHERE id = 6',
);
expect(rows[0].name).toBe('Mohmmedzw851@');
expect(message).toBe('Project Added successfully');
Expand All @@ -83,3 +83,28 @@ describe('Admin, (/cohorts/:cohortId)', () => {
});
});
});

describe('Admin, (/projects/:projectId)', () => {
test('PUT Route /projects/1 status 200, json header, message:Cohort updated successfully', (done) => {
const testData = {
name: 'Mooooot',
description: 'project test',
imgUrl: 'https://github.com/GSG-G1',
githubLink: 'https://github.com/GSG-G1',
websiteLink: 'https://github.com/GSG-G1',
projectType: 'remotely',
cohortId: '2',
};
return request(app)
.put('/api/v1/projects/5')
.send(testData)
.expect(200)
.expect('Content-Type', /json/)
.end(async (err, res) => {
if (err) return done(err);
const { message } = res.body.data;
expect(message).toBe('project updated successfully');
done();
});
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MohammedAlghazali This test looks good! You could consider adding a test for error conditions too, or a test for validation.

});