Skip to content

Commit

Permalink
Merge ae116bd into 79025f2
Browse files Browse the repository at this point in the history
  • Loading branch information
habinezadalvan committed Oct 14, 2019
2 parents 79025f2 + ae116bd commit 9c3186f
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: node_js

node_js:
- 'stable'
- '10'

cache:
directories:
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"author": "Andela Simulations Programme",
"license": "MIT",
"dependencies": {
"3000": "^6.9.5",
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/node": "^7.5.5",
Expand All @@ -35,11 +36,13 @@
"express": "^4.17.1",
"express-async-errors": "^3.1.1",
"express-session": "^1.15.6",
"http": "0.0.0",
"joi": "^14.3.1",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.15",
"method-override": "^2.3.10",
"multer": "^1.4.2",
"ngrok": "^3.2.5",
"nyc": "^14.1.1",
"open": "^6.4.0",
"passport": "^0.4.0",
Expand All @@ -60,11 +63,6 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/node": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/register": "^7.5.5",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"coveralls": "^3.0.5",
Expand Down
163 changes: 112 additions & 51 deletions src/controllers/articles.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@ const { notifyViaEmailAndPush } = NotificationServices;
const util = new Util();

const db = models.Article;

/**
*
*
* @class Articles
*/
class Articles {
/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} data
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} data
* @memberof Articles
*/
static async createArticles(req, res) {
const userId = req.auth.id;
const findUser = await Userservice.getOneUser(userId);
Expand Down Expand Up @@ -67,14 +68,14 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} articles
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} articles
* @memberof Articles
*/
static async getAllArticles(req, res) {
const counter = await db.count();
if (req.offset >= counter) {
Expand All @@ -85,9 +86,33 @@ class Articles {
if (!articles) {
return res.status(200).json({ status: 200, message: 'There is no article.' });
}
const allArticles = _.map(articles, _.partialRight(_.pick, ['slug', 'title', 'description', 'body', 'taglist', 'favorited', 'favoritedcount', 'flagged', 'images', 'views']));

allArticles.map((article) => {
const allArticles = _.map(
articles,
_.partialRight(_.pick, [
'slug',
'title',
'description',
'body',
'taglist',
'favorited',
'favoritedcount',
'flagged',
'images',
'views'
])
);

const popularArticles = allArticles.slice(0);
popularArticles.sort((a, b) => b.views - a.views);
const mostPopular = popularArticles.slice(0, 9);

if (req.query.popular) {
util.setSuccess(200, 'The most popular articles on authors haven', mostPopular);
return util.send(res);
}

allArticles.map(async (article) => {
const readTime = Helper.calculateReadTime(article.body);
article.readtime = readTime;
return true;
Expand All @@ -102,25 +127,61 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} article
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} article
* @memberof Articles
*/
static async getOneArticle(req, res) {
const findArticle = await db.findOne({
where: { slug: req.params.slug }
});

if (!findArticle) {
return res.status(200).json({
status: 200,
message: 'That article does not exist!'
});
}
const article = _.pick(findArticle, ['slug', 'title', 'description', 'body', 'taglist', 'favorited', 'favoritedcount', 'flagged', 'images', 'views']);

const article = _.pick(findArticle, [
'slug',
'title',
'description',
'body',
'taglist',
'favorited',
'favoritedcount',
'flagged',
'images',
'views'
]);

let viewObject = {
slug: findArticle.slug,
title: findArticle.title,
description: findArticle.description,
body: findArticle.body,
flagged: findArticle.flagged,
favorited: findArticle.favorited,
favoritedcount: findArticle.favoritedcount,
images: findArticle.images,
views: 1
};
if (findArticle) {
viewObject = { ...viewObject, views: findArticle.views + 1 };
await db.update(viewObject, {
where: {
id: findArticle.id
},
returing: true
});
} else {
await db.create(viewObject);
}
const readTime = Helper.calculateReadTime(article.body);
article.readtime = readTime;
if (req.auth) {
Expand All @@ -137,14 +198,14 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} message
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {object} message
* @memberof Articles
*/
static async deleteArticle(req, res) {
const findArticle = await db.findOne({
where: { slug: req.params.slug }
Expand All @@ -171,14 +232,14 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} updated article details
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} updated article details
* @memberof Articles
*/
static async UpdateArticle(req, res) {
const findArticle = await db.findOne({
where: { slug: req.params.slug }
Expand Down Expand Up @@ -207,14 +268,14 @@ class Articles {
}

/**
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} share article over email and social media channelds
* @memberof Articles
*/
*
*
* @static
* @param {*} req
* @param {*} res
* @returns {Object} share article over email and social media channelds
* @memberof Articles
*/
static async shareArticle(req, res) {
const article = await db.findOne({
where: { slug: req.params.slug }
Expand Down
44 changes: 44 additions & 0 deletions src/helpers/viewArticle.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import models from '../models';
import Util from './util';

const util = new Util();
const db = models.Article;
const viewDb = models.View;

const viewArticleHelper = async (req, res, slug) => {
const findArticle = await db.findOne({ where: { slug } });
if (!findArticle) {
util.setError(404, 'That article does not exist');
util.send(res);
}
// find ip address
const ipAddress = req.header('x-forwarded-for') || req.connection.remoteAddress;

// check if the article was viewed
const findViewsOfArticle = await viewDb.findOne({ where: { articleId: findArticle.id } });

let viewObject = {
articleId: findArticle.id,
userId: req.auth ? req.auth.id : null,
IP_address: ipAddress,
userType: req.auth ? 'loggedInUser' : 'guest',
views: 1
};
// update or create article views
if (findViewsOfArticle) {
viewObject = { ...viewObject, views: findViewsOfArticle.views + 1 };
await viewDb.update(viewObject, {
where: {
articleId: findArticle.id
},
returing: true
});
} else {
await viewDb.create(viewObject);
}
return {
views: findViewsOfArticle.views
};
};

export default viewArticleHelper;
2 changes: 1 addition & 1 deletion src/middlewares/query.check.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const searchArticleQuerybuilder = (searchQueries) => {

export const checkQuery = (req, res, next) => {
let {
limit, page, ...searchQueries
limit, page, popular, ...searchQueries
} = req.query;
const validQueries = ['author', 'keyword', 'tag', 'title'];
let isValidRequest = true;
Expand Down
28 changes: 28 additions & 0 deletions src/middlewares/verifyIfTokenExists.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import env from 'dotenv';
import jwt from 'jsonwebtoken';

env.config();
const verifyIfTokenExists = async (req, res, next) => {
let token = req.headers['x-access-token'] || req.headers.authorization;
if (!token) {
next();
} else {
if (token.startsWith('Bearer ')) {
token = token.slice(7, token.length);
}
if (token) {
jwt.verify(token, process.env.SECRET_KEY, (err, decode) => {
if (err) {
return res.status(401).send({
status: 401,
message: 'Token is not valid'
});
}
req.token = token;
req.auth = decode;
next();
});
}
}
};
export default verifyIfTokenExists;
1 change: 1 addition & 0 deletions src/migrations/20190813125249-create-article.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ module.exports = {
},
views: {
type: Sequelize.INTEGER,
defaultValue: 0,
allowNull: true
},
createdAt: {
Expand Down
Loading

0 comments on commit 9c3186f

Please sign in to comment.