Skip to content

Commit

Permalink
Merge 71259df into 7b9fc9b
Browse files Browse the repository at this point in the history
  • Loading branch information
omoefe-dukuye committed Mar 13, 2019
2 parents 7b9fc9b + 71259df commit 04b3038
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 43 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"fs": "0.0.1-security",
"joi": "^14.3.1",
"jsonwebtoken": "^8.3.0",
"loadash": "^1.0.0",
"lodash": "^4.17.11",
"methods": "^1.1.2",
"mongoose": "^5.2.2",
"mongoose-unique-validator": "^2.0.1",
Expand Down
23 changes: 22 additions & 1 deletion server/api/controllers/article.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Sequelize from 'sequelize';
import { createLogger, format, transports } from 'winston';
import { omit } from 'lodash';
import notifyFollowers from '../helpers/notification/followers';
import {
User, Article, LikeDislike, Tag, Rating, Category
User, Article, LikeDislike, Tag, Rating, Category, Comment
} from '../../models';
import {
getArticlesByAllParams, getArticlesBySearchTagParams, getArticlesBySearchAuthorParams,
Expand Down Expand Up @@ -529,9 +530,29 @@ export const getArticle = async (req, res) => {
message: 'Resource not found'
});
}
const comments = await Comment.findAll({
where: { articleId: { [Op.eq]: foundArticle.id } },
order: [['updatedAt', 'DESC']]
});

let articleComments = comments.map(async (comment) => {
const user = await User.findById(comment.userId, {
attributes: {
exclude: ['id', 'username', 'email', 'password',
'role', 'bio', 'imageUrl', 'verified', 'createdAt', 'updatedAt']
},
});

const editedComment = omit(comment.toJSON(), ['userId']);
editedComment.user = user.toJSON();
return editedComment;
});

articleComments = await Promise.all(articleComments);

foundArticle = foundArticle.toJSON();
foundArticle.readTime = getReadTime(foundArticle.body);
foundArticle.comments = articleComments;

return res.status(200).send({
status: 'success',
Expand Down
121 changes: 106 additions & 15 deletions server/api/controllers/comments.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,68 @@
import { omit } from 'lodash';
import {
Comment, Article, LikeComment, Sequelize
Comment,
User,
Article,
LikeComment,
Sequelize
} from '../../models';

import informBookmarkers from '../helpers/notification/bookmarkers';

const { Op } = Sequelize;
const {
Op
} = Sequelize;

export const postComment = async (req, res) => {
const { params: { articleId }, body: { commentBody }, user: { id: userId } } = req;
const {
params: {
articleId
},
body: {
commentBody
},
user: {
id: userId
}
} = req;
try {
const newComment = await Comment.create({ commentBody, articleId, userId });

let newComment = await Comment.create({
commentBody,
articleId,
userId
});
informBookmarkers(articleId, commentBody, userId);
return res.status(201).send({ status: 'success', data: newComment });

const comments = await Comment.findAll({
where: {
articleId: {
[Op.eq]: articleId
}
},
order: [['updatedAt', 'DESC']]
});

let allComments = comments.map(async (comment) => {
const user = await User.findById(comment.userId, {
attributes: {
exclude: ['id', 'username', 'email', 'password',
'role', 'bio', 'imageUrl', 'verified', 'createdAt', 'updatedAt']
},
});

const editedComment = omit(comment.toJSON(), ['userId']);
editedComment.user = user.toJSON();
return editedComment;
});

allComments = await Promise.all(allComments);
newComment = newComment.toJSON();
newComment.comments = allComments;

return res.status(201).send({
status: 'success',
data: newComment.comments
});
} catch (error) {
return res.status(500).send({
status: 'error',
Expand All @@ -23,7 +73,15 @@ export const postComment = async (req, res) => {
};

export const updateComment = async (req, res) => {
const { params: { articleId, commentId }, body: { commentBody } } = req;
const {
params: {
articleId,
commentId
},
body: {
commentBody
}
} = req;
try {
const foundArticle = await Article.findByPk(articleId);
if (!foundArticle) {
Expand All @@ -32,7 +90,13 @@ export const updateComment = async (req, res) => {
message: 'Article not found'
});
}
const foundComments = await foundArticle.getComments({ where: { id: { [Op.eq]: commentId } } });
const foundComments = await foundArticle.getComments({
where: {
id: {
[Op.eq]: commentId
}
}
});
const foundComment = foundComments[0];

if (!foundComment) {
Expand All @@ -49,8 +113,12 @@ export const updateComment = async (req, res) => {
});

// update the comment
const updatedComment = await foundComment.update({ commentBody },
{ returning: true, plain: true });
const updatedComment = await foundComment.update({
commentBody
}, {
returning: true,
plain: true
});

const oldComments = await updatedComment.getCommentHistories();
const comment = updatedComment.toJSON();
Expand Down Expand Up @@ -78,11 +146,24 @@ export const updateComment = async (req, res) => {
*/
export const deleteComment = async (req, res) => {
try {
const { params: { articleId, commentId }, user: { id: userId, role } } = req;
const {
params: {
articleId,
commentId
},
user: {
id: userId,
role
}
} = req;
const foundComment = await Comment.findOne({
where: {
id: { [Op.eq]: commentId },
articleId: { [Op.eq]: articleId },
id: {
[Op.eq]: commentId
},
articleId: {
[Op.eq]: articleId
},
}
});

Expand Down Expand Up @@ -130,10 +211,20 @@ export const deleteComment = async (req, res) => {
*/
export const likeComment = async (req, res) => {
try {
const { params: { commentId }, user: { id: userId } } = req;
const {
params: {
commentId
},
user: {
id: userId
}
} = req;

await LikeComment.findOrCreate({
where: { commentId, userId }
where: {
commentId,
userId
}
}).spread((like, created) => {
if (created) {
return res.status(201).send({
Expand Down
29 changes: 13 additions & 16 deletions server/api/controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,23 @@ export const socialLogin = async (req, res) => {
firstname, lastname, username, email, password, imageUrl
} = req.user;
try {
const [{ id, role }, isNew] = await User.findOrCreate({
const [{ id, role, isVerified }] = await User.findOrCreate({
where: { email },
defaults: {
firstname, lastname, username, password, imageUrl
}
});

let token;
const paramToken = isNew && signToken({ email }, '10m');
const paramToken = isVerified && signToken({ email }, '10m');

if (process.env.NODE_ENV === 'production' && isNew) {
if (process.env.NODE_ENV === 'production' && !isVerified) {
try {
await resetPasswordVerificationMail(username, email, paramToken);
} catch (error) {
logger.debug('Email Error::', error);
}
} else if (!isNew) {
} else if (!isVerified) {
token = signToken({
sid: req.sessionID,
id,
Expand All @@ -157,18 +157,15 @@ export const socialLogin = async (req, res) => {
});
}

return res.status(200).send({
status: 'success',
data: {
message: `${isNew ? `An email has been sent to ${email}. Follow contained instructions to verify your account and create password.` : 'Login Successful.'}`,
...(
isNew ? { link: `${req.protocol}://${req.headers.host}/api/users/resetPassword/${paramToken}` }
: {
token, username, email, role
}
)
}
});
const verifiedUrl = `dashboard#token${token}`;

return res.redirect(
`${process.env.REACT_ENDPOINT}/${
isVerified
? verifiedUrl
: 'signup?mailalert=true'
}`
);
} catch (e) {
return res.status(500).send({
status: 'fail',
Expand Down
10 changes: 7 additions & 3 deletions tests/article/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe('Tests for article resource', () => {

userToken4 = newToken;

const { body: { data: { id: newCommentId } } } = await chai.request(app)
const { body: { data: [{ id: newCommentId }] } } = await chai.request(app)
.post(`/api/articles/${articleId}/comments`)
.set('Authorization', `Bearer ${userToken}`)
.send({
Expand All @@ -182,7 +182,7 @@ describe('Tests for article resource', () => {
.set('Authorization', `Bearer ${userToken}`)
.send(comment);
const {
body: { data: { id: newCommentId, commentBody, articleId: returnedArticleId } }
body: { data: [{ id: newCommentId, commentBody, articleId: returnedArticleId }] }
} = res;
commentId = newCommentId;
expect(res).to.have.status(201);
Expand Down Expand Up @@ -768,6 +768,10 @@ describe('Tests for article resource', () => {
.set('Authorization', `Bearer ${userToken}`)
.send(mockArticle);
articleId = res.body.data.id;
await chai.request(app)
.post(`/api/articles/${articleId}/comments`)
.set('Authorization', `Bearer ${userToken}`)
.send(comment);
});

it('should return all articles', async () => {
Expand Down Expand Up @@ -837,7 +841,7 @@ describe('Tests for article resource', () => {
.post(`/api/articles/${articleId}/comments`)
.set('Authorization', `Bearer ${userToken}`)
.send(comment);
commentId = res.body.data.id;
commentId = res.body.data[0].id;
});

it('should update a comment', async () => {
Expand Down
22 changes: 14 additions & 8 deletions tests/auth/social-login.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import chai, { expect } from 'chai';
import chai, {
expect
} from 'chai';
import passport from 'passport';
import sinon from 'sinon';
import chaiHttp from 'chai-http';
import app from '../../index';
import models, { sequelize } from '../../server/models';
import { mockStrategy } from '../mocks/mockStrategy';
import models, {
sequelize
} from '../../server/models';
import {
mockStrategy
} from '../mocks/mockStrategy';
import mockRoles from '../mocks/mockRoles';

chai.use(chaiHttp);
Expand All @@ -18,17 +24,17 @@ describe('Test Cases for the social login endpoints', () => {

after((done) => {
Object.values(sequelize.models).map(function (model) {
return model.destroy({ where: {}, force: true });
return model.destroy({
where: {},
force: true
});
});
sequelize.queryInterface.sequelize.query('TRUNCATE TABLE session CASCADE;').then(() => done());
});

it('Should create account for user once platform returns payload', async () => {
const res = await chai.request(app)
.get('/api/users/google/redirect');
const { body: { status, data } } = res;
expect(res).to.have.status(200);
expect(data).to.have.property('link');
expect(status).to.eql('success');
expect(res).to.redirectTo('https://denethor-ah-frontend-staging.herokuapp.com/signup?mailalert=true');
});
});

0 comments on commit 04b3038

Please sign in to comment.