From 6959f2a6bfe4836782d3fc5bcebde221b6ff4999 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Mon, 28 Oct 2019 23:05:09 +0100 Subject: [PATCH] hw6: bonus done (tests pass, needs manual testing for HTML) --- hw6/Claudio_Maggioni/app.js | 3 +- .../routes/favourites_db_asaw/router.js | 164 ++++++++++++++++++ 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 hw6/Claudio_Maggioni/routes/favourites_db_asaw/router.js diff --git a/hw6/Claudio_Maggioni/app.js b/hw6/Claudio_Maggioni/app.js index 0ccd0e7..6d61bea 100644 --- a/hw6/Claudio_Maggioni/app.js +++ b/hw6/Claudio_Maggioni/app.js @@ -40,7 +40,8 @@ app.use(express.static('public')); const routers = require('./routes/routers'); app.use('/', routers.root); // app.use('/favorites', routers.favourites_db); -app.use('/favorites', routers.favourites_db_promises); +// app.use('/favorites', routers.favourites_db_promises); +app.use('/favorites', routers.favourites_db_asaw); app.use('/bookmarked', routers.bookmarked); module.exports = app; diff --git a/hw6/Claudio_Maggioni/routes/favourites_db_asaw/router.js b/hw6/Claudio_Maggioni/routes/favourites_db_asaw/router.js new file mode 100644 index 0000000..ae1385d --- /dev/null +++ b/hw6/Claudio_Maggioni/routes/favourites_db_asaw/router.js @@ -0,0 +1,164 @@ +/** @module root/router */ +'use strict'; +// vim: set ts=2 sw=2 et tw=80: + +const fs = require('fs'); +const express = require('express'); +const router = express.Router(); + +const mongoose = require('mongoose'); +const Favorite = mongoose.model('Favorite'); + +const { error, catchErrs, renderFav, parseId, notFound } = require('../utils'); + +async function findAndRender(filter, req, res) { + try { + const favs = await Favorite.find(filter); + renderFav(req, res, favs); + } catch(e) { + error(e, res); + } +} + +router.post('/', async (req, res) => { + if (!req.body.name || !req.body.dataURL) { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad create form parameters'); + return; + } + + const data = { + name: req.body.name, + dataURL: req.body.dataURL, + bookmarked: req.body.bookmarked, + }; + const favourite = new Favorite(data); + + if (req.body._id) { + favourite._id = req.body._id; + } else { + favourite._id = mongoose.Types.ObjectId(); + } + + try { + const fav = await favourite.save(); + res.status = 201; + renderFav(req, res, fav, false); + } catch(e) { + error(e, res); + } +}); + +router.get('/', async (req, res) => { + await findAndRender({}, req, res); +}); + +router.get('/search', async (req, res) => { + const filter = Object.assign({}, req.query); + delete filter['dataURL']; + delete filter['_method']; + + await findAndRender(filter, req, res); +}); + +function findOne(id) { + return async (req, res) => { + try { + const fav = await Favorite.findById(id(req)); + + if (notFound(fav, res)) { + return; + } + + renderFav(req, res, fav, false); + } catch(e) { + error(e, res); + } + }; +} + +router.get('/:id', findOne(req => parseId(req))); + +function handleUpdate(partial = false) { + return async (req, res) => { + const edit = {}; + for (const key of ['dataURL', 'name']) { + if (req.body[key]) { + edit[key] = req.body[key]; + } else if (!partial) { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad PUT form parameters'); + return; + } + } + + if (req.body.bookmarked !== undefined) { + edit.bookmarked = req.body.bookmarked; + } + + try { + const fav = await Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, { + new: false, + upsert: true, + setDefaultsOnInsert: true, + }); + + if (fav == null) { + res.status = 201; + await findOne(() => parseId(req))(req, res); + return; + } + + res.status = 200; + renderFav(req, res, fav, false); + } catch (e) { + error(e, res); + } + }; +} + +router.put('/:id', handleUpdate()); + +router.patch('/:id', handleUpdate(true)); + +router.delete('/:id', async (req, res) => { + try { + const fav = await Favorite.findByIdAndDelete(parseId(req)); + + if (notFound(fav, res)) { + return; + } + + res.format({ + json: () => res.writeHead(204), + html: () => res.writeHead(302, { 'Location': '/favorites' }) + }); + res.end(); + } catch (e) { + error(e, res); + } +}); + +router.put('/:id/bookmarked', (req, res) => { + try { + const fav = Favorite.findByIdAndUpdate(parseId(req), { + $set: { bookmarked: req.body.bookmarked } + }, { new: true }); + + if (notFound(fav, res)) { + return; + } + + if (!req.body.bookmarked) { + res.writeHead(400, { 'Content-Type': 'text/plain' }); + res.end('Bad PUT bookmark form parameters'); + } else { + renderFav(req, res, fav, false); + } + } catch (e) { + error(e, res); + } +}); + +/** router for /root */ +module.exports = router;