diff --git a/src/controllers/UserController.js b/src/controllers/UserController.js index eab690f..d6ac495 100644 --- a/src/controllers/UserController.js +++ b/src/controllers/UserController.js @@ -275,6 +275,45 @@ class UserController { return HelperMethods.serverError(res); } } + + /** + * Update rememberDetails column of a user + * Route: POST: api/v1/ + * @param {object} req - HTTP Request object + * @param {object} res - HTTP Response object + * @return {res} res - HTTP Response object + * @memberof UserController + */ + static async rememberUserDetails(req, res) { + try { + const { id } = req.decoded; + const { rememberDetails } = req.body; + const [, [update]] = await User.update( + { rememberDetails }, + { where: { id }, returning: true } + ); + + if (!update) { + return HelperMethods.clientError( + res, { + success: false, + message: 'User not found' + }, 404 + ); + } + + return HelperMethods.requestSuccessful( + res, { + success: true, + message: 'Update successful', + rememberDetails: update.get().rememberDetails + }, 200 + ); + } catch (error) { + if (error.errors) return HelperMethods.sequelizeValidationError(res, error); + return HelperMethods.serverError(res); + } + } } export default UserController; diff --git a/src/migrations/01-create-user.js b/src/migrations/01-create-user.js index 0eb76b9..95733fd 100644 --- a/src/migrations/01-create-user.js +++ b/src/migrations/01-create-user.js @@ -71,6 +71,10 @@ module.exports = { profileImage: { type: Sequelize.STRING, }, + rememberDetails: { + type: Sequelize.BOOLEAN, + defaultValue: false + }, createdAt: { allowNull: false, type: Sequelize.DATE diff --git a/src/models/User.js b/src/models/User.js index 22c509e..55571aa 100755 --- a/src/models/User.js +++ b/src/models/User.js @@ -177,6 +177,10 @@ export default (sequelize, DataTypes) => { } } }, + rememberDetails: { + type: DataTypes.BOOLEAN, + defaultValue: false + } }, { classMethods: { diff --git a/src/routes/userRoute.js b/src/routes/userRoute.js index 00735c3..19a6b44 100644 --- a/src/routes/userRoute.js +++ b/src/routes/userRoute.js @@ -21,6 +21,12 @@ const userRoutes = app => { Authorization.checkToken, UserController.getProfile ); + app.patch( + '/api/v1/remember_details', + Authorization.checkToken, + Validate.validateRememberDetailsUpdate, + UserController.rememberUserDetails + ); }; export default userRoutes; diff --git a/src/test/integrationTests/userController.test.js b/src/test/integrationTests/userController.test.js index f2f4025..e576233 100644 --- a/src/test/integrationTests/userController.test.js +++ b/src/test/integrationTests/userController.test.js @@ -127,12 +127,12 @@ describe('Integration tests for the user controller', () => { }); }); before('Get user token', async () => { - const response = await chai.request(app).post('/api/v1/auth/login') + const loginResponse = await chai.request(app).post('/api/v1/auth/login') .send({ email: 'demo2@demo.com', password: 'password', }); - const { token, id } = response.body.data.userDetails; + const { token, id } = loginResponse.body.data.userDetails; describe('Test profile update endpoints', () => { const newData = { id, @@ -204,5 +204,68 @@ describe('Integration tests for the user controller', () => { expect(result.body.message).equal('User not authorized'); }); }); + describe('Test for updating remember user details', () => { + it('should update rememberDetails to true', async () => { + const response = await chai + .request(app) + .patch('/api/v1/remember_details') + .set({ 'x-access-token': token }) + .send({ rememberDetails: 'true' }); + expect(response.status).to.deep.equal(200); + expect(response.body.data).to.have.property('message'); + expect(response.body.data.message).to.equal('Update successful'); + expect(response.body.data).to.have.property('success'); + expect(response.body.data.success).to.equal(true); + expect(response.body.data.rememberDetails).to.equal(true); + }); + it('should update rememberDetails to false', async () => { + const response = await chai + .request(app) + .patch('/api/v1/remember_details') + .set({ 'x-access-token': token }) + .send({ rememberDetails: 'false' }); + expect(response.status).to.deep.equal(200); + expect(response.body.data).to.have.property('message'); + expect(response.body.data.message).to.equal('Update successful'); + expect(response.body.data).to.have.property('success'); + expect(response.body.data.success).to.equal(true); + expect(response.body.data.rememberDetails).to.equal(false); + }); + it('should return client error 401 when token is missing', async () => { + const response = await chai + .request(app) + .patch('/api/v1/remember_details') + .send({ rememberDetails: true }); + expect(response.status).to.deep.equal(401); + expect(response.body).to.have.property('success'); + expect(response.body.success).to.equal(false); + expect(response.body).to.have.property('message'); + }); + it('should return client error when rememberDetails is missing', async () => { + const response = await chai + .request(app) + .patch('/api/v1/remember_details') + .set({ 'x-access-token': token }); + expect(response.status).to.deep.equal(400); + expect(response.body).to.have.property('success'); + expect(response.body.success).to.equal(false); + expect(response.body).to.have.property('message'); + expect(response.body.message).to + .equal('"rememberDetails" field is required and must be a boolean'); + }); + it('should return client error when rememberDetails is invalid', async () => { + const response = await chai + .request(app) + .patch('/api/v1/remember_details') + .set({ 'x-access-token': token }) + .send({ rememberDetails: 'some string' }); + expect(response.status).to.deep.equal(400); + expect(response.body).to.have.property('success'); + expect(response.body.success).to.equal(false); + expect(response.body).to.have.property('message'); + expect(response.body.message).to + .equal('"rememberDetails" field is required and must be a boolean'); + }); + }); }); }); diff --git a/src/validation/index.js b/src/validation/index.js index 4860de0..96b4ee1 100644 --- a/src/validation/index.js +++ b/src/validation/index.js @@ -100,7 +100,27 @@ class Validate { if (emptyField) return allFieldsRequired(res, emptyField); next(); } + + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @param {callback} next - The callback that passes the request to the next handler + * @returns {object} res - Response object when query is invalid + * @memberof Validate + */ + static validateRememberDetailsUpdate(req, res, next) { + req.body = trimValues(req.body); + const emptyField = checkForEmptyFields(req.body); + if (emptyField) return allFieldsRequired(res, emptyField); + const { rememberDetails } = req.body; + if ((rememberDetails !== 'true') && (rememberDetails !== 'false')) { + return res.status(400).send({ + success: false, + message: '"rememberDetails" field is required and must be a boolean', + }); + } + next(); + } } export default Validate; -