Skip to content

Commit

Permalink
Merge 8b07ee0 into 3fb9877
Browse files Browse the repository at this point in the history
  • Loading branch information
truestbyheart committed Jul 4, 2019
2 parents 3fb9877 + 8b07ee0 commit 1d463bb
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 10 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"devDependencies": {
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"chai-like": "^1.1.1",
"coveralls": "^3.0.3",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^13.1.0",
Expand All @@ -50,6 +51,7 @@
"babel-plugin-istanbul": "^5.1.2",
"bcrypt": "^3.0.6",
"body-parser": "^1.18.3",
"chai-things": "^0.2.0",
"cloudinary": "^1.14.0",
"cors": "^2.8.5",
"dotenv": "^8.0.0",
Expand Down
70 changes: 68 additions & 2 deletions src/api/controllers/articleController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import models from '../models';
import statusCodes from '../../helpers/constants/status.codes';
import errorMessage from '../../helpers/constants/error.messages';
import articleValidator from '../../helpers/validators/articleValidator';
import errorSender from '../../helpers/error.sender';
import generatePagination from '../../helpers/generate.pagination.details';

const { Article, Category } = models;
const { CREATED } = statusCodes;
Expand All @@ -25,8 +27,8 @@ export default class ArticleController {
/**
* register a new
* @static
* @param {*} req the request
* @param {*} res the response to be sent
* @param {Object} req the request
* @param {Object} res the response to be sent
* @memberof ArticleController
* @returns {Object} res
*/
Expand Down Expand Up @@ -75,6 +77,70 @@ export default class ArticleController {
});
}

/**
* This function gets all the articles that are stored in the article table
*
* @static
* @param {Object} req the request
* @param {Object} res the response to be sent
* @memberof Articles
* @returns {Object} res
*/
static async getArticles(req, res) {
// default constants
const defaultLimit = 10;
const defaultOffset = 0;
const result = {};
const emptyArticleArray = 0;

// const page = req.query.page || 1;
const limit = req.query.limit || defaultLimit;
const offset = req.query.offset || defaultOffset;
const articles = await Article.findAndCountAll({
offset,
limit
});

result.status = 200;
result.pagedArticles = generatePagination(articles.count, articles.rows, offset, limit);
result.Articles = articles.rows;
if (articles.rows.length > emptyArticleArray) {
res.status(statusCodes.OK).json({
result
});
} else {
res.status(statusCodes.NOT_FOUND).json({
status: 404,
message: 'There no more articles at the moment.'
});
}
}

/**
* This function gets a specific article using slug as the search keyword
*
* @static
* @param {Object} req the request
* @param {Object} res the response to be sent
* @memberof Articles
* @returns {Object} res
*/
static async getArticle(req, res) {
const { slug } = req.params;
const article = await Article.findOne({
where: { slug }
});

if (article) {
res.status(statusCodes.OK).json({
status: 200,
article
});
} else {
errorSender(statusCodes.NOT_FOUND, res, 'Article', errorMessage.noArticles);
}
}

/**
* allow an author to update his/her article
*
Expand Down
2 changes: 2 additions & 0 deletions src/api/routes/articleRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ articleRouter.post('/:slug/rating',
checkExistingRates.ExistingRating,
ratingsController.rateArticle);

articleRouter.get('/', articleController.getArticles);
articleRouter.get('/:slug', articleController.getArticle);
articleRouter.patch('/:slug',
uploadImage.single('coverImage'),
checkValidToken,
Expand Down
67 changes: 62 additions & 5 deletions src/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,8 @@
}
}
}
},
}
},
"/articles/{slug}": {
"patch": {
"tags": ["Articles"],
Expand Down Expand Up @@ -448,13 +449,69 @@
"description": "Please you must be the owner of this Article in order to modify it, Thanks"
}
}
},
}
},
"/articles/": {
"get": {
"tags": [
"Articles"
],
"summary": "Get a list of all articles",
"description": "",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"parameters": [
{
"in": "query",
"name": "page",
"description": "",
"required": true
}
],
"responses": {
"200": {
"description": "Profile updated correctly"
"description": "Return a list of articles"
},
"400": {
"description": "Invlid input(s)"
"404": {
"description": "There are no articles at the moment, Please try again later"
},
"default": {
"description": "Something went wrong"
}
}
}
},
"articles/{slug}": {
"get": {
"tags": [
"Articles"
],
"summary": "Get a single articles",
"description": "",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"parameters": [
{
"in": "path",
"name": "slug",
"description": "",
"required": true
}
],
"responses": {
"200": {
"description": "Return a single articles"
},
"404": {
"description": "Not found"
},
"default": {
"description": "Something went wrong"
Expand Down
6 changes: 3 additions & 3 deletions src/helpers/constants/error.messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ export default {
unkownEmail: "A user with the provided email doesn't exist",
invalidLink: 'Invalid link provided',
incorectPassword: 'Incorect password provided',
emailLinkInvalid:
'The link provided is corrupt, please request a new one or try to click it again',
emailLinkInvalid: 'The link provided is corrupt, please request a new one or try to click it again',
noUser: "User doesn't exist.",
authenticationMessage: 'You have to login to perform this action.',
serverError: 'Something went wrong',
Expand All @@ -27,5 +26,6 @@ export default {
authorisation: 'A token must be provided',
token: 'Invalid token provided',
ratingsNotFound: 'No ratings found for this article',
notOwner: 'Please you must be the owner of this Article in order to modify it, Thanks'
notOwner: 'Please you must be the owner of this Article in order to modify it, Thanks',
noArticles: 'Article not found!'
};
76 changes: 76 additions & 0 deletions tests/articles.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import '@babel/polyfill';
import chai from 'chai';
import chaihttp from 'chai-http';
import chailike from 'chai-like';
import chaithing from 'chai-things';
import server from '../src/index';
import status from '../src/helpers/constants/status.codes';
import errorMessage from '../src/helpers/constants/error.messages';

chai.use(chaihttp);
chai.use(chailike);
chai.use(chaithing);
chai.should();

describe('GET /articles/:slug', () => {
it('Should return the article', (done) => {
chai
.request(server)
.get('/api/articles/How-to-create-sequalize-seeds')
.end((err, res) => {
res.should.have.a.status(status.OK);
res.body.should.be.an('object');
res.body.should.have.property('article');
res.body.article.should.property('title', 'How to create sequalize seeds');
done();
});
});

it('Should return a message when article not found', (done) => {
chai
.request(server)
.get('/api/articles/How-to-create-sequalize-seed')
.end((err, res) => {
res.should.have.a.status(status.NOT_FOUND);
res.body.should.be.an('object');
res.body.errors.Article.should.be.eq(errorMessage.noArticles);
done();
});
});
});

describe('GET /articles', () => {
it('Should respond with a list of articles', (done) => {
chai
.request(server)
.get('/api/articles')
.end((err, res) => {
res.should.have.a.status(status.OK);
res.body.result.Articles.should.be.an('array');
res.body.result.should.have.property('Articles');
res.body.result.Articles.should.contain.something.like({
id: 1,
title: 'How to create sequalize seeds',
description: 'How to set dummy data automatically',
body:
'Suppose we want to insert some data into a few tables by default. If we follow up on previous example we can consider creating a demo user for User table.To manage all data migrations you can use seeders. Seed files are some change in data that can be used to populate database table with sample data or test data.Let\'s create a seed file which will add a demo user to our User table.',
slug: 'How-to-create-sequalize-seeds',
coverImage: 'default.jpeg',
tagList: ['postgres', 'express', 'sequelize'],
author: 1,
category: 1
});
done();
});
});
it('Should respond with a message if there no more articles', (done) => {
chai
.request(server)
.get('/api/articles/?offset=10&limit=10')
.end((err, res) => {
res.should.have.a.status(status.NOT_FOUND);
res.body.should.have.property('message', 'There no more articles at the moment.');
done();
});
});
});

0 comments on commit 1d463bb

Please sign in to comment.