Skip to content

Commit

Permalink
Merge 4e9bbc7 into 01ffe66
Browse files Browse the repository at this point in the history
  • Loading branch information
adaezeodurukwe committed Mar 13, 2019
2 parents 01ffe66 + 4e9bbc7 commit 9430ec2
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 9 deletions.
31 changes: 31 additions & 0 deletions server/controllers/articleComment.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable object-shorthand */
import models from '../database/models';
import response from '../utils/response';
import { favouriteArticleNotification, HelperUtils } from '../utils';
Expand Down Expand Up @@ -167,6 +168,36 @@ class Comment {
});
}
}

/**
* @description highlights and comments on an article
* @param {*} req
* @param {*} res
* @returns {object} highlighted string and comment
*/
static async highlight(req, res) {
const userId = req.user.id;
const { highlighted, index, comment } = req.body;
const { body } = req.article;
const articleId = req.article.id;
try {
const valid = index === body.indexOf(highlighted);
if (valid !== true) return response(res).badRequest({ message: 'invalid highlight' });

const userComment = await ArticleComment.create({
articleId,
comment,
highlighted,
index,
userId });
return response(res).created({
message: 'Comment created successfully',
userComment
});
} catch (error) {
return response(res).serverError({ errors: { server: ['database error'] } });
}
}
}

export default Comment;
2 changes: 1 addition & 1 deletion server/database/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
test: {
use_env_variable: 'DATABASE_URL',
dialect: 'postgres',
logging: false
logging: true
},
production: {
use_env_variable: 'DATABASE_URL',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ export default {
type: Sequelize.TEXT,
allowNull: false,
},
highlighted: {
type: Sequelize.STRING,
allowNull: true,
},
index: {
type: Sequelize.INTEGER,
allowNull: true,
},
totalLikes: {
type: Sequelize.INTEGER,
defaultValue: 0,
Expand Down
16 changes: 10 additions & 6 deletions server/database/models/articlecomment.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
export default (sequelize, DataTypes) => {
const ArticleComment = sequelize.define('ArticleComment', {
articleId: DataTypes.INTEGER,
userId: DataTypes.INTEGER,
comment: DataTypes.TEXT,
totalLikes: DataTypes.INTEGER
}, {});
const ArticleComment = sequelize.define('ArticleComment',
{
articleId: DataTypes.INTEGER,
userId: DataTypes.INTEGER,
comment: DataTypes.STRING,
highlighted: DataTypes.STRING,
index: DataTypes.INTEGER,
totalLikes: DataTypes.INTEGER
},
{});
ArticleComment.associate = (models) => {
const { CommentEditHistory, Article, User } = models;
ArticleComment.belongsTo(User, {
Expand Down
36 changes: 36 additions & 0 deletions server/middlewares/ValidateBody.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Validate body

import { body, validationResult } from 'express-validator/check';

const highltght = [
body('highlighted')
.exists()
.withMessage('highlighted required')
.isLength({ min: 1 })
.withMessage('invalid highlighted text'),

body('comment')
.exists()
.withMessage('comment required')
.isLength({ min: 2 })
.withMessage('comment required'),

body('index')
.exists()
.withMessage('index required')
.isNumeric()
.withMessage('index should be a number')
];

const validationHandler = (req, res, next) => {
const errors = validationResult(req);

if (!errors.isEmpty()) {
return res.status(400).json({
status: 400, message: errors.array()[0].msg,
});
}
return next();
};

export { highltght, validationHandler };
4 changes: 3 additions & 1 deletion server/middlewares/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import ValidateUser from './ValidateUser';
import ValidateComment from './ValidateComment';
import AuthenticateArticle from './AuthenticateArticle';
import ValidateReport from './ValidateReport';
import * as Validate from './ValidateBody';

export {
AuthenticateUser,
ValidateUser,
ValidateComment,
AuthenticateArticle,
ValidateReport
ValidateReport,
Validate
};
9 changes: 8 additions & 1 deletion server/routes/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import express from 'express';
import { ArticleController, Comment } from '../controllers';
import createArticleValidation from '../validations/create-article';
import ArticleCommentLikeController from '../controllers/article-comment-like';
import { AuthenticateUser, ValidateComment, AuthenticateArticle } from '../middlewares';
import { AuthenticateUser, ValidateComment, AuthenticateArticle, Validate } from '../middlewares';
import rateArticleValidation from '../validations/rate-article';

const router = express.Router();
Expand All @@ -26,6 +26,13 @@ router.post('/articles/:slug/comment',
ValidateComment.validateComment,
Comment.postComment);

router.post('/articles/:slug/highlight',
AuthenticateUser.verifyUser,
AuthenticateArticle.verifyArticle,
Validate.highltght,
Validate.validationHandler,
Comment.highlight);

router.get('/articles/:slug/comments',
AuthenticateArticle.verifyArticle,
Comment.getComments);
Expand Down
98 changes: 98 additions & 0 deletions server/test/comment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,101 @@ describe('DELETE user comment', () => {
});
});
});

describe('POST highlighted comment /api/articles/:slug/highlight', () => {
const articleURL = '/api/articles';
let theArticleSlug = '';
it('should create an article', (done) => {
chai
.request(app)
.post(articleURL)
.set('Authorization', `Bearer ${userToken}`)
.send({
title: 'some title',
description: 'some weird talk',
body: 'article body'
})
.end((err, res) => {
theArticleSlug = res.body.article.slug;
done();
});
});

it('Should create a highlight', (done) => {
chai.request(app)
.post(`/api/articles/${theArticleSlug}/highlight`)
.set('authorization', `Bearer ${userToken}`)
.send({
highlighted: 'article',
index: 0,
comment: 'Just testing the highlight here'
})
.end((err, res) => {
expect(res.status).to.be.equal(201);
expect(res.body.message).to.be.equal('Comment created successfully');
done(err);
});
});

it('Should not create a highlight without an index', (done) => {
chai.request(app)
.post(`/api/articles/${theArticleSlug}/highlight`)
.set('authorization', `Bearer ${userToken}`)
.send({
highlighted: 'article',
comment: 'Just testing the highlight here'
})
.end((err, res) => {
expect(res.status).to.be.equal(400);
expect(res.body.message).to.be.equal('index required');
done(err);
});
});

it('Should not create a highlight if index is not a number', (done) => {
chai.request(app)
.post(`/api/articles/${theArticleSlug}/highlight`)
.set('authorization', `Bearer ${userToken}`)
.send({
highlighted: 'article',
index: 'boo',
comment: 'Just testing the highlight here'
})
.end((err, res) => {
expect(res.status).to.be.equal(400);
expect(res.body.message).to.be.equal('index should be a number');
done(err);
});
});

it('Should not create a highlight without a highlighted sring', (done) => {
chai.request(app)
.post(`/api/articles/${theArticleSlug}/highlight`)
.set('authorization', `Bearer ${userToken}`)
.send({
index: 0,
comment: 'Just testing the highlight here'
})
.end((err, res) => {
expect(res.status).to.be.equal(400);
expect(res.body.message).to.be.equal('highlighted required');
done(err);
});
});

it('Should not create a highlight when highlighted text is less than 1', (done) => {
chai.request(app)
.post(`/api/articles/${theArticleSlug}/highlight`)
.set('authorization', `Bearer ${userToken}`)
.send({
highlighted: '',
index: 0,
comment: 'Just testing the highlight here'
})
.end((err, res) => {
expect(res.status).to.be.equal(400);
expect(res.body.message).to.be.equal('invalid highlighted text');
done(err);
});
});
});

0 comments on commit 9430ec2

Please sign in to comment.