diff --git a/src/app.js b/src/app.js index df3536e..e0c65c2 100644 --- a/src/app.js +++ b/src/app.js @@ -7,7 +7,7 @@ import { mock } from './middlewares/validators/socialLogin-mock'; const app = express(); -if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') { +if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') { app.use(mock); } logging(); diff --git a/src/controllers/likes.controller.js b/src/controllers/likes.controller.js new file mode 100644 index 0000000..4fc4f41 --- /dev/null +++ b/src/controllers/likes.controller.js @@ -0,0 +1,183 @@ +import likeService from '../services/likes.service'; +import Util from '../helpers/util'; + +const util = new Util(); +/** + * @author codepirates + * @exports LikesController + * @class ArticleController + * @description Handles all related articles functioanlities + * */ +class LikesController { + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @returns {object} response + * @static + */ + static async unlike(req, res) { + try { + if (req.body.likeId) { + const prof = { + status: 'neutral', + claps: 0, + }; + const like = await likeService.updateLikes(prof, req.body.likeId); + const newLike = { + status: like[1].status, + claps: like[1].claps, + ArticleSlug: like[1].ArticleSlug, + }; + util.setSuccess(200, 'Successfully unliked', newLike); + return util.send(res); + } + util.setError(401, 'you cant unlike article you did not like'); + return util.send(res); + } catch (error) { + util.setError(500, 'server error contact admin'); + return util.send(res); + } + } + + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @returns {object} response + * @static + */ + static async dislike(req, res) { + try { + if (req.body.author === req.body.userId) { + util.setError(401, 'You can not dislike to your own post'); + return util.send(res); + } + if (!req.body.likeId) { + const prof = { + userId: req.body.userId, + ArticleSlug: req.params.Article, + status: 'dislike', + claps: 0, + }; + const like = await likeService.createLikes(prof); + const newLike = { + status: like.status, + claps: like.claps, + ArticleSlug: like.ArticleSlug, + }; + util.setSuccess(200, 'Successfully disliked', newLike); + return util.send(res); + } + const prof = { + status: 'dislike', + claps: 0, + }; + if (req.body.status === 'dislike') { + prof.status = 'neutral'; + } + const like = await likeService.updateLikes(prof, req.body.likeId); + const newLike = { + status: like[1].status, + claps: like[1].claps, + ArticleSlug: like[1].ArticleSlug, + }; + util.setSuccess(200, 'Successfully disliked', newLike); + return util.send(res); + } catch (error) { + util.setError(500, 'server error contact admin'); + return util.send(res); + } + } + + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @returns {object} response + * @static + */ + static async clap(req, res) { + try { + if (req.body.author === req.body.userId) { + util.setError(401, 'You can not clap to your own post'); + return util.send(res); + } + if (req.body.likeId) { + const prof = { + status: 'like', + claps: req.body.claps + 1, + }; + const like = await likeService.updateLikes(prof, req.body.likeId); + const newLike = { + status: like[1].status, + claps: like[1].claps, + ArticleSlug: like[1].ArticleSlug, + }; + util.setSuccess(200, 'Successfully claped', newLike); + return util.send(res); + } + const prof = { + userId: req.body.userId, + ArticleSlug: req.params.Article, + status: 'like', + claps: 1, + }; + const like = await likeService.createLikes(prof); + const newLike = { + status: like.status, + claps: like.claps, + ArticleSlug: like.ArticleSlug, + }; + util.setSuccess(200, 'Successfully claped', newLike); + return util.send(res); + } catch (error) { + util.setError(500, 'server error contact admin'); + return util.send(res); + } + } + + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @returns {object} response + * @static + */ + static async getDislikes(req, res) { + try { + const dislike = await likeService.getAllADislike(req.params.Article); + if (dislike) { + const data = { + dislikes: dislike.count, + }; + util.setSuccess(200, 'Dislike retrieved successfully', data); + return util.send(res); + } + } catch (error) { + util.setError(400, 'server error contact admin'); + return util.send(res); + } + } + + /** + * @param {object} req - Request object + * @param {object} res - Response object + * @returns {object} response + * @static + */ + static async getClaps(req, res) { + try { + const claps = await likeService.getAllAClaps(req.params.Article); + if (claps) { + const data = { + clapers: claps.count, + claps: Object.values(claps)[1], + }; + util.setSuccess(200, 'Claps retrieved successfully', data); + return util.send(res); + } + } catch (error) { + util.setError(400, 'server error contact admin'); + return util.send(res); + } + } +} + +export default LikesController; diff --git a/src/controllers/profile.controller.js b/src/controllers/profile.controller.js index 9f3ed2c..e44c258 100644 --- a/src/controllers/profile.controller.js +++ b/src/controllers/profile.controller.js @@ -59,9 +59,9 @@ class Profile { async (err, image) => { try { const userName = req.auth.email; - const user = await UserService.findOne(userName, ''); - const oldURL = user.image; - if (!user) { + const User = await UserService.findOne(userName, ''); + const oldURL = User.image; + if (!User) { util.setError(400, 'User not found'); return util.send(res); } diff --git a/src/middlewares/auth.js b/src/middlewares/auth.js index 1ba16d5..599874e 100644 --- a/src/middlewares/auth.js +++ b/src/middlewares/auth.js @@ -41,8 +41,6 @@ const validateToken = async (req, res, next) => { req.token = token; req.auth = decode; next(); - - return decode; }); } else { return res.status(400).send({ diff --git a/src/middlewares/likes.middleware.js b/src/middlewares/likes.middleware.js new file mode 100644 index 0000000..90890db --- /dev/null +++ b/src/middlewares/likes.middleware.js @@ -0,0 +1,41 @@ +import Util from '../helpers/util'; +import models from '../models/index'; + +const util = new Util(); + +export default async (req, res, next) => { + try { + const user = await models.user.findOne({ where: { email: req.auth.email } }); + if (!user) { + util.setError(404, 'you are anonimous'); + return util.send(res); + } + const userId = user.id; + const ArticleSlug = req.params.Article; + const post = await models.Article.findOne({ where: { slug: ArticleSlug } }); + + if (!post) { + util.setError(404, 'post not found'); + return util.send(res); + } + const like = await models.Likes.findOne({ where: { ArticleSlug, userId } }); + if (!like) { + req.body.author = post.authorId; + req.body.userId = userId; + req.body.likeId = null; + req.body.claps = null; + req.body.author = post.authorId; + next(); + } else { + req.body.author = post.authorId; + req.body.likeId = like.id; + req.body.claps = like.claps; + req.body.userId = userId; + req.body.status = like.status; + next(); + } + } catch (error) { + util.setError(500, 'server error'); + return util.send(res); + } +}; diff --git a/src/migrations/20190816132215-create-likes.js b/src/migrations/20190816132215-create-likes.js new file mode 100644 index 0000000..a9ee9b3 --- /dev/null +++ b/src/migrations/20190816132215-create-likes.js @@ -0,0 +1,54 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Likes', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + ArticleSlug: { + type: Sequelize.STRING, + allowNull: false, + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + references: { + model: 'Articles', + key: 'slug' + } + }, + claps: { + allowNull: false, + type: Sequelize.INTEGER, + defaultValue: 0 + }, + userId: { + type: Sequelize.INTEGER, + onDelete: 'CASCADE', + onUpdate: 'CASCADE', + references: { + model: 'users', + key: 'id' + } + }, + status: { + type: Sequelize.ENUM, + values: ['like', 'dislike', 'neutral'], + defaultValue: 'neutral' + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Likes'); + } +}; + diff --git a/src/models/article.js b/src/models/article.js index 99c89b1..701606b 100644 --- a/src/models/article.js +++ b/src/models/article.js @@ -18,7 +18,7 @@ module.exports = (sequelize, DataTypes) => { targetKey: 'id', onUpdate: 'CASCADE', onDelete: 'CASCADE' - }) + }); }; return Article; }; diff --git a/src/models/likes.js b/src/models/likes.js new file mode 100644 index 0000000..361647f --- /dev/null +++ b/src/models/likes.js @@ -0,0 +1,25 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + const Likes = sequelize.define('Likes', { + ArticleSlug: DataTypes.STRING, + userId: DataTypes.INTEGER, + claps: DataTypes.INTEGER, + status: DataTypes.ENUM({ + values: ['like', 'dislike', 'neutral'] + }) + }, {}); + Likes.associate = (models) => { + Likes.belongsTo(models.user, { + foreignKey: 'userId', + onDelete: 'CASCADE', + onUpdate: 'CASCADE' + }); + Likes.belongsTo(models.Article, { + foreignKey: 'ArticleSlug', + targetKey: 'slug', + onDelete: 'CASCADE', + onUpdate: 'CASCADE' + }); + }; + return Likes; +}; diff --git a/src/routes/api/index.route.js b/src/routes/api/index.route.js index a2a5a9b..8f97dc8 100644 --- a/src/routes/api/index.route.js +++ b/src/routes/api/index.route.js @@ -7,6 +7,7 @@ import oauth from './oauth/oauth.routes'; import user from './user/user.route'; import article from './article/article.routes'; import profile from './profile/profile.route'; +import likes from './likes/likes.routes'; import rate from './rate/rate.route'; import Comments from './comment/comments.route'; @@ -16,6 +17,7 @@ router.use('/images', express.static(path.join(__dirname, 'images'))); router.use('/comments', Comments); router.use(oauth); router.use('/profile', profile); +router.use('/likes', likes); router.use('/users', user); router.use('/', article); router.use('/rate', rate); diff --git a/src/routes/api/likes/doc.yml b/src/routes/api/likes/doc.yml new file mode 100644 index 0000000..8692d55 --- /dev/null +++ b/src/routes/api/likes/doc.yml @@ -0,0 +1,173 @@ +/likes/clap/{articleslug}: + put: + summary: clap for an article + description: > + slap for an article which is not yours + tags: + - Like + produces: + - application/json + parameters: + - name: x-access-token + in: header + schema: + type: string + required: + - authorization + responses: + 200: + description: OK + schema: + $ref: '#definitions/success' + 404: + $ref: '#responses/Notfound' + 401: + $ref: '#responses/BadRequest' + 400: + $ref: '#responses/BadRequest' +/likes/claps/{articleslug}: + get: + summary: get all claps + description: > + get all claps for an article + tags: + - Like + produces: + - application/json + parameters: + - name: x-access-token + in: header + schema: + type: string + required: + - authorization + responses: + 200: + description: Claps retrieved successfully + schema: + $ref: '#definitions/success' + 404: + $ref: '#responses/Notfound' + 401: + $ref: '#responses/BadRequest' + 400: + $ref: '#responses/BadRequest' +/likes/dislikes/{articleslug}: + get: + summary: get all cdislikes + description: > + get all dislike for an article + tags: + - Like + produces: + - application/json + parameters: + - name: x-access-token + in: header + schema: + type: string + required: + - authorization + responses: + 200: + description: Dislike retrieved successfully + schema: + $ref: '#definitions/success' + 404: + $ref: '#responses/Notfound' + 401: + $ref: '#responses/BadRequest' + 400: + $ref: '#responses/BadRequest' +/likes/dislike/{articleslug}: + put: + summary: dislike an article + description: > + dislike an existing article which is not yours + tags: + - Like + produces: + - application/json + parameters: + - name: x-access-token + in: header + schema: + type: string + required: + - authorization + responses: + 200: + description: Successfully disliked + schema: + $ref: '#definitions/success' + 404: + $ref: '#responses/Notfound' + 401: + $ref: '#responses/BadRequest' + 400: + $ref: '#responses/BadRequest' +/likes/unlike/{articleslug}: + put: + summary: Unlike an article + description: > + unlike the article you arleady liked or disked + tags: + - Like + produces: + - application/json + parameters: + - name: x-access-token + in: header + schema: + type: string + required: + - authorization + responses: + 200: + description: Successfully unliked + schema: + $ref: '#definitions/success' + 404: + $ref: '#responses/Notfound' + 401: + $ref: '#responses/BadRequest' + 400: + $ref: '#responses/BadRequest' +tags: +- name: Like + description: Operations related to Article Claping and liking +responses: + success: + description: Success + schema: + $ref: '#/definitions/success' + BadRequest: + description: Bad request + schema: + $ref: '#/definitions/Error' + Notfound: + description: Not found + schema: + $ref: '#/definitions/Error' +definitions: + success: + type: object + properties: + status: + type: string + description: status code + message: + type: string + description: description of success + data: + type: string + description: data about success request + Error: + type: object + properties: + status: + type: string + description: status code + message: + type: string + description: description of error \ No newline at end of file diff --git a/src/routes/api/likes/likes.routes.js b/src/routes/api/likes/likes.routes.js new file mode 100644 index 0000000..f00da5b --- /dev/null +++ b/src/routes/api/likes/likes.routes.js @@ -0,0 +1,17 @@ +import express from 'express'; +import LikesController from '../../../controllers/likes.controller'; +import validateToken from '../../../middlewares/auth'; +import confirmEmaiAuth from '../../../middlewares/emailVarification.middleware'; +import isLike from '../../../middlewares/likes.middleware'; + +const router = express.Router(); +// greate edit a viewing profile handlers + +router.get('/claps/:Article', [validateToken, confirmEmaiAuth, isLike], LikesController.getClaps); +router.get('/dislikes/:Article', [validateToken, confirmEmaiAuth, isLike], LikesController.getDislikes); +router.put('/clap/:Article', [validateToken, confirmEmaiAuth, isLike], LikesController.clap); +router.put('/dislike/:Article', [validateToken, confirmEmaiAuth, isLike], LikesController.dislike); +router.put('/unlike/:Article', [validateToken, confirmEmaiAuth, isLike], LikesController.unlike); + + +export default router; diff --git a/src/routes/index.js b/src/routes/index.js index 9cfdbf4..445c596 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -38,9 +38,9 @@ const apiVersion = process.env.API_VERSION; const baseUrl = `/api/${apiVersion}`; router.get('/', (req, res) => res.status(200).json({ status: 200, data: 'Welcome to Authors Haven.' })); +router.use(article); router.use(baseUrl, api); router.use(oauth); -router.use(article); router.use(notfound); router.use(error); diff --git a/src/seeders/20190808074800-normal-user.js b/src/seeders/20190808074800-normal-user.js index 6508a0d..ef3080c 100644 --- a/src/seeders/20190808074800-normal-user.js +++ b/src/seeders/20190808074800-normal-user.js @@ -15,7 +15,18 @@ export default { verified: true, createdAt: new Date(), updatedAt: new Date() - } + }, + { + firstname: 'usertwo', + lastname: 'usertwo', + email: 'usertwo@gmail.com', + password: hashPassword, + username: 'usertwo', + role: 'normal', + verified: true, + createdAt: new Date(), + updatedAt: new Date() + }, ]), down: queryInterface => queryInterface.bulkDelete('users', null, {}) diff --git a/src/services/likes.service.js b/src/services/likes.service.js new file mode 100644 index 0000000..cd35dba --- /dev/null +++ b/src/services/likes.service.js @@ -0,0 +1,102 @@ +import Sequelize from 'sequelize'; +import models from '../models'; + +const db = models.Likes; + +/** + * + * + * @class LikeService + */ +class LikeService { + /** + * + * + * @static + * @param {*} ArticleSlug + * @returns {object} data + * @memberof LikeService + */ + static async getAllADislike(ArticleSlug) { + try { + const dislikes = await db.findAndCountAll({ + where: { + ArticleSlug: String(ArticleSlug), + status: 'dislike' + }, + attributes: { + exclude: ['id', 'userId', 'createdAt', 'updatedAt', 'status'] + }, + raw: true + }); + return dislikes; + } catch (error) { + throw error; + } + } + + /** + * + * + * @static + * @param {*} ArticleSlug + * @returns {object} data + * @memberof LikeService + */ + static async getAllAClaps(ArticleSlug) { + try { + const claps = await db.findAndCountAll({ + where: { + ArticleSlug: String(ArticleSlug), + status: 'like' + }, + attributes: [[Sequelize.fn('sum', Sequelize.col('claps')), 'total']], + }); + return claps; + } catch (error) { + throw error; + } + } + + /** + * + * + * @static + * @param {*} like + * @param {*} id + * @returns {Object} return db result object + * @memberof UserService + */ + static async updateLikes(like, id) { + try { + const { claps, status } = like; + return await db.update( + { + status: String(status), + claps: Number(claps), + }, + { where: { id: Number(id) }, returning: true, plain: true } + ); + } catch (error) { + throw error; + } + } + + /** + * + * + * @static + * @param {*} like + * @returns {Object} return db result object + * @memberof UserService + */ + static async createLikes(like) { + try { + return await db.create(like); + } catch (error) { + throw error; + } + } +} + +export default LikeService; diff --git a/test/like.test.js b/test/like.test.js new file mode 100644 index 0000000..cfa79eb --- /dev/null +++ b/test/like.test.js @@ -0,0 +1,312 @@ + +import 'dotenv/config'; +import { chai, server, expect } from './test-setup'; + +let usertoken, adminToken, mikeToken; + +describe('/likes and dislikes feature', () => { + it('should login first user ', (done) => { + chai + .request(server) + .post('/api/v1/users/login') + .send({ + email: 'user@gmail.com', + password: 'ASqw12345' + }) + .end((error, res) => { + if (error) done(error); + usertoken = `Bearer ${res.body.token}`; + expect(res.status).to.be.equal(200); + expect(res.body).to.have.deep.property('message'); + done(); + }); + }); + it('should login second user ', (done) => { + chai + .request(server) + .post('/api/v1/users/login') + .send({ + email: 'usertwo@gmail.com', + password: 'ASqw12345' + }) + .end((error, res) => { + if (error) done(error); + mikeToken = `Bearer ${res.body.token}`; + expect(res.status).to.be.equal(200); + expect(res.body).to.have.deep.property('message'); + done(); + }); + }); + it('should login an admin', (done) => { + chai + .request(server) + .post('/api/v1/users/login') + .send({ + email: 'admin@gmail.com', + password: 'ASqw12345' + }) + .end((error, res) => { + if (error) done(error); + adminToken = `Bearer ${res.body.token}`; + expect(res.status).to.be.equal(200); + expect(res.body).to.have.deep.property('message'); + done(); + }); + }); + + it('should throw an error when user not authenticated ', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', `21${usertoken}`) + .end((error, res) => { + if (error) done(error); + expect(res.status).to.be.equal(401); + expect(res.body).to.have.deep.property('message'); + done(); + }); + }); + + it('should not clap for your article', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', `${adminToken}`) + .end((error, res) => { + if (error) done(error); + expect(res.status).to.be.equal(401); + expect(res.body).to.have.deep.property('message'); + expect(res.body.message).to.deep.equal('You can not clap to your own post'); + done(); + }); + }); + it('should return not dislike your article ', (done) => { + chai + .request(server) + .put('/api/v1/likes/dislike/fakeslug') + .set('x-access-token', `${adminToken}`) + .end((error, res) => { + if (error) done(error); + expect(res.status).to.be.equal(401); + expect(res.body).to.have.deep.property('message'); + expect(res.body.message).to.deep.equal('You can not dislike to your own post'); + done(); + }); + }); + it('should not unlike the article you didnt like', (done) => { + chai + .request(server) + .put('/api/v1/likes/unlike/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(401); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status'); + expect(res.body.message).to.deep.equal('you cant unlike article you did not like'); + done(); + }); + }); + it('Should successfully clap for a certain article', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully claped'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(1); + expect(res.body.data.status).to.deep.equal('like'); + done(); + }); + }); + + it('Should successfully clap for a certain article second time', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully claped'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(2); + expect(res.body.data.status).to.deep.equal('like'); + done(); + }); + }); + + it('should unlike Article', (done) => { + chai + .request(server) + .put('/api/v1/likes/unlike/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully unliked'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(0); + expect(res.body.data.status).to.deep.equal('neutral'); + done(); + }); + }); + + it('should dislike Article', (done) => { + chai + .request(server) + .put('/api/v1/likes/dislike/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully disliked'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(0); + expect(res.body.data.status).to.deep.equal('dislike'); + done(); + }); + }); + it('second user should dislike Article', (done) => { + chai + .request(server) + .put('/api/v1/likes/dislike/fakeslug') + .set('Authorization', mikeToken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully disliked'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(0); + expect(res.body.data.status).to.deep.equal('dislike'); + done(); + }); + }); + it('should return all Dislike to a certain article ', (done) => { + chai + .request(server) + .get('/api/v1/likes/dislikes/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'data', 'status'); + expect(res.body.message).to.deep.equal('Dislike retrieved successfully'); + expect(res.body.data).to.have.keys('dislikes'); + done(); + }); + }); + it('should Unlike Article due to user try to dislike secomd time ', (done) => { + chai + .request(server) + .put('/api/v1/likes/dislike/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully disliked'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(0); + expect(res.body.data.status).to.deep.equal('neutral'); + done(); + }); + }); + + + it('should not unlike unexisting article', (done) => { + chai + .request(server) + .put('/api/v1/likes/unlike/fakesl') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(404); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status'); + expect(res.body.message).to.deep.equal('post not found'); + done(); + }); + }); + it('Should successfully clap to atricle for second user ', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', mikeToken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully claped'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(1); + expect(res.body.data.status).to.deep.equal('like'); + done(); + }); + }); + it('Should successfully clap for first user', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully claped'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(1); + expect(res.body.data.status).to.deep.equal('like'); + done(); + }); + }); + it('Should successfully clap second time for first user', (done) => { + chai + .request(server) + .put('/api/v1/likes/clap/fakeslug') + .set('x-access-token', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'status', 'data'); + expect(res.body.message).to.deep.equal('Successfully claped'); + expect(res.body.data).to.have.keys('ArticleSlug', 'status', 'claps'); + expect(res.body.data.claps).to.deep.equal(2); + expect(res.body.data.status).to.deep.equal('like'); + done(); + }); + }); + it('should return all claps to a certain article', (done) => { + chai + .request(server) + .get('/api/v1/likes/claps/fakeslug') + .set('Authorization', usertoken) + .end((error, res) => { + if (error) done(error); + expect(res).have.status(200); + expect(res).to.be.an('object'); + expect(res.body).to.have.keys('message', 'data', 'status'); + expect(res.body.message).to.deep.equal('Claps retrieved successfully'); + expect(res.body.data.clapers).to.deep.equal(2); + done(); + }); + }); +});