From eea4290e9c4ad5c9bbdd30564b01d67b35ba566d Mon Sep 17 00:00:00 2001 From: Kizito Akhilome Date: Fri, 7 Sep 2018 09:53:50 +0100 Subject: [PATCH] feat(api): create endpoint for making new orders - write tests for POST /api/v1/orders/ - write code to make tests pass [Finishes #160239612] --- package-lock.json | 128 +++++++++++++++++--------- package.json | 1 + server/controllers/orderController.js | 17 ++++ server/index.js | 3 + server/routes/routes.js | 1 + tests/routes/routes.spec.js | 27 ++++++ 6 files changed, 135 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21f3aff..9d50be7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1464,20 +1464,27 @@ "dev": true }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", "requires": { "bytes": "3.0.0", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } } }, "boxen": { @@ -2544,6 +2551,64 @@ "type-is": "~1.6.16", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + } } }, "extend": { @@ -3711,9 +3776,12 @@ } }, "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } }, "ignore": { "version": "4.0.6", @@ -6311,37 +6379,14 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", "requires": { "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - } } }, "rc": { @@ -6677,8 +6722,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { "version": "5.5.1", diff --git a/package.json b/package.json index 4c6fd08..6142908 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "homepage": "https://github.com/akhilome/fast-food-fast#readme", "dependencies": { + "body-parser": "^1.18.3", "express": "^4.16.3" }, "devDependencies": { diff --git a/server/controllers/orderController.js b/server/controllers/orderController.js index 3a262bc..cb840a0 100644 --- a/server/controllers/orderController.js +++ b/server/controllers/orderController.js @@ -1,4 +1,5 @@ import orders from '../db/orders'; +import Order from '../models/Order'; class OrderController { static getAllOrders(req, res) { @@ -16,6 +17,22 @@ class OrderController { return res.status(200).json(order); } + + static newOrder(req, res) { + const { author, title } = req.body; + if (!author || !title) { + return res.status(400).json({ + error: 'incomplete data', + }); + } + + const order = new Order(orders.length + 1, author, title); + orders.push(order); + return res.status(201).json({ + message: 'order placed', + order, + }); + } } export default OrderController; diff --git a/server/index.js b/server/index.js index 5ba39b1..c85836f 100644 --- a/server/index.js +++ b/server/index.js @@ -1,4 +1,5 @@ import express from 'express'; +import bodyParser from 'body-parser'; import router from './routes/routes'; const app = express(); @@ -9,6 +10,8 @@ app.get('/', (req, res) => { }); }); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); app.use('/api/v1', router); app.listen(3000); diff --git a/server/routes/routes.js b/server/routes/routes.js index 651243c..9c65a58 100644 --- a/server/routes/routes.js +++ b/server/routes/routes.js @@ -12,5 +12,6 @@ router.get('/', (req, res) => { router.get('/orders', OrderController.getAllOrders); router.get('/orders/:id', findOrder, OrderController.getOrder); +router.post('/orders', OrderController.newOrder); export default router; diff --git a/tests/routes/routes.spec.js b/tests/routes/routes.spec.js index 1c1451b..bd8cd07 100644 --- a/tests/routes/routes.spec.js +++ b/tests/routes/routes.spec.js @@ -99,3 +99,30 @@ describe('GET /api/v1/orders/', () => { }); }); }); + +describe('POST /api/v1/orders', () => { + const completeData = { author: 'Kizito', title: 'Turkey' }; + const incompleteData = { author: 'Kizito' }; + + it('should return a 400 error and a message if data is incomplete', (done) => { + chai.request(app) + .post('/api/v1/orders') + .send(incompleteData) + .end((err, res) => { + res.should.have.status(400); + res.body.should.be.an('object').which.has.a.property('error'); + done(); + }); + }); + + it('should add the order to the database and respond with 201 if data is complete', (done) => { + chai.request(app) + .post('/api/v1/orders') + .send(completeData) + .end((err, res) => { + res.should.have.status(201); + res.body.should.be.an('object').which.has.a.property('message'); + done(); + }); + }); +});