diff --git a/server/controllers/routes/admin/index.js b/server/controllers/routes/admin/index.js index 4dbd4d2d..857fc784 100644 --- a/server/controllers/routes/admin/index.js +++ b/server/controllers/routes/admin/index.js @@ -1,5 +1,7 @@ const router = require('express').Router(); +const { deleteStudent, putStudentData } = require('./student'); +const { addCohort, deleteCohort, editCohort } = require('./cohort'); const { addProject, editProject, @@ -7,9 +9,6 @@ const { getCohortProjects, } = require('./project'); -const { addCohort, deleteCohort, editCohort } = require('./cohort'); -const { deleteStudent } = require('./student'); - router.post('/cohorts', addCohort); router @@ -31,6 +30,7 @@ router.put('/projects/:projectId', editProject); router.post('/projects', addProject); router.get('/cohorts/:cohortId/projects', getCohortProjects); router.delete('/alumni/:studentId', deleteStudent); +router.put('/alumni/:studentId', putStudentData); router.delete('/projects/:projectId', deleteProjectData); module.exports = router; diff --git a/server/controllers/routes/admin/student/index.js b/server/controllers/routes/admin/student/index.js index 973e6c59..d4bc1b5a 100644 --- a/server/controllers/routes/admin/student/index.js +++ b/server/controllers/routes/admin/student/index.js @@ -1,5 +1,7 @@ const deleteStudent = require('./deleteStudent'); +const putStudentData = require('./putStudentData'); module.exports = { deleteStudent, + putStudentData, }; diff --git a/server/controllers/routes/admin/student/putStudentData.js b/server/controllers/routes/admin/student/putStudentData.js new file mode 100644 index 00000000..30aa9ee9 --- /dev/null +++ b/server/controllers/routes/admin/student/putStudentData.js @@ -0,0 +1,43 @@ +const { putStudent } = require('../../../../database/queries'); +const studentSchema = require('../../../../validation/studentSchema'); + +const putStudentData = async (req, res, next) => { + try { + const { studentId } = req.params; + const data = await studentSchema.validate( + { ...req.body, studentId }, + { abortEarly: false }, + ); + const result = await putStudent(data); + if (result.rowCount === 1) { + res.json({ + StatusCode: 200, + data: { + message: "Student's data updated successfully", + }, + }); + } else { + res.status(404).json({ + StatusCode: 404, + data: { + message: 'There is no student for this id', + }, + }); + } + } catch (err) { + if (err.errors) { + res.status(400).json({ statusCode: 400, data: { message: err.errors } }); + } else if (err.detail) { + res.status(409).json({ + statusCode: 409, + data: { + message: err.detail, + }, + }); + } else { + next(err); + } + } +}; + +module.exports = putStudentData; diff --git a/server/database/queries/index.js b/server/database/queries/index.js index a515cd92..57f7b1b8 100644 --- a/server/database/queries/index.js +++ b/server/database/queries/index.js @@ -1,4 +1,4 @@ -const { getAlumniQuery, deleteStudentQuery } = require('./student'); +const { getAlumniQuery, deleteStudentQuery, putStudent } = require('./student'); const { putSpecificCohort, @@ -26,6 +26,7 @@ module.exports = { getCohortProjectsQuery, editProjectQuery, deleteStudentQuery, + putStudent, getProjectById, deleteProject, }; diff --git a/server/database/queries/student/index.js b/server/database/queries/student/index.js index 3f3b4acd..5dd98692 100644 --- a/server/database/queries/student/index.js +++ b/server/database/queries/student/index.js @@ -1,7 +1,9 @@ const getAlumniQuery = require('./getAlumni'); const deleteStudentQuery = require('./deleteStudentQuery'); +const putStudent = require('./putStudent'); module.exports = { getAlumniQuery, deleteStudentQuery, + putStudent, }; diff --git a/server/database/queries/student/putStudent.js b/server/database/queries/student/putStudent.js new file mode 100644 index 00000000..343db0dd --- /dev/null +++ b/server/database/queries/student/putStudent.js @@ -0,0 +1,11 @@ +const connection = require('../../config/connection'); + +const putStudent = (reqData) => { + const { name, email, imgUrl, githubLink, cohortId, studentId } = reqData; + return connection.query( + 'UPDATE student SET name = $1, email = $2, img_url = $3, github_link = $4, cohort_id = $5 WHERE id = $6', + [name, email, imgUrl, githubLink, cohortId, studentId], + ); +}; + +module.exports = putStudent; diff --git a/server/validation/index.js b/server/validation/index.js index 603be23b..3f3dbbc4 100644 --- a/server/validation/index.js +++ b/server/validation/index.js @@ -1,9 +1,11 @@ const cohortSchema = require('./cohortSchema '); const { editCohortSchema } = require('./editCohort'); const projectSchema = require('./projectSchema'); +const studentSchema = require('./studentSchema'); module.exports = { cohortSchema, projectSchema, editCohortSchema, + studentSchema, }; diff --git a/server/validation/studentSchema.js b/server/validation/studentSchema.js new file mode 100644 index 00000000..ba810ac8 --- /dev/null +++ b/server/validation/studentSchema.js @@ -0,0 +1,12 @@ +const yup = require('yup'); + +const studentSchema = yup.object({ + name: yup.string().required(), + email: yup.string().email().required(), + imgUrl: yup.string().url().required(), + githubLink: yup.string().url().required(), + cohortId: yup.number().required(), + studentId: yup.number().required(), +}); + +module.exports = studentSchema; diff --git a/test/index.test.js b/test/index.test.js index 16a5427f..ca10293d 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -208,3 +208,150 @@ describe('Delete specific student by ID', () => { }); }); }); + +describe('Admin, Put project', () => { + const validData = { + name: 'Rehab', + email: 'rehab@gmail.com', + imgUrl: 'https://avatars3.githubusercontent.com/u/49806841?s=460&v=4', + githubLink: 'https://github.com/rehabas', + cohortId: 1, + }; + const invalidData = { + name: 'Rehab', + email: 'email', + imgUrl: 'img url', + githubLink: 'github link', + cohortId: 1, + }; + const duplicateData = { + name: 'Rehab', + email: 'rana@gmail.com', + imgUrl: 'https://avatars3.githubusercontent.com/u/49806841?s=460&v=4', + githubLink: 'https://github.com/rehabas', + cohortId: 1, + }; + + test('PUT Route /alumni/1 status 200, json header, put data ', (done) => { + request(app) + .put('/api/v1/alumni/1') + .send(validData) + .expect(200) + .expect('Content-Type', /json/) + .end(async (err, res) => { + if (err) return done(err); + const { + data: { message }, + } = res.body; + const { rows } = await connection.query( + 'SELECT * from student WHERE id = 1', + ); + expect(rows).toHaveLength(1); + expect(rows[0]).toEqual({ + id: 1, + name: 'Rehab', + email: 'rehab@gmail.com', + img_url: + 'https://avatars3.githubusercontent.com/u/49806841?s=460&v=4', + github_link: 'https://github.com/rehabas', + cohort_id: 1, + }); + expect(message).toBe("Student's data updated successfully"); + done(); + }); + }); + + test('PUT Route /alumni/1 status 200, json header, put data with same email', (done) => { + request(app) + .put('/api/v1/alumni/1') + .send({ + name: 'sara', + email: 'alaa@gmail.com', + imgUrl: 'https://avatars3.githubusercontent.com/u/49806841?s=460&v=4', + githubLink: 'https://github.com/rehabas', + cohortId: 1, + }) + .expect(200) + .expect('Content-Type', /json/) + .end(async (err, res) => { + if (err) return done(err); + const { + data: { message }, + } = res.body; + const { rows } = await connection.query( + 'SELECT * from student WHERE id = 1', + ); + expect(rows).toHaveLength(1); + expect(rows[0]).toEqual({ + id: 1, + name: 'sara', + email: 'alaa@gmail.com', + img_url: + 'https://avatars3.githubusercontent.com/u/49806841?s=460&v=4', + github_link: 'https://github.com/rehabas', + cohort_id: 1, + }); + expect(message).toBe("Student's data updated successfully"); + done(); + }); + }); + + test('PUT Route /alumni/11 status 404, json header, put data ', (done) => { + request(app) + .put('/api/v1/alumni/11') + .send(validData) + .expect(404) + .expect('Content-Type', /json/) + .end(async (err, res) => { + if (err) return done(err); + const { + data: { message }, + } = res.body; + const { rows } = await connection.query( + 'SELECT * from student WHERE id = 11', + ); + expect(rows).toHaveLength(0); + expect(message).toBe('There is no student for this id'); + done(); + }); + }); + + test('PUT Route /alumni/1 status 400, json header, put invalid data ', (done) => { + request(app) + .put('/api/v1/alumni/1') + .send(invalidData) + .expect(400) + .expect('Content-Type', /json/) + .end(async (err, res) => { + if (err) return done(err); + const { + data: { message }, + } = res.body; + await connection.query('SELECT * from student WHERE id = 1'); + expect(message).toEqual([ + 'email must be a valid email', + 'imgUrl must be a valid URL', + 'githubLink must be a valid URL', + ]); + done(); + }); + }); + + test('PUT Route /alumni/1 status 409, json header, put data ', (done) => { + request(app) + .put('/api/v1/alumni/1') + .send(duplicateData) + .expect(409) + .expect('Content-Type', /json/) + .end(async (err, res) => { + if (err) return done(err); + const { + data: { message }, + } = res.body; + expect(message).toBe( + `Key (email)=(${duplicateData.email}) already exists.`, + ); + done(); + }); + }); +});