Skip to content

Commit

Permalink
Merge pull request #49 from andela/ft-edit-comments-on-requests-16837…
Browse files Browse the repository at this point in the history
…8880

#168378880 Edit posted comments on a request
  • Loading branch information
Oluwafayokemi committed Sep 12, 2019
2 parents 41aefa4 + 202c2e3 commit b8d033f
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 18 deletions.
1 change: 1 addition & 0 deletions .coveralls.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@

repo_token: process.ENV.COVERALLS_REPO_TOKEN

2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"root": true,
"extends": "airbnb-base",
"env": {
"browser": true,
"node": true,
"es6": true,
"mocha": true
Expand All @@ -26,6 +27,7 @@
"requireParamDescription": false,
"requireReturnDescription": true
}],
"import/named": false,
"require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
Expand Down
47 changes: 44 additions & 3 deletions src/controllers/comment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable require-jsdoc */
import models from '../models';
import errorResponse from '../utils/index';
import { eventEmitter } from '../services/websocket';

const { Comment, Notification, Request } = models;
Expand All @@ -17,16 +18,21 @@ export default class CommentController {
const userId = req.user.id;
const { lineManagerId } = req.user;
const { requestId } = req.params;
const newComment = await Comment.create({
commentBody, requestId, userId
});

const request = await Request.findOne({
where: {
id: requestId
}
});

if (!request) return res.status(400).json({
status: 'error',
message: 'This trip request does not exist'});

const newComment = await Comment.create({
commentBody, requestId, userId
});

const { lineManagerId: managerId, userId: id } = request;

const emitMessage = 'New Comment';
Expand Down Expand Up @@ -81,6 +87,41 @@ export default class CommentController {
}
}

/**
* @param {Objec} req the edited comment
* @param {Object} res message to user
* @returns {Object} success or failure to edit comment
* @description Allow a user to edit a posted comment
*/
static async editComment(req, res) {
const { commentBody } = req.body;
const { commentId } = req.params;
const userId = req.user.id;
try {
let comment = await Comment.findOne({
where: {
id: commentId, userId
}
});

if (!comment) return errorResponse(new Error('This comment doesn\'t exist'), res, 404);

comment = await comment.update({ commentBody }, { returning: true });
const patchedComment = comment.dataValues;

return res.status(200).json({
status: 'success',
data: {
message: 'Comment successfully updated',
commentBody: patchedComment.commentBody,
patcher: patchedComment.userId
}
});
} catch (error) {
res.status(500).json({ status: 'error', error: error.message });
}
}

/**
* @param {Object} req the unwanted comment to be removed
* @param {Object} res successfully deleted comment or failure object
Expand Down
107 changes: 104 additions & 3 deletions src/docs/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ module.exports = {
}
],
responses: {
200: {
description: 'Permissions have been set for a role',
201: {
description: 'successful operation; comment created',
Expand Down Expand Up @@ -784,7 +783,6 @@ module.exports = {
}
}
}
}
}
},
get: {
Expand Down Expand Up @@ -899,8 +897,111 @@ module.exports = {
}
}
}
},
}
},
'/request/requestId/comment/commentId': {
patch: {
tags: ['comment'],
summary: 'Edit a posted comment',
produces: ['application/json'],
parameters: [
{
name: 'Authorization',
in: 'headers',
description: 'Bearer token',
type: 'string'
},
{
in: 'body',
name: 'body',
description: 'body',
schema: {
type: 'object',
properties: {
commentBody: {
type: 'string',
example: 'About my last comment, I meant to say nothing actually.'
}
}
}
}
],
responses: {
200: {
description: 'comment successfully updated',
schema: {
type: 'object',
properties: {
status: {
type: 'string'
},
data: {
type: 'object'
}
}
}
},
404: {
description: 'comment with that comment ID and or user ID does not exist',
schema: {
type: 'object',
properties: {
status: {
type: 'string'
},
error: {
type: 'string'
}
}
}
}
}
},
delete: {
tags: ['comment'],
summary: 'delete a posted comment',
produces: ['application/json'],
parameters: [
{
name: 'Authorization',
in: 'headers',
description: 'Bearer token',
type: 'string'
}
],
responses: {
200: {
description: 'comment successfully deleted',
schema: {
type: 'object',
properties: {
status: {
type: 'string'
},
data: {
type: 'object'
}
}
}
},
401: {
description: 'You are not the owner of the comment, invalid token',
schema: {
type: 'object',
properties: {
status: {
type: 'string'
},
error: {
type: 'string'
}
}
}
}
}
}
}
,
'/role': {
patch: {
tags: ['role & permissions'],
Expand Down
4 changes: 1 addition & 3 deletions src/routes/accommodation.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Router } from 'express';
import { AccommodationController } from '../controllers';
import {
checkToken, checkVerified, /* checkIfBooked, checkIfOwner */
} from '../middlewares';
import { checkToken, checkVerified } from '../middlewares';
import getImageFromRequest from '../middlewares/getImageFromRequest';
import ValidateAccommodation from '../middlewares/validateAccommodation';
import CloudinaryConfig from '../middlewares/cloudinaryConfig';
Expand Down
2 changes: 1 addition & 1 deletion src/routes/api/comment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable import/no-useless-path-segments */
import { Router } from 'express';
import { CommentController } from '../../controllers/';
import validateComment from '../../middlewares/validateComment';
Expand All @@ -7,6 +6,7 @@ const router = Router();

router.post('/:requestId/comment', validateComment, CommentController.postComment);
router.get('/:requestId/comment', CommentController.getComments);
router.patch('/:requestId/comment/:commentId', validateComment, CommentController.editComment);
router.delete('/:requestId/comment/:commentId', CommentController.pseudoDeleteComment);

export default router;
69 changes: 61 additions & 8 deletions src/tests/comment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ before((done) => {
status: 'pending',
type: 'one-way',
}).then((newRequest) => {
requestId = newRequest.id;
Trip.create({
requestId: newRequest.id,
requestId,
from: 'lagos',
to: 'kampala',
departureDate: '2019-08-09 13:00',
Expand Down Expand Up @@ -90,7 +91,7 @@ before((done) => {
describe('POST /request/:requestId/comment, Creating a new newcomment', () => {
it('Should return details of the new comments on a request', (done) => {
chai.request(server)
.post('/api/v1/request/1/comment')
.post(`/api/v1/request/${requestId}/comment`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: 'This is the comment',
Expand All @@ -111,7 +112,7 @@ describe('POST /request/:requestId/comment, Creating a new newcomment', () => {
// send a second comment
it('Should return details of the second comment on a request', (done) => {
chai.request(server)
.post('/api/v1/request/1/comment')
.post(`/api/v1/request/${requestId}/comment`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: 'second comment, this comment\'s deleted-at column sould be null ',
Expand All @@ -131,7 +132,7 @@ describe('POST /request/:requestId/comment, Creating a new newcomment', () => {

it('Should respond with error object if an empty comment is made', (done) => {
chai.request(server)
.post('/api/v1/request/1/comment')
.post(`/api/v1/request/${requestId}/comment`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: '',
Expand All @@ -149,7 +150,7 @@ describe('POST /request/:requestId/comment, Creating a new newcomment', () => {

it('Should respond with error object if a bad comment request is made', (done) => {
chai.request(server)
.post('/api/v1/request/1/comment')
.post(`/api/v1/request/${requestId}/comment`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: 1,
Expand All @@ -166,10 +167,62 @@ describe('POST /request/:requestId/comment, Creating a new newcomment', () => {
});
});

describe('PATCH /request/requestId/comment/commentId, editing a comment', () => {
it('Should allow a users ability to edit their posted comments', (done) => {
chai.request(server)
.patch(`/api/v1/request/${requestId}/comment/2`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: 'Am the second comment, and i\'ve been patched! anyhow'
})
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
expect(err).to.be.null;
expect(res).to.has.status(200);
expect(res.body).to.haveOwnProperty('status');
expect(res.body.status).to.equal('success');
expect(res.body).to.haveOwnProperty('data');
expect(res.body.data).to.haveOwnProperty('patcher');
done();
});
});

it('Should throw an error if bad edit comment is made', (done) => {
chai.request(server)
.patch(`/api/v1/request/${requestId}/comment/2`)
.set('Authorization', `Bearer ${firstToken}`)
.send({
commentBody: 1
})
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
expect(res).to.has.status(400);
expect(res.body).to.haveOwnProperty('status');
expect(res.body).to.haveOwnProperty('error');
done();
});
});

it('Should NOT allow a user ability to edit another user\'s posted comments', (done) => {
chai.request(server)
.patch(`/api/v1/request/${requestId}/comment/2`)
.set('Authorization', `Bearer ${secondToken}`)
.send({
commentBody: 'Am an impostor trying to patch the second comment'
})
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
expect(res).to.has.status(404);
expect(res.body).to.haveOwnProperty('status');
done();
});
});
});

describe('PSEUDO-delete /request/:requestId/comment/commentId', () => {
it('Should NOT ALLOW a user to delete another user\'s comment', (done) => {
chai.request(server)
.delete('/api/v1/request/1/comment/1')
.delete(`/api/v1/request/${requestId}/comment/1`)
.set('Authorization', `Bearer ${secondToken}`)
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
Expand All @@ -183,7 +236,7 @@ describe('PSEUDO-delete /request/:requestId/comment/commentId', () => {

it('Should set DeletedAt column to current date and time', (done) => {
chai.request(server)
.delete('/api/v1/request/1/comment/1')
.delete(`/api/v1/request/${requestId}/comment/1`)
.set('Authorization', `Bearer ${firstToken}`)
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
Expand All @@ -200,7 +253,7 @@ describe('PSEUDO-delete /request/:requestId/comment/commentId', () => {
describe('GET /request/:requestId/comment', () => {
it('Should return all comments in the database related to a request', (done) => {
chai.request(server)
.get('/api/v1/request/1/comment')
.get(`/api/v1/request/${requestId}/comment`)
.set('Authorization', `Bearer ${firstToken}`)
.end((err, res) => {
// eslint-disable-next-line no-unused-expressions
Expand Down
Loading

0 comments on commit b8d033f

Please sign in to comment.