Skip to content

Commit

Permalink
Merge e4b0357 into 69641c2
Browse files Browse the repository at this point in the history
  • Loading branch information
oosahon committed Sep 13, 2019
2 parents 69641c2 + e4b0357 commit e7b9624
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 40 deletions.
8 changes: 3 additions & 5 deletions src/controllers/comment.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ export default class CommentController {
comment,
user_id: user.id
});

res.status(201).json({
status: 'success',
data: postedComment
});
// sends the comment data to the notification middleware
req.body.commentData = postedComment;
return next(); // calls the notification middleware
} catch (error) { next(error); }
}

Expand Down
4 changes: 2 additions & 2 deletions src/controllers/request.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,12 @@ export default class RequestController {
}
}

/**
/**
* @param {object} req
* @param {object} res
* @returns {json} request
*/
static async approveRequest(req, res) {
static async approveRequest(req, res) {
try {
const request = await Request.update(
{
Expand Down
3 changes: 3 additions & 0 deletions src/middlewares/comment.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export default class AuthenticationMiddleware {
const isPermitted = (user.id === request.user_id)
|| (user.id === request.User.manager_id);

// make request available to the next middleware
req.body.requestData = request;

return isPermitted
? next()
: res.status(403).json({
Expand Down
50 changes: 50 additions & 0 deletions src/middlewares/notification.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import model from '../db/models/index';

const { Notification } = model;

/**
* Notifications middleware
*/
export default class NotificationMiddleware {
/**
* sends notification to user when a comment is made on a request
* @param {Object} req
* @param {Object} res
* @returns {JSON} responseBody
*/
static async postCommentNotification(req, res) {
// requestData and commentData were gotten from the ensureUserCanPost and postComment middlewares respectively
const { requestData, user, commentData } = req.body;

try {
// send notification to User's manager if user owns the request
const responseMessage = (user.id === requestData.user_id)
? 'A notification was sent to your manager.'
: 'A notification was sent to the request\'s owner.';

const receiver_id = (user.id === requestData.user_id)
? requestData.User.manager_id
: requestData.user_id;

await Notification.create({
request_id: requestData.id,
subject: 'New Comment On Request',
notification: commentData.comment,
receiver_id
});

await res.status(201).json({
status: 'success',
data: commentData,
message: responseMessage
});
} catch (error) {
// sending a 201 status because although notification failed, comment was successfully posted
res.status(201).json({
status: 'success',
data: commentData,
message: 'Could not send notification.'
});
}
}
}
5 changes: 4 additions & 1 deletion src/routes/api/comment.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import CommentController from '../../controllers/comment.controller';
import auth from '../../middlewares/auth';
import Authorization from '../../middlewares/comment.middleware';
import validateComment from '../../validation/comment.validation';
import NotificationMiddleware from '../../middlewares/notification.middleware';

const { postCommentNotification } = NotificationMiddleware;

const router = express.Router();

/* comment Routes Here */
router.post('/comments', auth.verifyUserToken, validateComment, Authorization.ensureUserCanPost, CommentController.postComment);
router.post('/comments', auth.verifyUserToken, validateComment, Authorization.ensureUserCanPost, CommentController.postComment, postCommentNotification);
router.delete('/comment/:comment_id', auth.verifyUserToken, Authorization.verifyCommentOwner, CommentController.deleteComment);
router.get('/comment/:request_id', auth.verifyUserToken, Authorization.verifyPermission, CommentController.getComments);

Expand Down
16 changes: 16 additions & 0 deletions src/test/bookings/checkin.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import chai from 'chai';
import chaiHttp from 'chai-http';
import sinon from 'sinon';
import app from '../../index';
import models from '../../db/models/index';

const { Booking } = models;

const { expect } = chai;
chai.use(chaiHttp);
Expand Down Expand Up @@ -85,6 +89,18 @@ describe('Bookings', () => {
done();
});
});

it('Should fake server error', (done) => {
const stub = sinon.stub(Booking, 'update').throws(new Error());
chai.request(app)
.patch('/api/v1/bookings/1/checkin')
.set('Authorization', myToken)
.end((error, res) => {
stub.restore();
expect(res).to.have.status(500);
done();
});
});
});
});

138 changes: 106 additions & 32 deletions src/test/comment/postComments.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import chai from 'chai';
import chaiHttp from 'chai-http';
import sinon from 'sinon';
import app from '../../index';
import commentController from '../../controllers/comment.controller';
import commentMiddleware from '../../middlewares/comment.middleware';
import models from '../../db/models/index';
const { Request, Comment, Notification } = models;

const { expect } = chai;

chai.use(chaiHttp);

let myToken;
let managerToken;
let userWithoutManagerToken;

before((done) => {
chai.request(app)
Expand All @@ -20,35 +22,31 @@ before((done) => {
})
.end((err, res) => {
myToken = res.body.data.token;
done();
});

chai.request(app)
.post('/api/v1/auth/signin')
.send({
email: 'bola.akin@email.com',
password: 'bolaji99'
})
.end((err, res) => {
managerToken = res.body.data.token;
});

chai.request(app)
.post('/api/v1/auth/signin')
.send({
email: 'peter_koke@email.com',
password: 'asdfghjkl'
})
.end((err, res) => {
userWithoutManagerToken = res.body.data.token;
});
done();
});

describe('Post Comments /comments', () => {
it('Should fake controller server error', (done) => {
const req = { body: {} };
const res = {
status(){},
send(){}
};
sinon.stub(res, 'status').returnsThis();
commentController.postComment(req, res);
(res.status).should.have.callCount(0);
done();
});

it('Should fake middleware server error', (done) => {
const req = { body: {} };
const res = {
status(){},
send(){}
};
sinon.stub(res, 'status').returnsThis();
commentMiddleware.ensureUserCanPost(req, res);
(res.status).should.have.callCount(0);
done();
});

it('Should send a 401 error if authorization token was not provided', (done) => {
chai.request(app)
.post('/api/v1/comments')
Expand Down Expand Up @@ -152,9 +150,9 @@ describe('Post Comments /comments', () => {
it('Should send a 403 error if request does not belong to user', (done) => {
chai.request(app)
.post('/api/v1/comments')
.set('Authorization', myToken)
.set('Authorization', userWithoutManagerToken)
.send({
request_id: 3,
request_id: 2,
comment: 'Is there a way forward?'
})
.end((error, res) => {
Expand All @@ -168,9 +166,9 @@ describe('Post Comments /comments', () => {
it('Should send a 403 error is user is neither the manager or owner of the request', (done) => {
chai.request(app)
.post('/api/v1/comments')
.set('Authorization', myToken)
.set('Authorization', userWithoutManagerToken)
.send({
request_id: 3,
request_id: 2,
comment: 'Is there a way forward?'
})
.end((error, res) => {
Expand All @@ -195,6 +193,7 @@ describe('Post Comments /comments', () => {
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('A notification was sent to your manager.');
done();
});
});
Expand All @@ -213,6 +212,7 @@ describe('Post Comments /comments', () => {
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('A notification was sent to your manager.');
done();
});
});
Expand All @@ -231,6 +231,7 @@ describe('Post Comments /comments', () => {
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('A notification was sent to your manager.');
done();
});
});
Expand All @@ -249,7 +250,80 @@ describe('Post Comments /comments', () => {
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('A notification was sent to your manager.');
done();
});
});

it('Should post comment if user is the manager of the request\s owner', (done) => {
chai.request(app)
.post('/api/v1/comments')
.send({
request_id: 2,
comment: 'Please what is the status?',
authorization: managerToken
})
.end((error, res) => {
expect(res).to.have.status(201);
expect(res.body.status).to.deep.equal('success');
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('A notification was sent to the request\'s owner.');
done();
});
});

it('Should fake request server error', (done) => {
const stub = sinon.stub(Request, 'findByPk').throws(new Error());
chai.request(app)
.post('/api/v1/comments')
.send({
request_id: 2,
comment: 'Can a notification be sent?',
authorization: myToken
})
.end((error, res) => {
stub.restore();
expect(res).to.have.status(500);
done();
});
});

it('Should fake comments error', (done) => {
const stub = sinon.stub(Comment, 'create').throws(new Error());
chai.request(app)
.post('/api/v1/comments')
.send({
request_id: 2,
comment: 'Can a notification be sent?',
authorization: myToken
})
.end((error, res) => {
stub.restore();
expect(res).to.have.status(500);
done();
});
});

it('Should fake notification error', (done) => {
const stub = sinon.stub(Notification, 'create').throws(new Error());
chai.request(app)
.post('/api/v1/comments')
.send({
request_id: 2,
comment: 'Can a notification be sent?',
authorization: myToken
})
.end((error, res) => {
stub.restore();
expect(res).to.have.status(201);
expect(res.body.status).to.deep.equal('success');
expect(res.body.data).to.be.an('object');
expect(res.body.data).to.have
.keys('comment', 'createdAt', 'delete_status', 'id', 'request_id', 'updatedAt', 'user_id');
expect(res.body.message).to.deep.equal('Could not send notification.');
done();
});
});
});
});

0 comments on commit e7b9624

Please sign in to comment.