Skip to content

Commit

Permalink
Merge pull request #104 from andela/ch-reading-stats-fix-response
Browse files Browse the repository at this point in the history
Ch fix reading stats
  • Loading branch information
jnkindi authored and mwibutsa committed Jun 21, 2019
2 parents af40c22 + 656378b commit b9e7999
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 83 deletions.
8 changes: 6 additions & 2 deletions controllers/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,16 @@ class Article {
});
} else {
const { id: articleid } = article;
const [, created] = await ArticleReadingStats.findOrCreate({
const count = await ArticleReadingStats.count({
where: { userid: req.user, articleid }
});
if (created) {

if (count === 0) {
await ArticleModel.addViewer(articleid);
}
await ArticleReadingStats.destroy({ where: { userid: req.user, articleid } });
await ArticleReadingStats.create({ userid: req.user, articleid });

let categoryName = 'Other';
const getCategory = await ArticleCategoryModel.findOne({
where: { id: article.category }
Expand Down
141 changes: 68 additions & 73 deletions controllers/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,27 @@ const logError = debug('app:*');
*/
class Search {
/**
* @author: Innocent Nkunzi
* @param {*} req character
* @param {*} res array
* @returns {*} match
*/
* @author: Innocent Nkunzi
* @param {*} req character
* @param {*} res array
* @returns {*} match
*/
static async systemSearch(req, res) {
let { keyword, tag, author } = req.query;
keyword = createSearchKeyword(keyword);
tag = createSearchKeyword(tag);
tag = tag.split(' ');
author = createSearchKeyword(author);
const { Op } = Sequelize;
try {
const searchTag = await articleModel.findAll({
attributes: {
exclude: ['id', 'authorid'],
exclude: ['id', 'authorid']
},
where: {
taglist: {
[Op.contains]: [tag],
},
},
[Op.contains]: tag
}
}
});
const searchAuthor = await UserModel.findAll({
attributes: {
Expand All @@ -47,130 +47,125 @@ class Search {
'email_notifications',
'role',
'createdAt',
'updatedAt',
],
'updatedAt'
]
},
where: {
[Op.or]: {
firstname: {
[Op.iLike]: {
[Op.any]: author,
},
[Op.any]: author
}
},
lastname: {
[Op.iLike]: {
[Op.any]: author,
},
[Op.any]: author
}
},
username: {
[Op.iLike]: {
[Op.any]: author,
},
[Op.any]: author
}
},
email: {
[Op.iLike]: {
[Op.any]: author,
},
[Op.any]: author
}
},
bio: {
[Op.iLike]: {
[Op.any]: author,
},
[Op.any]: author
}
},
image: {
[Op.iLike]: {
[Op.any]: author,
},
},
},
},
[Op.any]: author
}
}
}
}
});

const searchArticle = await articleModel.findAll({
include: [{
model: UserModel,
attributes: {
exclude: [
'password',
'verified',
'inapp_notifications',
'email_notifications',
'provideruserid',
'provider',
],
},
},],
include: [
{
model: UserModel,
attributes: {
exclude: [
'password',
'verified',
'inapp_notifications',
'email_notifications',
'provideruserid',
'provider'
]
}
}
],
where: {
[Op.or]: {
title: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
slug: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
body: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
description: {
[Op.iLike]: {
[Op.any]: keyword,
},
},
},
},
[Op.any]: keyword
}
}
}
}
});
const searchUser = await UserModel.findAll({
attributes: {
exclude: [
'id',
'provider',
'provideruserid',
'password',
'createdAt',
'updatedAt',
],
exclude: ['id', 'provider', 'provideruserid', 'password', 'createdAt', 'updatedAt']
},
where: {
[Op.or]: {
firstname: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
lastname: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
email: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
username: {
[Op.iLike]: {
[Op.any]: keyword,
},
[Op.any]: keyword
}
},
bio: {
[Op.iLike]: {
[Op.any]: keyword,
},
},
},
},
[Op.any]: keyword
}
}
}
}
});
return res.status(200).json({
searchArticle,
searchUser,
searchTag,
searchAuthor,
searchAuthor
});
} catch (error) {
logError(error);
Expand Down
46 changes: 42 additions & 4 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import select from 'lodash';
import Sequelize from 'sequelize';
import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';
import moment from 'moment';
import mailLinkMaker from '../helpers/mailLinkMaker';
import model from '../models/index';
import Mailer from '../helpers/mailer';
Expand Down Expand Up @@ -30,6 +31,7 @@ const {
notifications: notificationModel,
articlereadingstats: ArticleReadingStats,
roleassignment: AssignRoleModel,
article: ArticleModel,
} = model;

/**
Expand Down Expand Up @@ -70,7 +72,7 @@ class User {
};
await UserVerificationModel.create(verification);

let userAccount = select.pick(result, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified']);
let userAccount = select.pick(result, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified', 'role']);
const token = helper.generateToken(userAccount);
userAccount = select.pick(result, ['username', 'email', 'bio', 'image']);
return helper.authenticationResponse(res, token, userAccount);
Expand Down Expand Up @@ -103,7 +105,7 @@ class User {
// verify password
if (user && helper.comparePassword(password, user.password)) {
// return user and token
let userAccount = select.pick(user, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified']);
let userAccount = select.pick(user, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified', 'role']);
const token = helper.generateToken(userAccount);
userAccount = select.pick(user, ['username', 'email', 'bio', 'image']);
return helper.authenticationResponse(res, token, userAccount);
Expand Down Expand Up @@ -163,7 +165,7 @@ class User {
verified: true
};
const result = await UserModel.socialUsers(ruser);
let userAccount = select.pick(result, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified']);
let userAccount = select.pick(result, ['id', 'firstname', 'lastname', 'username', 'email', 'image', 'verified', 'role']);
const token = helper.generateToken(userAccount);
userAccount = select.pick(result, ['username', 'email', 'bio', 'image']);
return res.redirect(`${process.env.FRONTEND_URL}?token=${token}`);
Expand Down Expand Up @@ -483,7 +485,43 @@ class User {
if (!stats || stats.length === 0) {
return helper.jsonResponse(res, 404, { message: 'No article read' });
}
return helper.jsonResponse(res, 200, { stats, statsCount: stats.length });
const allStats = await Promise.all(
stats.map(async (singleStat) => {
const user = await UserModel.findOne({ attributes: { exclude: ['password'] }, where: { id: singleStat.authorid } });
const article = await ArticleModel.findOne({ where: { id: singleStat.articleid } });
return {
id: singleStat.id,
articleid: singleStat.articleid,
userid: singleStat.userid,
article,
user,
createdAt: singleStat.createdAt,
updatedAt: singleStat.updatedAt
};
})
);
const today = moment();
const startWeekDate = today.startOf('week').format('YYYY-MM-DD');
const endWeekDate = today.endOf('week').format('YYYY-MM-DD');
const startMonthDate = today.startOf('month').format('YYYY-MM-DD');
const endMonthDate = today.endOf('month').format('YYYY-MM-DD');
const thisWeekRead = await ArticleReadingStats.count({
where: {
userid: req.user,
createdAt: {
$between: [startWeekDate, endWeekDate]
}
}
});
const thisMonthRead = await ArticleReadingStats.count({
where: {
userid: req.user,
createdAt: {
$between: [startMonthDate, endMonthDate]
}
}
});
return helper.jsonResponse(res, 200, { statsArticles: allStats, thisWeekRead, thisMonthRead });
} catch (error) {
return helper.jsonResponse(res, 400, { error });
}
Expand Down
2 changes: 1 addition & 1 deletion models/articlereadingstats.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ArticleReadingStatsModel = (Sequelize, DataTypes) => {
freezeTableName: true, // Model tableName will be the same as the model name
});
ArticleReadingStats.readingStats = async (type, id) => {
let query = `SELECT articlereadingstats.*, articles.title FROM articlereadingstats, articles WHERE articlereadingstats.userid = ${id} AND articles.authorid = articlereadingstats.userid AND articlereadingstats.articleid = articles.id`;
let query = `SELECT articles.*, articlereadingstats.* FROM articlereadingstats, articles WHERE articlereadingstats.userid = ${id} AND articles.authorid = articlereadingstats.userid AND articlereadingstats.articleid = articles.id ORDER BY articlereadingstats.id DESC`;
if (type === 'article') {
query = `SELECT articlereadingstats.*, users.username FROM articlereadingstats, users WHERE articlereadingstats.articleid = ${id} AND articlereadingstats.userid = users.id`;
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"lodash": "^4.17.11",
"method-override": "^2.3.10",
"methods": "^1.1.2",
"moment": "^2.24.0",
"morgan": "^1.9.1",
"multer": "^1.4.1",
"multer-storage-cloudinary": "^2.2.1",
Expand Down Expand Up @@ -91,4 +92,4 @@
"prettier-stylelint": "^0.4.2",
"sinon": "^7.3.2"
}
}
}
3 changes: 1 addition & 2 deletions test/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ describe('Article commenting', () => {
.then((res) => {
res.should.have.status(200);
res.body.should.be.a('object');
res.body.should.have.property('stats');
res.body.should.have.property('statsCount');
res.body.should.have.property('statsArticles');
done();
})
.catch(err => err);
Expand Down

0 comments on commit b9e7999

Please sign in to comment.