Skip to content

Commit

Permalink
Merge 93ed6b2 into 0723eb2
Browse files Browse the repository at this point in the history
  • Loading branch information
UhiriweAudace committed Jul 24, 2019
2 parents 0723eb2 + 93ed6b2 commit 7578928
Show file tree
Hide file tree
Showing 22 changed files with 753 additions and 106 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"regenerator-runtime": "^0.13.2",
"request": "^2.88.0",
"sequelize": "^5.8.7",
"sequelize-cli": "^5.5.0",
"slug": "^1.1.0",
"social-share": "^0.1.0",
"socket.io": "^2.2.0",
Expand Down
118 changes: 118 additions & 0 deletions src/api/controllers/category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import models from '../../sequelize/models';

const { Category, Article } = models;
/**
* @Author - Audace Uhiriwe
*/
class categoryController {
/**
* Admin - create a new category
* @param {object} req - Request.
* @param {object} res - Response.
* @returns {object} - returns a created article
*/
static async createCategory(req, res) {
// check if the category exists
const { categoryName } = req.body;
const categoryExists = await Category.findOne({ where: { categoryName } });
if (categoryExists) {
return res.status(400).send({ error: 'This category is already Exist!' });
}
const data = await Category.NewCategory(req.body);
return res.status(201).send({
message: `This category of ${categoryName} has been successfully added!`,
data
});
}

/**
* Admin - edit an existing category
* @param {object} req - Request.
* @param {object} res - Response.
* @returns {object} - returns an updated article
*/
static async editCategory(req, res) {
// check if the category exists
const { categoryName } = req.body;
const { id } = req.params;
const categoryExists = await Category.findAll({ where: { id } });
if (categoryExists[0].dataValues.categoryName === categoryName) {
return res.status(400).send({
error: 'This category is already exists, Nothing you changed!'
});
}
if (categoryExists === null) {
return res.status(404).send({ error: 'This category Not found!' });
}
const updateCategory = {
categoryName: categoryName || categoryExists[0].dataValues.categoryName
};
await Category.EditCategory(
updateCategory,
categoryExists[0].dataValues.id
);
return res.status(200).send({
message: `This category of ${categoryExists[0].dataValues.categoryName} has been successfully updated to ${categoryName}!`
});
}

/**
* Admin - delete an existing category
* @param {object} req - Request.
* @param {object} res - Response.
* @returns {object} - returns a message
*/
static async deleteCategory(req, res) {
const { id } = req.params;
// check if the category exists
const categoryExists = await Category.findOne({ where: { id } });
if (categoryExists === null) {
return res.status(404).send({ error: 'This category Not found!' });
}
await Category.destroy({ where: { id } });
return res.status(200).send({
message: 'This category has been successfully deleted!'
});
}

/**
* Admin - fetch all categories
* @param {object} req - Request.
* @param {object} res - Response.
* @returns {object} - returns an array of all categories
*/
static async getAllCategory(req, res) {
const categories = await Category.findAll();
if (categories === null) {
return res.status(200).send({ message: 'No Categories found, so far!' });
}
return res.status(200).send({
message: 'Here\'s all categories, so far!',
categories
});
}

/**
* Admin - fetch all articles related to a specific category
* @param {object} req - Request.
* @param {object} res - Response.
* @returns {object} - returns an array which contains all articles related to a specific category
*/
static async fetchAllArticles(req, res) {
const { categoryName } = req.params;
const category = await Category.findOne({ where: { categoryName } });
if (category === null) {
return res.status(404).send({ message: 'This Category Not found!' });
}
const articles = await Article.findAll({ where: { categoryName } });
if (!articles[0]) {
return res.status(200).send({ message: 'No Articles found with this Category, so far!' });
}
return res.status(200).send({
message: 'Here\'s all articles related to that category, so far!',
articles
});
}
}

export default categoryController;
27 changes: 27 additions & 0 deletions src/api/routes/categoryRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Router } from 'express';
import CategoryController from '../controllers/category';
import validateBody from '../../middleware/validateBody';
import Auth from '../../middleware/auth';

const categoryRouter = Router();
const { verifyToken, checkIsAdmin } = Auth;
const {
createCategory,
editCategory,
deleteCategory,
getAllCategory,
fetchAllArticles
} = CategoryController;

categoryRouter.post(
'/',
verifyToken,
checkIsAdmin,
validateBody('category'),
createCategory
);
categoryRouter.put('/:id', verifyToken, checkIsAdmin, editCategory);
categoryRouter.delete('/:id', verifyToken, checkIsAdmin, deleteCategory);
categoryRouter.get('/', getAllCategory);
categoryRouter.get('/:categoryName/articles', fetchAllArticles);
export default categoryRouter;
3 changes: 3 additions & 0 deletions src/api/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ratingsRouter from './ratingsRouter';
import bookmarkRouter from './bookmark';
import termsAndConditionsRouter from './termsConditionsRouter';
import chatRouter from './chatRouter';
import categoryRouter from './categoryRouter';

const api = express();

Expand All @@ -19,5 +20,7 @@ api.use('/ratings', ratingsRouter);
api.use('/bookmarks', bookmarkRouter);
api.use('/termsandconditions', termsAndConditionsRouter);
api.use('/chats', chatRouter);
api.use('/categories', categoryRouter);


export default api;
3 changes: 2 additions & 1 deletion src/helpers/articlesHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ArticlesHelper {
*/
static async createNewArticle(req) {
const {
title, body, description, tagList
title, body, description, tagList, categoryName
} = req.body;
const { id } = req.user;
const newSlug = this.createSlug(title);
Expand All @@ -43,6 +43,7 @@ class ArticlesHelper {
authorId: id,
readtime,
views: 0,
categoryName: categoryName || 'other'
});

// Uplooad article image
Expand Down
12 changes: 8 additions & 4 deletions src/helpers/validationSchemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ const password = Joi.string()
.trim()
.regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/)
.required()
.label('Password is required and must be at least 8 letters containing'
+ ' at least a number a Lowercase letter and an Uppercase letter');
.label('Password is required and must be at least 8 letters containing at least a number a Lowercase letter and an Uppercase letter');
const email = Joi.string()
.trim()
.lowercase()
Expand Down Expand Up @@ -143,14 +142,19 @@ export default {
.label('The comment should have at least 3 letters!'),
occurencyNumber: Joi.number()
.label('Occurrency should be a number')


}),
validateTerms: Joi.object().keys({
termsAndConditions: Joi.string()
.trim()
.min(10)
.required()
.label('Terms and Conditions are required are required and should at least have 10 letters')
}),
category: Joi.object().keys({
categoryName: Joi.string()
.trim()
.min(3)
.required()
.label('The category Name should be a string which has at least 3 characters and is required!')
})
};
6 changes: 5 additions & 1 deletion src/sequelize/migrations/20190613355309-create-article.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ module.exports = {
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
},
categoryName: {
type: Sequelize.STRING,
allowNull: false
},
}),
down: (queryInterface, Sequelize) => queryInterface.dropTable('Articles')
};
26 changes: 26 additions & 0 deletions src/sequelize/migrations/20190710111019-create-category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable no-unused-vars */
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Categories', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
categoryName: {
type: Sequelize.STRING
},
articleId: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}),
down: (queryInterface, Sequelize) => queryInterface.dropTable('Categories')
};
4 changes: 4 additions & 0 deletions src/sequelize/models/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ module.exports = (sequelize, DataTypes) => {
views: {
type: DataTypes.INTEGER
},
categoryName: {
type: DataTypes.STRING,
allowNull: false
},
},
{}
);
Expand Down
18 changes: 18 additions & 0 deletions src/sequelize/models/category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* eslint-disable no-unused-vars */
/* eslint-disable func-names */
module.exports = (sequelize, DataTypes) => {
const Category = sequelize.define('Category', {
categoryName: DataTypes.STRING,
articleId: DataTypes.INTEGER
}, {});

Category.NewCategory = data => Category.create({ categoryName: data.categoryName });
Category.EditCategory = (data, id) => Category.update(
{ categoryName: data.categoryName },
{ where: { id } }
);
Category.associate = function (models) {
// associations can be defined here
};
return Category;
};
19 changes: 18 additions & 1 deletion src/sequelize/seeders/20190618062925-test-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module.exports = {
lastName: 'Audace',
username: 'Audace',
email: 'u.audace@gmail.com',
password: 'Uhiriwe1!',
password: '$2b$08$GCULzAkfmfB/fGyZrnfMSeFG.KdYasuBa2r7z1n.CUFy.KrdnOUdi',
bio: '',
avatar: '',
cover: '',
Expand All @@ -72,6 +72,23 @@ module.exports = {
updatedAt: new Date(),
roles: ['user']
},
{
firstName: 'Uhiriwe1',
lastName: 'Audace1',
username: 'Audace1',
email: 'u1.audace@gmail.com',
password: '$2b$08$/.eqmrkBU5fqgXJon0f33O.q.D7khNyqX8/oIFXy5Jxy/Pjtc4euW',
bio: '',
avatar: '',
dateOfBirth: '12/12/1999',
gender: '',
provider: '',
socialId: '',
verified: 'true',
createdAt: new Date(),
updatedAt: new Date(),
roles: ['admin']
},
{
firstName: 'Eric',
lastName: 'Prestein',
Expand Down
9 changes: 6 additions & 3 deletions src/sequelize/seeders/20190620204605-articles-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module.exports = {
createdAt: new Date(),
updatedAt: new Date(),
readtime: '2 min',
views: 0
views: 0,
categoryName: 'other'
},
{
slug: '73H99992',
Expand All @@ -24,7 +25,8 @@ module.exports = {
createdAt: new Date(),
updatedAt: new Date(),
readtime: '1min',
views: 0
views: 0,
categoryName: 'other'
},
{
slug: 'This_is_andela_2433546h34',
Expand All @@ -36,7 +38,8 @@ module.exports = {
createdAt: new Date(),
updatedAt: new Date(),
authorId: 4,
views: 0
views: 0,
categoryName: 'other'
}
]),

Expand Down
Loading

0 comments on commit 7578928

Please sign in to comment.