diff --git a/server/controllers/menuController.js b/server/controllers/menuController.js index 433f07d..610bb95 100644 --- a/server/controllers/menuController.js +++ b/server/controllers/menuController.js @@ -14,6 +14,22 @@ class MenuController { res.status(500).json(); } } + + static async addFood(req, res) { + const { foodName, foodImage, price } = req; + try { + const insertQuery = 'INSERT INTO menu(food_name, food_image, price) VALUES($1, $2, $3) RETURNING *'; + const newFood = (await pool.query(insertQuery, [foodName, foodImage, price])).rows[0]; + + res.status(201).json({ + status: 'success', + message: 'new food added successfully', + food: newFood, + }); + } catch (error) { + res.status(500).json(); + } + } } export default MenuController; diff --git a/server/middleware/sanitizer.js b/server/middleware/sanitizer.js index c1863ec..193da96 100644 --- a/server/middleware/sanitizer.js +++ b/server/middleware/sanitizer.js @@ -79,6 +79,29 @@ class Sanitize { return next(); } + + static addFood(req, res, next) { + const { foodName, foodImage, price } = req.body; + + if (!foodName || !price) { + return res.status(400).json({ + status: 'error', + message: 'you\'re missing some important fields', + }); + } + + if (Number.isNaN(Number(price))) { + return res.status(400).json({ + status: 'error', + message: 'food price should be a number', + }); + } + + req.foodName = foodName; + req.foodImage = foodImage; + req.price = price; + return next(); + } } export default Sanitize; diff --git a/server/routes/menuRouter.js b/server/routes/menuRouter.js index 520bc2e..e6776a7 100644 --- a/server/routes/menuRouter.js +++ b/server/routes/menuRouter.js @@ -1,9 +1,17 @@ import { Router } from 'express'; import AuthHandler from '../middleware/authHandler'; import MenuController from '../controllers/menuController'; +import Sanitize from '../middleware/sanitizer'; const router = new Router(); router.get('/', AuthHandler.authorize, MenuController.getMenu); +router.post( + '/', + AuthHandler.authorize, + AuthHandler.authorizeAdmin, + Sanitize.addFood, + MenuController.addFood, +); export default router; diff --git a/tests/routes/menu.spec.js b/tests/routes/menu.spec.js index 8341026..ccdc123 100644 --- a/tests/routes/menu.spec.js +++ b/tests/routes/menu.spec.js @@ -21,6 +21,74 @@ before(async () => { await populateUsersTablePromise; }); +describe('POST /menu', () => { + it('should not allow non admin users add new food to menu', (done) => { + chai.request(app) + .post('/api/v1/menu') + .set('x-auth', generateValidToken(seedData.users.validUser)) + .send({ + foodName: 'Steak', + foodImage: 'https://i.imgur.com/7itOeyG.jpg', + price: 1200, + }) + .end((err, res) => { + if (err) done(err); + + res.status.should.eql(403); + done(); + }); + }); + + it('should not accept an incomplete request body', (done) => { + chai.request(app) + .post('/api/v1/menu') + .set('x-auth', generateValidToken(seedData.users.admin)) + .send({ foodName: 'Pizza' }) + .end((err, res) => { + if (err) done(err); + + res.status.should.eql(400); + res.body.message.should.eql('you\'re missing some important fields'); + done(); + }); + }); + + it('should not accept an improperly formatted price', (done) => { + chai.request(app) + .post('/api/v1/menu') + .set('x-auth', generateValidToken(seedData.users.admin)) + .send({ foodName: 'Smoked bread', price: 'cheap' }) + .end((err, res) => { + if (err) done(err); + + res.status.should.eql(400); + res.body.message.should.eql('food price should be a number'); + done(); + }); + }); + + it('should add new food items to the menu successfully', (done) => { + chai.request(app) + .post('/api/v1/menu') + .set('x-auth', generateValidToken(seedData.users.admin)) + .send({ + foodName: 'Tasty Chicken', + foodImage: 'https://i.imgur.com/z490cis.jpg', + price: '1200', + }) + .end((err, res) => { + if (err) done(err); + + res.status.should.eql(201); + res.body.should.be.an('object').which.has.all.keys(['status', 'message', 'food']); + res.body.food.should.have.all.keys(['id', 'food_name', 'food_image', 'price']); + res.body.food.food_name.should.eql('Tasty Chicken'); + res.body.food.price.should.eql(1200); + done(); + }); + }); +}); + describe('GET /menu', () => { const { validUser } = seedData.users;