Skip to content

Commit

Permalink
#165412920 article rating pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
sengayire committed Jun 12, 2019
1 parent 6076e1d commit 46d6a4d
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 4 deletions.
42 changes: 42 additions & 0 deletions src/controllers/RatingController.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,47 @@ class RatingController {
article: rating
});
}

/**
* @param {object} req Request sent to the route
* @param {object} res Response from server
* @returns {object} Object representing the response returned
*/
static async sortArticlesByRating(req, res) {
const { limit, offset } = req.query;
const articles = await Article.rate.sort(parseInt(limit, 0) || 20, offset || 0, {
keyword: req.query.keyword,
author: req.query.author,
tag: req.query.tag
});
return articles.length >= 1 && !!articles
? res.status(status.OK).send({
articles,
articlesCount: articles.length
})
: res.status(status.NOT_FOUND).send({ message: 'No articles found' });
}

/**
* @param {object} req Request sent to the route
* @param {object} res Responfromse server
* @returns {object} Object representing the response returned
*/
static async ArticleRatings(req, res) {
const { limit, offset } = req.query;
const articleRatings = await Article.rate.articleRatings(
parseInt(limit, 0) || 20,
offset || 0,
req.article.id
);
return Object.keys(articleRatings).length
? res.status(status.OK).send({
articleRatings,
articlesCount: articleRatings.length
})
: res.status(status.NOT_FOUND).send({ message: 'No rating for this article' });
}
}

// validation
export default RatingController;
3 changes: 2 additions & 1 deletion src/queries/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import * as User from './users';
import * as Article from './articles';
import * as Token from './tokens';
import * as Tag from './tags';
import * as Rating from './ratings';
import * as Notification from './notifications';
import * as Chat from './chats';
import * as Gallery from './gallery';
import { getAllRatings, createRatings } from './readingStats';

export {
User, Token, Chat, Notification, Gallery
User, Token, Chat, Notification, Gallery, Rating
};

export {
Expand Down
21 changes: 21 additions & 0 deletions src/queries/ratings/getAll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import db from '../../models';

export default async (limit, offset, articleId) => {
const allRatings = await db.Rating.findAll({
limit,
offset,
where: {
articleId
},
logging: false,
attributes: ['id', 'rating', 'createdAt'],
include: [
{
model: db.User,
as: 'author',
attributes: ['username', 'firstName', 'lastName', 'bio', 'image', 'createdAt']
}
]
});
return allRatings;
};
4 changes: 3 additions & 1 deletion src/queries/ratings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import update from './update';
import get from './get';
import findAll from './findAll';
import findAllByArticle from './findAllByArticle';
import sort from './sortArticlesByRatings';
import articleRatings from './getAll';

export {
create, update, get, findAll, findAllByArticle
create, update, get, findAll, findAllByArticle, sort, articleRatings
};
29 changes: 29 additions & 0 deletions src/queries/ratings/sortArticlesByRatings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import db from '../../models';
import * as filters from '../../helpers/searchArticleFilters';

/**
* Get specific article ratings
* @param {object} limit limit for query
* @param {object} offset offset for query
* @param {object} condition contains author, tag and keyword to filter query
* @returns {object} Object representing the response returned
*/
export default async (limit, offset, { keyword, author, tag }) => {
const where = filters.filterQueryBuilder({ keyword, author, tag });
const paginate = { limit, offset };
let response = [];
response = await db.Article.findAll({
paginate,
where,
order: [['rating', 'DESC']],
logging: false,
include: [
{
model: db.User,
as: 'author',
attributes: ['username', 'bio', 'image']
}
]
});
return response;
};
3 changes: 2 additions & 1 deletion src/queries/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import getAllUser from './getAllUser';
import * as follow from '../follows';

export {
create, findOne, update, findOrCreate, follow, getAllUser, permissions
create, findOne, update, findOrCreate
};
export { getAllUser, permissions, follow };
2 changes: 1 addition & 1 deletion src/routes/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const router = express.Router();
router.use(articles);
router.use('/users/roles', roles);
router.use(tags);
router.use(rating);
router.use('/articles', comments);
router.use('/users', users);
router.use('/chats', chats);
Expand All @@ -28,7 +29,6 @@ router.use('/article', report);
router.use('/permissions', permissions);
router.use(highlights);
router.use('/notifications', notifications);
router.use(rating);
router.use('/user', readingStats);

export default router;
12 changes: 12 additions & 0 deletions src/routes/api/rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Router } from 'express';
import RatingController from '../../controllers/RatingController';
import asyncHandler from '../../middlewares/asyncHandler';
import checkArticleBySlug from '../../middlewares/checkArticleBySlug';
import validateArticle from '../../middlewares/validation/articles';
import validateRating from '../../middlewares/validation/validateRating';
import verifyToken from '../../middlewares/verifyToken';
import checkPermissions from '../../middlewares/checkPermissions';
Expand All @@ -21,5 +22,16 @@ rating.post(
);

rating.get('/rating/:slug/article', checkArticleBySlug, asyncHandler(RatingController.get));
rating.get(
'/rating/articles',
validateArticle.pagination,
asyncHandler(RatingController.sortArticlesByRating)
);

rating.get(
'/rating/:slug/articles',
checkArticleBySlug,
validateArticle.pagination,
asyncHandler(RatingController.ArticleRatings)
);
export default rating;
20 changes: 20 additions & 0 deletions src/tests/controllers/RatingController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,24 @@ describe('ARTICLE RATINGS', () => {
done();
});
});
it('sort articles by rating', (done) => {
chai
.request(app)
.get('/api/v1/rating/articles?limit=1&offset=0')
.end((err, res) => {
expect(res).to.have.status(status.OK);
res.body.should.be.an('object');
done();
});
});
it("sort article's rating", (done) => {
chai
.request(app)
.get(`/api/v1/rating/${createdArticle.dataValues.slug}/articles?limit=1&offset=0`)
.end((err, res) => {
expect(res).to.have.status(status.OK);
res.body.should.be.an('object');
done();
});
});
});

0 comments on commit 46d6a4d

Please sign in to comment.