From 0cf93a6f00fdf69ff2041f1b1bd7608b3da320e6 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 27 Aug 2021 20:10:00 +0100 Subject: [PATCH] quote rating api --- backend/api/controllers/quote-ratings.js | 76 ++++++++++++++++++++++++ backend/api/routes/quote-ratings.js | 15 +++++ backend/dao/quote-ratings.js | 32 ++++++++++ backend/dao/user.js | 10 ++++ backend/server.js | 2 + 5 files changed, 135 insertions(+) create mode 100644 backend/api/controllers/quote-ratings.js create mode 100644 backend/api/routes/quote-ratings.js create mode 100644 backend/dao/quote-ratings.js diff --git a/backend/api/controllers/quote-ratings.js b/backend/api/controllers/quote-ratings.js new file mode 100644 index 000000000..720afd93c --- /dev/null +++ b/backend/api/controllers/quote-ratings.js @@ -0,0 +1,76 @@ +const QuoteRatingsDAO = require("../../dao/quote-ratings"); +const UserDAO = require("../../dao/user"); +const MonkeyError = require("../../handlers/error"); + +class QuoteRatingsController { + static async getRating(req, res, next) { + try { + const { quoteId, language } = req.query; + let data = await QuoteRatingsDAO.get(parseInt(quoteId), language); + return res.status(200).json(data); + } catch (e) { + return next(e); + } + } + static async submitRating(req, res, next) { + try { + let { uid } = req.decodedToken; + let { quoteId, rating, language } = req.body; + quoteId = parseInt(quoteId); + rating = parseInt(rating); + if (isNaN(quoteId) || isNaN(rating)) { + throw new MonkeyError( + 400, + "Bad request. Quote id or rating is not a number." + ); + } + if (typeof language !== "string") { + throw new MonkeyError(400, "Bad request. Language is not a string."); + } + + if (rating < 1 || rating > 5) { + throw new MonkeyError( + 400, + "Bad request. Rating must be between 1 and 5." + ); + } + + //check if user already submitted a rating + let user = await UserDAO.getUser(uid); + + if (!user) { + throw new MonkeyError(401, "User not found."); + } + let quoteRatings = user.quoteRatings; + + if (quoteRatings === undefined) quoteRatings = {}; + if (quoteRatings[language] === undefined) quoteRatings[language] = {}; + if (quoteRatings[language][quoteId] == undefined) + quoteRatings[language][quoteId] = undefined; + + let quoteRating = quoteRatings[language][quoteId]; + + let newRating; + let update; + if (quoteRating) { + //user already voted for this + newRating = rating - quoteRating; + update = true; + } else { + //user has not voted for this + newRating = rating; + update = false; + } + + await QuoteRatingsDAO.submit(quoteId, language, newRating, update); + quoteRatings[language][quoteId] = rating; + await UserDAO.updateQuoteRatings(uid, quoteRatings); + + return res.sendStatus(200); + } catch (e) { + return next(e); + } + } +} + +module.exports = QuoteRatingsController; diff --git a/backend/api/routes/quote-ratings.js b/backend/api/routes/quote-ratings.js new file mode 100644 index 000000000..37f4329db --- /dev/null +++ b/backend/api/routes/quote-ratings.js @@ -0,0 +1,15 @@ +const { authenticateRequest } = require("../../middlewares/auth"); +const { Router } = require("express"); +const QuoteRatingsController = require("../controllers/quote-ratings"); + +const router = Router(); + +router.get("/get", authenticateRequest, QuoteRatingsController.getRating); + +router.post( + "/submit", + authenticateRequest, + QuoteRatingsController.submitRating +); + +module.exports = router; diff --git a/backend/dao/quote-ratings.js b/backend/dao/quote-ratings.js new file mode 100644 index 000000000..cc8c15a34 --- /dev/null +++ b/backend/dao/quote-ratings.js @@ -0,0 +1,32 @@ +const MonkeyError = require("../handlers/error"); +const { mongoDB } = require("../init/mongodb"); + +class QuoteRatingsDAO { + static async submit(quoteId, language, rating, update) { + if (update) { + return await mongoDB() + .collection("quote-rating") + .updateOne( + { quoteId, language }, + { $inc: { totalRating: rating } }, + { upsert: true } + ); + } else { + return await mongoDB() + .collection("quote-rating") + .updateOne( + { quoteId, language }, + { $inc: { ratings: 1, totalRating: rating } }, + { upsert: true } + ); + } + } + + static async get(quoteId, language) { + return await mongoDB() + .collection("quote-rating") + .findOne({ quoteId, language }); + } +} + +module.exports = QuoteRatingsDAO; diff --git a/backend/dao/user.js b/backend/dao/user.js index 94a45c37d..bfe97661f 100644 --- a/backend/dao/user.js +++ b/backend/dao/user.js @@ -40,6 +40,16 @@ class UsersDAO { } } + static async updateQuoteRatings(uid, quoteRatings) { + const user = await mongoDB().collection("users").findOne({ uid }); + if (!user) + throw new MonkeyError(404, "User not found", "updateQuoteRatings"); + await mongoDB() + .collection("users") + .updateOne({ uid }, { $set: { quoteRatings } }); + return true; + } + static async updateEmail(uid, email) { const user = await mongoDB().collection("users").findOne({ uid }); if (!user) throw new MonkeyError(404, "User not found", "update email"); diff --git a/backend/server.js b/backend/server.js index 9206a9571..510054f8a 100644 --- a/backend/server.js +++ b/backend/server.js @@ -26,6 +26,8 @@ const resultRouter = require("./api/routes/result"); app.use("/results", resultRouter); const presetRouter = require("./api/routes/preset"); app.use("/presets", presetRouter); +const quoteRatings = require("./api/routes/quote-ratings"); +app.use("/quote-ratings", quoteRatings); app.use(function (e, req, res, next) { let uid = undefined;