Skip to content

Commit

Permalink
[Feature #166241007] Search Functionality Added to Authors Haven
Browse files Browse the repository at this point in the history
  • Loading branch information
UhiriweAudace committed Jun 28, 2019
1 parent 3f97aab commit 24cf29a
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 35 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"nyc": {
"exclude": [
"src/config/passportSetup.js",
"src/sequelize/**/*.js"
"src/sequelize/**/*.js",
"test/**/*.js"
]
}
}
23 changes: 0 additions & 23 deletions src/api/controllers/articlesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,6 @@ class articlesController {
* @return {object} returns array of articles
*/
static async getAllArticle(req, res) {
const { page, limit } = req.query;
const pageNumber = parseInt(page, 10);
const limitNumber = parseInt(limit, 10);
if (
typeof pageNumber === 'number'
&& typeof limitNumber === 'number'
&& typeof page !== 'undefined'
&& typeof limit !== 'undefined'
) {
if (pageNumber <= 0 || limitNumber <= 0) {
return res.status(400).json({
error: 'Invalid request'
});
}
const offset = limitNumber * (pageNumber - 1);
const foundArticles = await Article.findAll({
limit: limitNumber,
offset
});
return res.json({
data: foundArticles
});
}
const allArticle = await articles.getAllArticle();

if (!allArticle[0]) {
Expand Down
13 changes: 5 additions & 8 deletions src/api/routes/articlesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import articlesController from '../controllers/articlesController';
import Auth from '../../middleware/auth';
import check from '../../middleware/checkOwner';
import validateBody from '../../middleware/validateBody';
import search from '../../middleware/search';
import commentsController from '../controllers/comments';
import comment from '../../middleware/validComment';
import RatingController from '../controllers/ratingController';
Expand All @@ -12,7 +13,7 @@ import isNotBlocked from '../../middleware/articleNotBlocked';
import isThisArticleBlocked from '../../middleware/isThisArticleBlocked';
import bookmarkController from '../controllers/bookmark';
import checkLikesandDislikes from '../../middleware/checkLikesDislikes';

import paginate from '../../middleware/paginate';

const articlesRouter = Router();
const {
Expand All @@ -33,17 +34,17 @@ const { verifyToken, checkIsModerator } = Auth;
const { createRatings, UpdateRatings } = RatingController;
const { bookmark } = bookmarkController;


const { searchForArticle } = search;
const {
createComment, editComment, deleteComment, getComment, commentAcomment,
likeComment, dislikeComment, countLikes, countDislikes, commentHistory
likeComment, dislikeComment, countLikes, countDislikes
} = commentsController;
const { checkComment, checkParameter, articleExists } = comment;
const { liked, disliked } = checkLikesandDislikes;

articlesRouter
.post('/', verifyToken, validateBody('createArticle'), createArticle)
.get('/', getAllArticle);
.get('/', paginate, searchForArticle, getAllArticle);

articlesRouter
.get('/:slug', slugExist, isThisArticleBlocked, getOneArticle)
Expand Down Expand Up @@ -83,10 +84,6 @@ articlesRouter.get('/comments/:commentId/likes', checkParameter, countLikes);
articlesRouter.post('/:slug/bookmark', verifyToken, slugExist, bookmark);

articlesRouter.post('/:slug/report', verifyToken, validateBody('checkComment'), slugExist, reportArticle);
// get comment edit history

articlesRouter.get('/comments/:commentId/history', verifyToken, checkParameter, commentHistory);


// block reported articles
articlesRouter.post('/:slug/block', verifyToken, checkIsModerator, validateBody('checkDescription'), slugExist, isAlreadBlocked, blockArticle);
Expand Down
32 changes: 32 additions & 0 deletions src/middleware/paginate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import db from '../sequelize/models';

const { Article } = db;

const paginate = async (req, res, next) => {
const { page, limit } = req.query;
const pageNumber = parseInt(page, 10);
const limitNumber = parseInt(limit, 10);
if (
typeof pageNumber === 'number'
&& typeof limitNumber === 'number'
&& typeof page !== 'undefined'
&& typeof limit !== 'undefined'
) {
if (pageNumber <= 0 || limitNumber <= 0) {
return res.status(400).json({
error: 'Invalid request'
});
}
const offset = limitNumber * (pageNumber - 1);
const foundArticles = await Article.findAll({
limit: limitNumber,
offset
});
return res.json({
data: foundArticles
});
}
next();
};

export default paginate;
198 changes: 198 additions & 0 deletions src/middleware/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/* eslint-disable no-prototype-builtins */
import sequelize from 'sequelize';
import models from '../sequelize/models';

const { Op } = sequelize;
const { User, Article } = models;
/**
* @description search by different parameters
*/
class search {
/**
* @param {object} req - Request.
* @param {object} res - Response.
* @param {function} next - passing to other middlewares
* @returns {object} - Contains an article information.
*/
static async searchForArticle(req, res, next) {
const {
title, author, keywords, tag
} = req.query;

if (!Object.keys(req.query).length) {
return next();
}

if (!title && !tag && !author && !keywords) {
return res.status(400).send({ error: 'You made a Bad Request!' });
}

if (author && !keywords && !tag && !title) {
// check if the author has a value and has at least three characters
if (author.length < 3) return res.status(400).send({ error: 'You should have provided at least 3 characters long for author\'s name' });
// @find the author
const result = await User.findOne({
where: { username: { [Op.iLike]: `%${author}%` } }
});
if (result === null) {
return res.status(404).send({
error: `This Author with username of ${author} not exists!`
});
}

// @find All article written by the found Author
const response = await Article.findAll({
where: { authorId: result.dataValues.id },
include: [
{
as: 'author',
model: User,
attributes: ['username', 'bio', 'image']
}
],
attributes: [
'slug',
'title',
'description',
'readtime',
'body',
'tagList',
'updatedAt',
'createdAt'
]
});

if (!response[0]) {
return res.status(404).send({
error: `Author : ${author} - doesn't have any article, so far!`
});
}

// @returning the response
return res.status(200).send({
message: `Here's All article written by Author who is like ${author}`,
data: response
});
}

if (title && !author && !tag && !keywords) {
// check if the title has at least three characters
if (title.length < 3) return res.status(400).send({ error: 'You should have provided at least 3 characters long for title' });

const titleFound = await Article.findAll({
where: { title: { [Op.iLike]: `%${title}%` } },
include: [
{
as: 'author',
model: User,
attributes: ['username', 'bio', 'image']
}
],
attributes: [
'slug',
'title',
'description',
'readtime',
'body',
'readtime',
'tagList',
'updatedAt',
'createdAt'
]
});
if (!titleFound[0]) {
return res.status(200).send({
error: 'No Articles with that title, so far!'
});
}

return res
.status(200)
.send({
message: `Here's All Articles which has the same title like this ${title}`,
data: titleFound
});
}

if (!title && !author && tag && !keywords) {
// check if the tag has at least three characters
if (tag.length < 3) return res.status(400).send({ error: 'You should have provided at least 3 characters long for tag' });

const tagFound = await Article.findAll({
where: { tagList: { [Op.contains]: [tag.toLowerCase()] } },
include: [
{
as: 'author',
model: User,
attributes: ['username', 'bio', 'image']
}
],
attributes: [
'slug',
'title',
'description',
'readtime',
'body',
'readtime',
'tagList',
'updatedAt',
'createdAt'
]
});
if (!tagFound[0]) {
return res.status(200).send({
error: 'No Articles with that tag, so far!'
});
}

return res
.status(200)
.send({
message: `Here's All Articles which has the same tag like this ${tag}`,
data: tagFound
});
}

if (!title && !author && !tag && keywords) {
// check if the keyword has at least three characters
if (keywords.length < 3) return res.status(400).send({ error: 'You should have provided at least 3 characters long for keywords' });

const keywordFound = await Article.findAll({
where: {
[Op.or]: [
{ title: { [Op.iLike]: `%${keywords.toLowerCase()}%` } },
{ body: { [Op.iLike]: `%${keywords.toLowerCase()}%` } },
{ description: { [Op.iLike]: `%${keywords.toLowerCase()}%` } },
{ tagList: { [Op.contains]: [keywords.toLowerCase()] } }
]
},
attributes: [
'slug',
'title',
'description',
'readtime',
'body',
'readtime',
'tagList',
'updatedAt',
'createdAt'
]
});
if (!keywordFound[0]) {
return res.status(200).send({
error: 'No Articles with that Keyword found, so far!'
});
}

return res
.status(200)
.send({
data: keywordFound
});
}

next();
}
}

export default search;
Loading

0 comments on commit 24cf29a

Please sign in to comment.