📦 NEW: backend: randomQuote Function

This commit is contained in:
Divlo 2020-04-22 12:21:02 +02:00
parent 88e4e8c0cc
commit f2df72fe29
8 changed files with 182 additions and 3 deletions

View File

@ -26,6 +26,7 @@ app.use('/users', require('./routes/users'));
app.use('/admin', require('./routes/admin')); app.use('/admin', require('./routes/admin'));
app.use('/favorites', require('./routes/favorites')); app.use('/favorites', require('./routes/favorites'));
app.use('/comments', require('./routes/comments')); app.use('/comments', require('./routes/comments'));
app.use('/quotes', require('./routes/quotes'));
/* Errors Handling */ /* Errors Handling */
app.use((_req, _res, next) => errorHandling(next, { statusCode: 404, message: "La route n'existe pas!" })); // 404 app.use((_req, _res, next) => errorHandling(next, { statusCode: 404, message: "La route n'existe pas!" })); // 404
@ -41,6 +42,7 @@ const Categories = require('./models/categories');
const Users = require('./models/users'); const Users = require('./models/users');
const Favorites = require('./models/favorites'); const Favorites = require('./models/favorites');
const Comments = require('./models/comments'); const Comments = require('./models/comments');
const Quotes = require('./models/quotes');
// A function has a category // A function has a category
Categories.hasOne(Functions, { constraints: true, onDelete: 'CASCADE'}); Categories.hasOne(Functions, { constraints: true, onDelete: 'CASCADE'});
@ -58,6 +60,10 @@ Comments.belongsTo(Users, { constraints: false });
Functions.hasMany(Comments); Functions.hasMany(Comments);
Comments.belongsTo(Functions, { constraints: false }); Comments.belongsTo(Functions, { constraints: false });
// Users can suggest new quotes
Users.hasMany(Quotes);
Quotes.belongsTo(Users, { constraints: false });
/* Server */ /* Server */
// sequelize.sync({ force: true }) // sequelize.sync({ force: true })
sequelize.sync() sequelize.sync()

View File

@ -8,6 +8,7 @@ const convertCurrencyOutput = require('./main/convertCurrency');
const calculateAgeOutput = require('./main/calculateAge'); const calculateAgeOutput = require('./main/calculateAge');
const heapAlgorithmOutput = require('./main/heapAlgorithm'); const heapAlgorithmOutput = require('./main/heapAlgorithm');
const convertEncodingOutput = require('./main/convertEncoding'); const convertEncodingOutput = require('./main/convertEncoding');
const randomQuote = require('./main/randomQuote');
const functionObject = { const functionObject = {
randomNumber : randomNumberOutput, randomNumber : randomNumberOutput,
@ -19,7 +20,8 @@ const functionObject = {
convertCurrency : convertCurrencyOutput, convertCurrency : convertCurrencyOutput,
calculateAge : calculateAgeOutput, calculateAge : calculateAgeOutput,
heapAlgorithm : heapAlgorithmOutput, heapAlgorithm : heapAlgorithmOutput,
convertEncoding : convertEncodingOutput convertEncoding : convertEncodingOutput,
randomQuote : randomQuote,
}; };
// Choisi la fonction à exécuter // Choisi la fonction à exécuter

View File

@ -0,0 +1,23 @@
const errorHandling = require('../../utils/errorHandling');
const { serverError } = require('../../config/errors');
const Quotes = require('../../../models/quotes');
const Users = require('../../../models/users');
const sequelize = require('../../utils/database');
module.exports = randomQuote = async ({ res, next }, _argsObject) => {
try {
const quote = await Quotes.findOne({
order: sequelize.random(),
include: [
{ model: Users, attributes: ["name", "logo"] }
],
attributes: {
exclude: ["isValidated"]
},
});
return res.status(200).json(quote);
} catch (error) {
console.log(error);
return errorHandling(next, serverError);
}
}

View File

@ -5,6 +5,8 @@ const errorHandling = require('../assets/utils/errorHandling');
const { serverError } = require('../assets/config/errors'); const { serverError } = require('../assets/config/errors');
const Functions = require('../models/functions'); const Functions = require('../models/functions');
const Categories = require('../models/categories'); const Categories = require('../models/categories');
const Quotes = require('../models/quotes');
const Users = require('../models/users');
const helperQueryNumber = require('../assets/utils/helperQueryNumber'); const helperQueryNumber = require('../assets/utils/helperQueryNumber');
const Sequelize = require('sequelize'); const Sequelize = require('sequelize');
const deleteFilesNameStartWith = require('../assets/utils/deleteFilesNameStartWith'); const deleteFilesNameStartWith = require('../assets/utils/deleteFilesNameStartWith');
@ -248,7 +250,7 @@ exports.putCategory = async (req, res, next) => {
category.name = name; category.name = name;
category.color = color; category.color = color;
const result = await category.save(); const result = await category.save();
return res.status(200).json({ message: "La catégorie a bien été modifié!", result }); return res.status(200).json({ message: "La catégorie a bien été modifiée!", result });
} catch (error) { } catch (error) {
console.log(error); console.log(error);
return errorHandling(next, serverError); return errorHandling(next, serverError);
@ -263,9 +265,60 @@ exports.deleteCategory = async (req, res, next) => {
return errorHandling(next, { message: "La catégorie n'existe pas." }); return errorHandling(next, { message: "La catégorie n'existe pas." });
} }
await category.destroy(); await category.destroy();
return res.status(200).json({ message: "La catégorie a bien été supprimé!" }); return res.status(200).json({ message: "La catégorie a bien été supprimée!" });
} catch (error) { } catch (error) {
console.log(error); console.log(error);
return errorHandling(next, serverError); return errorHandling(next, serverError);
} }
}
exports.getQuotes = (req, res, next) => {
const page = helperQueryNumber(req.query.page, 1);
const limit = helperQueryNumber(req.query.limit, 10);
const offset = (page - 1) * limit;
Quotes.findAndCountAll({
limit,
offset,
where: {
isValidated: 0,
},
include: [
{ model: Users, attributes: ["name", "logo"] }
],
order: [['createdAt', 'DESC']]
})
.then((result) => {
const { count, rows } = result;
const hasMore = (page * limit) < count;
return res.status(200).json({ totalItems: count, hasMore, rows });
})
.catch((error) => {
console.log(error);
return errorHandling(next, serverError);
});
}
exports.putQuote = async (req, res, next) => {
const { id } = req.params;
const { isValid } = req.body;
try {
if (typeof isValid !== 'boolean') {
return errorHandling(next, { message: "isValid doit être un booléen.", statusCode: 400 });
}
const quote = await Quotes.findOne({ where: { id, isValidated: 0 } });
if (!quote) {
return errorHandling(next, { message: "La citation n'existe pas (ou est déjà validé).", statusCode: 404 });
}
if (isValid) {
quote.isValidated = true;
const result = await quote.save();
return res.status(200).json({ isValidated: true, message: "La citation a bien été validée!", result });
}
await quote.destroy();
return res.status(200).json({ isValidated: false, message: "La citation a bien été supprimée!" });
} catch (error) {
console.log(error);
return errorHandling(next, serverError);
}
} }

46
api/controllers/quotes.js Normal file
View File

@ -0,0 +1,46 @@
const errorHandling = require('../assets/utils/errorHandling');
const { serverError } = require('../assets/config/errors');
const Quotes = require('../models/quotes');
const Users = require('../models/users');
const helperQueryNumber = require('../assets/utils/helperQueryNumber');
exports.getQuotes = (req, res, next) => {
const page = helperQueryNumber(req.query.page, 1);
const limit = helperQueryNumber(req.query.limit, 10);
const offset = (page - 1) * limit;
Quotes.findAndCountAll({
limit,
offset,
where: {
isValidated: 1,
},
include: [
{ model: Users, attributes: ["name", "logo"] }
],
attributes: {
exclude: ["isValidated"]
},
order: [['createdAt', 'DESC']]
})
.then((result) => {
const { count, rows } = result;
const hasMore = (page * limit) < count;
return res.status(200).json({ totalItems: count, hasMore, rows });
})
.catch((error) => {
console.log(error);
return errorHandling(next, serverError);
});
}
exports.postQuote = (req, res, next) => {
const { quote, author } = req.body;
Quotes.create({ quote, author, userId: req.userId })
.then((_result) => {
return res.status(200).json({ message: "La citation a bien été ajoutée, elle est en attente de confirmation d'un administrateur." });
})
.catch((error) => {
console.log(error);
return errorHandling(next, serverError);
});
}

24
api/models/quotes.js Normal file
View File

@ -0,0 +1,24 @@
const Sequelize = require('sequelize');
const sequelize = require('../assets/utils/database');
module.exports = sequelize.define('quote', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
quote: {
type: Sequelize.STRING,
allowNull: false,
},
author: {
type: Sequelize.STRING,
allowNull: false,
},
isValidated: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: 0
}
});

View File

@ -196,4 +196,14 @@ AdminRouter.route('/categories/:id')
// Supprime une catégorie avec son id // Supprime une catégorie avec son id
.delete(isAuth, isAdmin, adminController.deleteCategory); .delete(isAuth, isAdmin, adminController.deleteCategory);
AdminRouter.route('/quotes')
// Récupère les citations pas encore validées
.get(isAuth, isAdmin, adminController.getQuotes);
AdminRouter.route('/quotes/:id')
// Valide ou supprime une citation
.put(isAuth, isAdmin, adminController.putQuote);
module.exports = AdminRouter; module.exports = AdminRouter;

15
api/routes/quotes.js Normal file
View File

@ -0,0 +1,15 @@
const { Router } = require('express');
const quotesController = require('../controllers/quotes');
const isAuth = require('../middlewares/isAuth');
const QuotesRouter = Router();
QuotesRouter.route('/')
// Récupère les citations
.get(quotesController.getQuotes)
// Proposer une citation
.post(isAuth, quotesController.postQuote);
module.exports = QuotesRouter;