-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
346 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import model from '../db/models/index'; | ||
|
||
const { Users, Articles, Rating } = model; | ||
|
||
/** | ||
* rating controller | ||
*/ | ||
class ArticleManager { | ||
/** | ||
* | ||
* @param {Object} req | ||
* @param {Object} res | ||
* @returns {Object} return object | ||
*/ | ||
static async rateArticle(req, res) { | ||
const { slug } = req.params; | ||
const { rating } = req.body; | ||
|
||
const findArticle = await Articles.findOne({ where: { slug } }); | ||
if (!findArticle) { | ||
return res.status(404).send({ | ||
error: 'Article not found!' | ||
}); | ||
} | ||
const findUser = await Users.findOne({ where: { email: req.user.email } }); | ||
|
||
if (findUser.id === findArticle.postedBy) { | ||
return res.status(400).json({ | ||
error: 'You can not rate your article!' | ||
}); | ||
} | ||
|
||
const findIfUserRatedArticle = await Rating.findOne({ | ||
where: { | ||
user: findUser.id, | ||
articleId: findArticle.id | ||
} | ||
}); | ||
if (findIfUserRatedArticle) { | ||
return res.status(400).json({ | ||
error: 'You have already rated this article' | ||
}); | ||
} | ||
|
||
const articleRatings = await Rating.findOne({ where: { articleId: findArticle.id, rating } }); | ||
if (articleRatings == null) { | ||
const saveRating = await Rating.create({ | ||
rating, | ||
user: findUser.id, | ||
articleId: findArticle.id | ||
}); | ||
return res.status(201).json({ | ||
message: 'Article rated successfuly', | ||
data: { | ||
user: saveRating.user, | ||
rating: saveRating.rating | ||
}, | ||
}); | ||
} | ||
return res.status(400).json({ error: 'You cannot rate article twice' }); | ||
} | ||
} | ||
export default ArticleManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
'use strict'; | ||
module.exports = { | ||
up: (queryInterface, Sequelize) => { | ||
return queryInterface.createTable('Ratings', { | ||
id: { | ||
allowNull: false, | ||
primaryKey: true, | ||
type: Sequelize.UUID | ||
}, | ||
rating: { | ||
type: Sequelize.INTEGER, | ||
allowNull: false | ||
}, | ||
user: { | ||
type: Sequelize.INTEGER, | ||
allowNull: false, | ||
onDelete: 'CASCADE', | ||
references: { | ||
model: 'Users', | ||
key: 'id', | ||
as: 'user' | ||
} | ||
}, | ||
articleId: { | ||
type: Sequelize.INTEGER, | ||
allowNull: false, | ||
onDelete: 'CASCADE', | ||
references: { | ||
model: 'Articles', | ||
key: 'id', | ||
as: 'articleId' | ||
} | ||
}, | ||
createdAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.fn('now') | ||
}, | ||
updatedAt: { | ||
allowNull: false, | ||
type: Sequelize.DATE, | ||
defaultValue: Sequelize.fn('now') | ||
} | ||
}); | ||
}, | ||
down: (queryInterface, Sequelize) => { | ||
return queryInterface.dropTable('Ratings'); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,4 @@ module.exports = (sequelize, DataTypes) => { | |
// associations can be defined here | ||
}; | ||
return BlacklistTokens; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use strict'; | ||
module.exports = (sequelize, DataTypes) => { | ||
const Rating = sequelize.define('Rating', { | ||
id: { | ||
type: DataTypes.UUID, | ||
allowNull: false, | ||
primaryKey: true, | ||
defaultValue: DataTypes.UUIDV4 | ||
}, | ||
rating: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false | ||
}, | ||
user: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false | ||
}, | ||
articleId: { | ||
type: DataTypes.INTEGER, | ||
allowNull: false | ||
} | ||
}, {}); | ||
Rating.associate = (models) => { | ||
Rating.belongsTo(models.Users, { | ||
foreignKey: 'user', | ||
targetKey: 'id' | ||
}); | ||
Rating.belongsTo(models.Articles, { | ||
foreignKey: 'articleId', | ||
targetKey: 'id' | ||
}); | ||
}; | ||
return Rating; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import Joi from '@hapi/joi'; | ||
|
||
/** | ||
* rating article validaton | ||
*/ | ||
class ArticleValidation { | ||
/** | ||
* @param {object} req | ||
* @param {object} res | ||
* @param {object} next | ||
* @returns {Object} ratingSchema object | ||
*/ | ||
static async rating(req, res, next) { | ||
const ratingSchema = Joi.object().keys({ | ||
rating: Joi.number().integer().valid('1', '2', '3', '4', '5').label('Rate') | ||
.required() | ||
}); | ||
const { | ||
rating | ||
} = req.body; | ||
const rate = { | ||
rating | ||
}; | ||
const checkRating = Joi.validate(rate, ratingSchema, { | ||
abortEarly: false | ||
}); | ||
if (checkRating.error) { | ||
const Errors = []; | ||
for (let i = 0; i < checkRating.error.details.length; i += 1) { | ||
Errors.push(checkRating.error.details[i].message.replace('"', ' ').replace('"', ' ')); | ||
} | ||
return res.status(400).json({ Errors }); | ||
} | ||
req.rate = checkRating.value; | ||
next(); | ||
} | ||
} | ||
export default ArticleValidation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.