Skip to content

Commit

Permalink
feat(average-rating): display average rating on articles- update rati…
Browse files Browse the repository at this point in the history
…ng controller- update article migration- update article modelfinishes: 163589492
  • Loading branch information
tejiri4 committed Jan 30, 2019
1 parent 131cac1 commit 96b8f3d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 248 deletions.
20 changes: 16 additions & 4 deletions server/controllers/RatingController.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,16 @@ class RatingController {
return response(res, 400, 'failure', 'Rating should be between 1 and 5');
}

const rated = await Util.resourceExists(Rating, {
articleId: article.dataValues.id,
userId
const checkRating = await Rating.findAndCountAll({
where: {
articleId: article.dataValues.id
}
});
const { count } = checkRating;
const rated = checkRating.rows.find(data => data.userId === userId);
let totalRating = 0;
checkRating.rows.forEach((rateObj) => {
totalRating += rateObj.rating;
});
if (!rated) {
if (article.dataValues.userId === userId) return response(res, 403, 'failure', 'You cannot rate your own article');
Expand All @@ -129,16 +136,21 @@ class RatingController {
articleId: article.dataValues.id,
userId
});
totalRating += rate.dataValues.rating;
const averageRating = Math.round(totalRating / (count + 1));
Util.updateAverageRating(article, averageRating);
return response(res, 201, 'success', 'You have successfully rated this article', null, rate.dataValues);
}

const previousRating = rated.dataValues.rating;
if (previousRating === Number(rating)) {
return response(res, 200, 'success', 'You did not update the rating');
}
const newRating = await rated.update({
rating: Number(rating)
});
totalRating = ((totalRating - previousRating) + Number(rating));
const averageRating = Math.round(totalRating / (count));
Util.updateAverageRating(article, averageRating);
const { articleId, createdAt, updatedAt } = newRating.dataValues;
return response(
res, 200, 'success', 'You have successfully updated your rating', null,
Expand Down
14 changes: 14 additions & 0 deletions server/helpers/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ class Util {
return resource;
}

/**
* @static
* @description a function to ascertain if a resource exists
* @param {object} model Model to check for resource existence
* @param {object} data
* @returns {object} returns resource if true or null otherwise
*/
static async updateAverageRating(model, data) {
const updateArticle = await model.update({
averageRating: data
});
return updateArticle;
}

/**
* @description Util method used to send in-app notification to the user
* @static
Expand Down
4 changes: 4 additions & 0 deletions server/migrations/20190111130213-create-article.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export default {
userId: {
type: Sequelize.UUID
},
averageRating: {
type: Sequelize.INTEGER,
defaultValue: 0
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
Expand Down
4 changes: 4 additions & 0 deletions server/models/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export default (sequelize, DataTypes) => {
userId: {
type: DataTypes.UUID,
allowNull: false
},
averageRating: {
type: DataTypes.INTEGER,
defaultValue: 0
}
},
{
Expand Down
244 changes: 1 addition & 243 deletions server/test/controllers/comment.spec.js
Original file line number Diff line number Diff line change
@@ -1,252 +1,10 @@
// import chai, { expect } from 'chai';
// import chaiHttp from 'chai-http';
// import sinon from 'sinon';
// import app from '../../..';
// import db from '../../models';
// import { token, tokenTwo } from '../mockData/token';

// const { Article, Comment } = db;
// chai.use(chaiHttp);

// describe('Comment Model', () => {
// describe('Create a comment', () => {
// it('It should be able to create a comment', async () => {
// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.eqls(201);
// expect(response.body.status).to.eqls('success');
// expect(response.body.data.message).to.eqls('Comment created');
// });
// it('It should not be able to create a comment when content is empty', async () => {
// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: ''
// });
// expect(response.status).to.eqls(422);
// });
// it('It should be able to handle unexpected errors thrown during creating a comment', async () => {
// const stub = sinon
// .stub(Article, 'findOne')
// .callsFake(() => Promise.reject(new Error('Internal Server Error')));

// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.body.data.statusCode).to.equal(500);
// stub.restore();
// });
// it('It should return an error with incorrect token', async () => {
// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.equal(401);
// expect(response.body.status).to.equal('failure');
// });
// it('It should return an error when token is expired', async () => {
// const expiredToken = 'jdjdjdjdjdj';
// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${expiredToken}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.equal(401);
// expect(response.body.status).to.equal('failure');
// });
// });
// describe('Get comments for an article', () => {
// it('It should be able to get all comments', async () => {
// const response = await chai
// .request(app)
// .get('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(200);
// expect(response.body.status).to.eqls('success');
// expect(response.body.data.message).to.eqls('Comment found');
// });
// it('It should be able to get a single comment', async () => {
// const response = await chai
// .request(app)
// .get('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(200);
// expect(response.body.status).to.eqls('success');
// expect(response.body.data.message).to.eqls('Comment found');
// });
// it('It should not be able to get a single comment if comment id is wrong', async () => {
// const response = await chai
// .request(app)
// .get('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// });
// it('It should throw an error when article id is not found', async () => {
// const response = await chai
// .request(app)
// .get('/api/v1/articles/dhdhdhhdhdhhdhd/comments')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// });
// it('It should be able to handle unexpected errors thrown when getting a comment', async () => {
// const stub = sinon
// .stub(Article, 'findOne')
// .callsFake(() => Promise.reject(new Error('Internal Server Error')));

// const response = await chai
// .request(app)
// .post('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.body.data.statusCode).to.equal(500);
// stub.restore();
// });
// });
// describe('Update comment', () => {
// it('It should not be able to update a comment created by another user', async () => {
// const response = await chai
// .request(app)
// .put('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${tokenTwo}`)
// .send({
// content: 'Nice write up here'
// });
// expect(response.status).to.eqls(403);
// expect(response.body.status).to.eqls('failure');
// expect(response.body.data.message).to.eqls('You are not allowed to update another user\'s comment');
// });
// it('It should be able to update a comment created by only a user', async () => {
// const response = await chai
// .request(app)
// .put('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.eqls(200);
// expect(response.body.status).to.eqls('success');
// expect(response.body.data.message).to.eqls('Comment updated');
// });
// it('It should throw an error when you want to update a comment when comment id is wrong', async () => {
// const response = await chai
// .request(app)
// .put('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// });
// it('It should be able to handle unexpected errors thrown during updating a comment', async () => {
// const stub = sinon
// .stub(Comment, 'findOne')
// .callsFake(() => Promise.reject(new Error('Internal Server Error')));

// const response = await chai
// .request(app)
// .put('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.body.data.statusCode).to.equal(500);
// stub.restore();
// });
// it('It should not be able to update a comment when article dont has no comment', async () => {
// const response = await chai
// .request(app)
// .put('/api/v1/articles/95745c60-7b1a-11e8-9c9c-2d42b21b1a/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// expect(response.body.data.message).to.eqls('Comment not found for article id');
// });
// });
// describe('Delete comment', () => {
// it('It should not be able to delete a comment created by another user', async () => {
// const response = await chai
// .request(app)
// .delete('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${tokenTwo}`);
// expect(response.status).to.eqls(403);
// expect(response.body.status).to.eqls('failure');
// expect(response.body.data.message).to.eqls('You are not allowed to delete another user\'s comment');
// });
// it('It should not be able to delete a comment when article has no comment', async () => {
// const response = await chai
// .request(app)
// .delete('/api/v1/articles/95745c60-7b1a-11e8-9c9c-2d42b21b1a/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// expect(response.body.data.message).to.eqls('Comment not found for article id');
// });
// it('It should not be able to delete a comment when comment id is wrong', async () => {
// const response = await chai
// .request(app)
// .delete('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(404);
// expect(response.body.status).to.eqls('failure');
// });
// it('It should be able to delete a comment created by only a user', async () => {
// const response = await chai
// .request(app)
// .delete('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1a3e')
// .set('Authorization', `Bearer ${token}`);
// expect(response.status).to.eqls(200);
// expect(response.body.status).to.eqls('success');
// expect(response.body.data.message).to.eqls('Comment deleted');
// });
// it('It should be able to handle unexpected errors thrown during deleting a comment', async () => {
// const stub = sinon
// .stub(Comment, 'findOne')
// .callsFake(() => Promise.reject(new Error('Internal Server Error')));

// const response = await chai
// .request(app)
// .delete('/api/v1/articles/how-to-be-a-10x-dev-sGNYfURm/comments/09543c60-7b1a-11e8-9c9c-2d42b21b1')
// .set('Authorization', `Bearer ${token}`)
// .send({
// content: 'Nice write up'
// });
// expect(response.body.data.statusCode).to.equal(500);
// stub.restore();
// });
// });
// });


import chai, { expect } from 'chai';
import chaiHttp from 'chai-http';
import sinon from 'sinon';
import app from '../../..';
import db from '../../models';
import { token, tokenTwo } from '../mockData/token';

console.log(tokenTwo);
const { Article, Comment } = db;
chai.use(chaiHttp);

Expand Down
2 changes: 1 addition & 1 deletion server/test/controllers/ratingController.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ describe('Rating Model', () => {
});
it('Should handle unexpected errors thrown when updating or creating ratings', async () => {
const stub = sinon
.stub(Rating, 'findOne')
.stub(Article, 'findOne')
.callsFake(() => Promise.reject(new Error('Internal Server Error')));

const response = await chai
Expand Down

0 comments on commit 96b8f3d

Please sign in to comment.