From a6893a115f52b5f4f51f12032902a8efbc3f6071 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Sun, 14 Jul 2019 19:08:56 +0100 Subject: [PATCH 01/16] bug(feedback): implement auto grader feedback >- refactore code >- change entry specification >- rename variables from came case to snake case >- rename token name [Fixes #167280608] --- package-lock.json | 218 +++++++++++++++++++++---- package.json | 2 + server/app.js | 6 +- server/controllers/carController.js | 25 ++- server/controllers/orderController.js | 28 ++-- server/controllers/uploadController.js | 21 +++ server/controllers/userController.js | 16 +- server/db/migrations/createTables.js | 30 ++-- server/helper/schema.js | 13 +- server/middleware/authentication.js | 4 +- server/middleware/validator.js | 33 ++-- server/model/cars.js | 10 +- server/model/flags.js | 2 +- server/model/order.js | 12 +- server/model/user.js | 22 +-- server/router/carRoute.js | 1 + server/router/orderRoute.js | 2 +- server/router/uploadRoute.js | 9 + server/test/data/car.js | 6 +- server/test/data/order.js | 15 +- server/test/data/user.js | 11 +- server/test/test.jpg | Bin 0 -> 15379 bytes server/test/test.js | 171 ++++++++++++------- 23 files changed, 456 insertions(+), 201 deletions(-) create mode 100644 server/controllers/uploadController.js create mode 100644 server/router/uploadRoute.js create mode 100644 server/test/test.jpg diff --git a/package-lock.json b/package-lock.json index 544807d..8196ac0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -874,6 +874,38 @@ "to-fast-properties": "^2.0.0" } }, + "@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz", + "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==", + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==" + }, "@types/chai": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", @@ -1083,6 +1115,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=" + }, "array-includes": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", @@ -1390,6 +1427,38 @@ "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -2024,6 +2093,38 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -2510,6 +2611,14 @@ "vary": "~1.1.2" } }, + "express-fileupload": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.1.5.tgz", + "integrity": "sha512-ZYxGkXm9y1dSMgbW+lwvtqld+dulYm3OU1GQF9n6NNEwulHTPUsz4mHGG5/LiUszz5jnh/j8AcpLFUdaj8UUtQ==", + "requires": { + "busboy": "^0.2.14" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4348,6 +4457,11 @@ "verror": "1.10.0" } }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==" + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -4495,6 +4609,11 @@ "chalk": "^2.0.1" } }, + "lolex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.1.0.tgz", + "integrity": "sha512-BYxIEXiVq5lGIXeVHnsFzqa1TxN5acnKnPCdlZSpzm8viNEOhiigupA4vTQ9HEFQ6nLTQ9wQOgBknJgzUYQ9Aw==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4678,9 +4797,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -4858,6 +4977,33 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "nise": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.0.tgz", + "integrity": "sha512-Z3sfYEkLFzFmL8KY6xnSJLRxwQwYBjOXi/24lb62ZnZiGA0JUzGGTI6TBIgfCSMIDl9Jlu8SRmHNACLTemDHww==", + "requires": { + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^4.1.0", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + } + } + }, "node-environment-flags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", @@ -6054,9 +6200,9 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -6099,6 +6245,30 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "sinon": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz", + "integrity": "sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA==", + "requires": { + "@sinonjs/commons": "^1.4.0", + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/samsam": "^3.3.1", + "diff": "^3.5.0", + "lolex": "^4.0.1", + "nise": "^1.4.10", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -6391,6 +6561,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -6900,38 +7075,15 @@ "dev": true }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unique-string": { diff --git a/package.json b/package.json index 375d59c..531c275 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,12 @@ "cors": "^2.8.5", "dotenv": "^8.0.0", "express": "^4.17.0", + "express-fileupload": "^1.1.5", "joi": "^14.3.1", "jsonwebtoken": "^8.5.1", "mocha": "^6.1.4", "pg": "^7.11.0", + "sinon": "^7.3.2", "swagger-ui-express": "^4.0.5", "yamljs": "^0.3.0" }, diff --git a/server/app.js b/server/app.js index 8b9dd75..88f6d2d 100644 --- a/server/app.js +++ b/server/app.js @@ -3,17 +3,20 @@ import bodyParser from 'body-parser'; import swaggerUi from 'swagger-ui-express'; import yaml from 'yamljs'; import cors from 'cors'; +import fileUpload from 'express-fileupload'; import router from './router/userRoute'; import carRouter from './router/carRoute'; import orderRouter from './router/orderRoute'; import adminRouter from './router/adminRoute'; - +import uploadRouter from './router/uploadRoute'; import utilities from './helper/utilities'; + const app = express(); app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); +app.use(fileUpload({ useTempFiles: true })); const swaggerdoc = yaml.load(`${__dirname}/../swagger.yaml`); app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerdoc)); @@ -22,6 +25,7 @@ app.use('/api/v1', router); app.use('/api/v1', carRouter); app.use('/api/v1', orderRouter); app.use('/api/v1', adminRouter); +app.use('/api/v1', uploadRouter); app.use('*', (req, res) => utilities.errorstatus(res, 404, 'This Route is Not On This Server')); diff --git a/server/controllers/carController.js b/server/controllers/carController.js index fb43a3e..117759f 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -6,16 +6,16 @@ import pool from '../db/config/config'; class carController { static async postAds(req, res) { try { - const { email } = req.user; + const { id } = req.user; const { - manufacturer, model, bodyType, price, state, + manufacturer, model, body_type, price, state, } = req.body; const status = 'available'; const carCreated = await dbMethods.insertToDb('cars', { - email, manufacturer, model, bodytype: bodyType, price, state, status, + owner: id, manufacturer, model, body_type, price, state, status, }, 'RETURNING *'); return utilities.successStatus(res, 201, 'data', carCreated); @@ -26,14 +26,14 @@ class carController { static async markSold(req, res) { try { - const { email } = req.user; + const { id } = req.user; const { carId } = req.params; const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (email === carCheck[0].email) { + if (id === carCheck[0].owner) { await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); @@ -47,7 +47,7 @@ class carController { static async updateCar(req, res) { try { - const { email } = req.user; + const { id } = req.user; const { carId } = req.params; const updatePrice = req.body.price; @@ -55,7 +55,7 @@ class carController { if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (email !== carCheck[0].email) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); + if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); if (carCheck[0].status !== 'sold') { await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); @@ -113,7 +113,7 @@ class carController { } if (bodyType) { - const carType = await dbMethods.readFromDb('cars', '*', { bodytype: bodyType.toLowerCase() }); + const carType = await dbMethods.readFromDb('cars', '*', { body_type: bodyType.toLowerCase() }); if (!carType[0]) return utilities.errorstatus(res, 404, 'No Car With This Body Type Found'); return utilities.successStatus(res, 200, 'data', carType); @@ -129,10 +129,17 @@ class carController { if (!car[0]) return utilities.errorstatus(res, 404, 'Car Not Found'); - const flagObj = await dbMethods.insertToDb('flags', { carId, reason, description }, 'RETURNING *'); + const flagObj = await dbMethods.insertToDb('flags', { car_id: carId, reason, description }, 'RETURNING *'); return utilities.successStatus(res, 201, 'data', flagObj); } + + static async updateCarImage(req, res) { + const { car_image } = req.body; + const { car_id } = req.params; + await dbMethods.updateDbRow('cars', { car_image }, { id: Number(car_id) }); + return utilities.successStatus(res, 200, 'data', 'Updated Successfully'); + } } diff --git a/server/controllers/orderController.js b/server/controllers/orderController.js index 5f93d1a..8ebc069 100644 --- a/server/controllers/orderController.js +++ b/server/controllers/orderController.js @@ -5,20 +5,19 @@ class orderController { static async purchaseOrder(req, res) { try { const { id } = req.user; - const carId = Number(req.params.id); + const car_id = Number(req.body.car_id); - const isCar = await dbMethods.readFromDb('cars', '*', { id: carId }); + const isCar = await dbMethods.readFromDb('cars', '*', { id: car_id }); if (!isCar[0]) return utilities.errorstatus(res, 404, 'Car Not Found'); - const { priceOffered } = req.body; + const { amount } = req.body; const status = 'pending'; - const buyerId = id; + const buyer_id = id; const { price } = isCar[0]; - const orderCreated = await dbMethods.insertToDb('orders', { - buyerId, carId, status, price, priceOffered, - }, 'RETURNING id, created_on, carid, buyerid, status, price, priceoffered'); + buyer_id, car_id, status, price, price_offered: amount, + }, 'RETURNING id, created_on, car_id, buyer_id, status, price, price_offered'); return utilities.successStatus(res, 201, 'data', orderCreated); } catch (error) { @@ -29,25 +28,26 @@ class orderController { static async updatePurchase(req, res) { try { const { id } = req.user; - const { newPriceOffered } = req.body; + const { price } = req.body; const { orderId } = req.params; + const new_price_offered = price; const isOrder = await dbMethods.readFromDb('orders', '*', { id: Number(orderId) }); if (!isOrder[0]) return utilities.errorstatus(res, 400, 'Purchase Order Not found'); if (isOrder[0].status === 'pending') { - if (Number(isOrder[0].buyerid) !== id) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); + if (Number(isOrder[0].buyer_id) !== id) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (isOrder[0].oldpriceoffered === null) { - await dbMethods.updateDbRow('orders', { oldpriceoffered: isOrder[0].priceoffered }, { id: Number(orderId) }); - } else await dbMethods.updateDbRow('orders', { oldpriceoffered: isOrder[0].newpriceoffered }, { id: Number(orderId) }); + if (isOrder[0].old_price_offered === null) { + await dbMethods.updateDbRow('orders', { old_price_offered: isOrder[0].price_offered }, { id: Number(orderId) }); + } else await dbMethods.updateDbRow('orders', { old_price_offered: isOrder[0].new_price_offered }, { id: Number(orderId) }); - await dbMethods.updateDbRow('orders', { newpriceoffered: newPriceOffered }, { id: Number(orderId) }); + await dbMethods.updateDbRow('orders', { new_price_offered }, { id: Number(orderId) }); const update = await dbMethods.readFromDb('orders', '*', { id: Number(orderId) }); - delete update[0].priceoffered; + delete update[0].price_offered; return utilities.successStatus(res, 200, 'data', update[0]); } return utilities.errorstatus(res, 400, 'Purchase Order Already Approved'); diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js new file mode 100644 index 0000000..1bcb2b9 --- /dev/null +++ b/server/controllers/uploadController.js @@ -0,0 +1,21 @@ +import utilities from '../helper/utilities'; + +const cloudinary = require('cloudinary').v2; + +cloudinary.config({ + cloud_name: process.env.cloud_name, + api_key: process.env.api_key, + api_secret: process.env.api_secret, +}); + +class uploadController { + static upload(req, res) { + const file = req.files.photo; + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + return utilities.successStatus(res, 200, 'data', result.url); + }); + } +} + +export default uploadController; diff --git a/server/controllers/userController.js b/server/controllers/userController.js index dc16e16..2a7b6c5 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -14,7 +14,7 @@ class userController { static async signupUser(req, res) { try { const { - firstName, lastName, email, password, phoneNumber, + first_name, last_name, email, password, address, } = req.body; const user = await dbMethods.readFromDb('users', '*', { email }); @@ -22,17 +22,17 @@ class userController { if (user[0]) { return utilities.errorstatus(res, 400, 'User Already Exist'); } - const isAdmin = false; + const is_admin = false; const hashpassword = secure.passwordhash(password); const fetchedUser = await dbMethods.insertToDb('users', { - firstName, lastName, email, hashpassword, isAdmin, phoneNumber, + first_name, last_name, email, hashpassword, is_admin, address, }, 'RETURNING id'); const { id } = fetchedUser; return utilities.successStatus(res, 201, 'data', { - token: token({ id: fetchedUser.id }), id, firstName, lastName, email, phoneNumber, + token: token({ id: fetchedUser.id }), id, first_name, last_name, email, address, }); } catch (err) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); @@ -53,16 +53,16 @@ class userController { if (passwordcheck) { const { - id, firstname, lastname, phonenumber, + id, first_name, last_name, address, } = user[0]; return utilities.successStatus(res, 200, 'data', { token: token({ id }), id, - firstName: firstname, - lastName: lastname, + first_name, + last_name, email, - phoneNumber: phonenumber, + address, }); } diff --git a/server/db/migrations/createTables.js b/server/db/migrations/createTables.js index af10d0a..5cf5697 100644 --- a/server/db/migrations/createTables.js +++ b/server/db/migrations/createTables.js @@ -16,52 +16,52 @@ function insertMultiple(table, array, returning = '') { const usersTable = `CREATE TABLE IF NOT EXISTS users( id serial PRIMARY KEY, - firstname text NOT NULL, - lastname text NOT NULL, + first_name text NOT NULL, + last_name text NOT NULL, email text NOT NULL, hashpassword text NOT NULL, - phonenumber text, - isadmin boolean NOT NULL, - profilepic text DEFAULT 'http://res.cloudinary.com/demo/image/upload/v1340625837/4srvcynxrf5j87niqcx6w.jpg' + address text, + is_admin boolean NOT NULL, + profile_pic text DEFAULT 'http://res.cloudinary.com/amoslv/image/upload/v1562438896/ytgtpwvbaw5ew8x8fwsb.png' ); `; const carsTable = `CREATE TABLE IF NOT EXISTS cars( id serial PRIMARY KEY, - email text NOT NULL, + owner int NOT NULL, created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, manufacturer text NOT NULL, model text NOT NULL, - bodytype text NOT NULL, + body_type text NOT NULL, price text NOT NULL, state text NOT NULL, status text NOT NULL, - carimage text DEFAULT 'http://res.cloudinary.com/demo/image/upload/v1340625837/4srvcynxrf5j87niqcx6w.jpg' + car_image text ); `; const ordersTable = `CREATE TABLE IF NOT EXISTS orders( id serial PRIMARY KEY, created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - buyerid text NOT NULL, - carid text NOT NULL, + buyer_id text NOT NULL, + car_id text NOT NULL, status text NOT NULL, price text NOT NULL, - priceOffered text NOT NULL, - oldPriceOffered text, - newPriceOffered text + price_offered text NOT NULL, + old_price_offered text, + new_price_offered text ); `; const flagsTable = `CREATE TABLE IF NOT EXISTS flags( id serial PRIMARY KEY, created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - carid text NOT NULL, + car_id text NOT NULL, reason text NOT NULL, description text NOT NULL ); `; - +// DEFAULT 'http://res.cloudinary.com/amoslv/image/upload/v1562770121/p09iwdyzfz2u8b4mtf9d.jpg' async function create() { try { diff --git a/server/helper/schema.js b/server/helper/schema.js index cd11685..18ebe34 100644 --- a/server/helper/schema.js +++ b/server/helper/schema.js @@ -2,14 +2,14 @@ import Joi from 'joi'; const schema = { signup: Joi.object().keys({ - firstName: Joi.string().regex(/^[A-Za-z]{3,}$/).trim() + first_name: Joi.string().regex(/^[A-Za-z]{3,}$/).trim() .required(), - lastName: Joi.string().regex(/^[A-Za-z]{3,}$/).trim() + last_name: Joi.string().regex(/^[A-Za-z]{3,}$/).trim() .required(), email: Joi.string().email().required() .trim(), password: Joi.string().required().min(8), - phoneNumber: Joi.number().required(), + address: Joi.string().required(), }), signin: Joi.object().keys({ @@ -26,18 +26,19 @@ const schema = { car: Joi.object().keys({ manufacturer: Joi.string().trim().required(), model: Joi.string().trim().required(), - bodyType: Joi.string().trim().required() + body_type: Joi.string().trim().required().valid('car', 'van', 'truck', 'trailer', 'bus', 'motorbike', 'jeep') .trim(), price: Joi.number().required(), state: Joi.string().trim().valid('new', 'used').required(), }), order: Joi.object().keys({ - priceOffered: Joi.number().required(), + amount: Joi.number().required(), + car_id: Joi.number().required(), }), updateOrder: Joi.object().keys({ - newPriceOffered: Joi.number().required(), + price: Joi.number().required(), }), updateCar: Joi.object().keys({ diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index ba6a1ef..0c068bb 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -8,7 +8,7 @@ dotenv.config(); class authenticator { static async authenticateUser(req, res, next) { try { - const token = req.headers.authtoken; + const { token } = req.headers; if (!token) { return res.status(401).json({ status: 'Error', @@ -21,7 +21,7 @@ class authenticator { if (!isUser[0]) { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } - req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].isadmin }; + req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/middleware/validator.js b/server/middleware/validator.js index 3c05b6d..e19e86b 100644 --- a/server/middleware/validator.js +++ b/server/middleware/validator.js @@ -13,11 +13,11 @@ class validate { static validateSignup(req, res, next) { const { - firstName, lastName, email, password, phoneNumber, + first_name, last_name, email, password, address, } = req.body; const validateObject = { - firstName, lastName, email, password, phoneNumber, + first_name, last_name, email, password, address, }; const error = util.validateJoi(validateObject, schema.signup); @@ -25,10 +25,11 @@ class validate { return util.errorstatus(res, 400, error); } - req.body.firstName = firstName.trim(); - req.body.lastName = lastName.trim(); + req.body.first_name = first_name.trim(); + req.body.last_name = last_name.trim(); req.body.password = password.trim(); req.body.email = email.toLowerCase().trim(); + req.body.address = address.trim(); return next(); } @@ -92,11 +93,11 @@ class validate { */ static validateCar(req, res, next) { const { - manufacturer, model, bodyType, price, state, + manufacturer, model, body_type, price, state, } = req.body; const validateObject = { - manufacturer, model, bodyType, price, state, + manufacturer, model, body_type, price, state, }; const error = util.validateJoi(validateObject, schema.car); @@ -106,7 +107,7 @@ class validate { req.body.manufacturer = manufacturer.trim(); req.body.model = model.trim(); - req.body.bodyType = bodyType.trim(); + req.body.body_type = body_type.trim(); req.body.state = state.trim(); if (Number(req.body.price) < 0) return util.errorstatus(res, 400, 'Price must Not be Negative'); @@ -123,8 +124,8 @@ class validate { */ static validateOrder(req, res, next) { - const { priceOffered } = req.body; - const validateObject = { priceOffered }; + const { amount, car_id } = req.body; + const validateObject = { amount, car_id }; const error = util.validateJoi(validateObject, schema.order); @@ -132,7 +133,7 @@ class validate { return util.errorstatus(res, 400, error); } - if (Number(req.body.priceOffered) < 0) return util.errorstatus(res, 400, 'Price must Not be Negative'); + if (Number(req.body.amount) < 0) return util.errorstatus(res, 400, 'Amount Must Not be Negative'); return next(); } @@ -146,8 +147,8 @@ class validate { */ static validateUpdateOrder(req, res, next) { - const { newPriceOffered } = req.body; - const validateObject = { newPriceOffered }; + const { price } = req.body; + const validateObject = { price }; const error = util.validateJoi(validateObject, schema.updateOrder); @@ -155,7 +156,7 @@ class validate { return util.errorstatus(res, 400, error); } - if (Number(req.body.newPriceOffered) < 0) return util.errorstatus(res, 400, 'Price must Not be Negative'); + if (Number(req.body.price) < 0) return util.errorstatus(res, 400, 'Price must Not be Negative'); return next(); } @@ -253,6 +254,12 @@ class validate { return next(); } + + static validateImage(req, res, next) { + // console.log(req.files); + if (!req.files) return util.errorstatus(res, 404, 'NO IMAGE FOUND'); + return next(); + } } export default validate; diff --git a/server/model/cars.js b/server/model/cars.js index 5782d9f..59d77af 100644 --- a/server/model/cars.js +++ b/server/model/cars.js @@ -1,21 +1,23 @@ const cars = [ { - email: 'support@automart.com', + owner: '2', manufacturer: 'Toyota', model: 'Camry', - bodyType: 'car', + body_type: 'car', price: '70000000', state: 'new', status: 'available', + // carimage : 'http://res.cloudinary.com/amoslv/image/upload/v1562770121/p09iwdyzfz2u8b4mtf9d.jpg' }, { - email: 'support@automart.com', + owner: '4', manufacturer: 'Toyota', model: 'Camry', - bodyType: 'car', + body_type: 'car', price: '1000000', state: 'new', status: 'available', + // carimage : 'http://res.cloudinary.com/amoslv/image/upload/v1562770121/p09iwdyzfz2u8b4mtf9d.jpg' }, ]; diff --git a/server/model/flags.js b/server/model/flags.js index fb0a2d7..a534f2b 100644 --- a/server/model/flags.js +++ b/server/model/flags.js @@ -1,6 +1,6 @@ const flags = [ { - carId: '1', + car_id: '1', reason: 'demand', description: 'Price too high', }, diff --git a/server/model/order.js b/server/model/order.js index 3df7bfc..35eb47d 100644 --- a/server/model/order.js +++ b/server/model/order.js @@ -1,17 +1,17 @@ const orders = [ { - buyerId: '1', - carId: '1', + buyer_id: '1', + car_id: '1', status: 'pending', price: '70000000', - priceOffered: '50000000', + price_offered: '50000000', }, { - buyerId: '1', - carId: '1', + buyer_id: '1', + car_id: '1', status: 'approved', price: '70000000', - priceOffered: '50000000', + price_offered: '50000000', }, ]; diff --git a/server/model/user.js b/server/model/user.js index d7f1ae8..1fd9723 100644 --- a/server/model/user.js +++ b/server/model/user.js @@ -1,27 +1,27 @@ const users = [ { email: 'admin@automart.com', - firstname: 'admin', - lastname: 'admin', + first_name: 'admin', + last_name: 'admin', hashpassword: '$2b$10$jMVKhvrtL/5hBq6L.D.46eCEPT2Hhsi5tioRHe9wToBt3SmqqaTI6', - isAdmin: true, - phoneNumber: '090878985', + is_admin: true, + address: 'Lagos', }, { email: 'admin444@automart.com', - firstname: 'admin', - lastname: 'admin', + first_name: 'admin', + last_name: 'admin', hashpassword: 'automart', - isAdmin: false, - phoneNumber: '090878985', + is_admin: false, + address: 'Lagos', }, { email: 'popo@automart.com', - firstname: 'Bolu', - lastname: 'Baba', + first_name: 'Bolu', + last_name: 'Baba', hashpassword: 'uche123', - isAdmin: false, + is_admin: false, }, ]; diff --git a/server/router/carRoute.js b/server/router/carRoute.js index 851616a..91535ba 100644 --- a/server/router/carRoute.js +++ b/server/router/carRoute.js @@ -10,6 +10,7 @@ carRouter.patch('/car/:carId/price', authenticator.authenticateUser, authenticat carRouter.get('/car/:carId/', authenticator.authenticateUser, authenticator.isUser, carController.specificCar); carRouter.get('/car', authenticator.authenticateUser, validator.validateGetCar, carController.car); carRouter.post('/flag/:carId', authenticator.authenticateUser, authenticator.isUser, validator.validateFlag, carController.flagCar); +carRouter.patch('/cars/:car_id', authenticator.authenticateUser, authenticator.isUser, carController.updateCarImage); export default carRouter; diff --git a/server/router/orderRoute.js b/server/router/orderRoute.js index 6c46043..2509ac6 100644 --- a/server/router/orderRoute.js +++ b/server/router/orderRoute.js @@ -4,7 +4,7 @@ import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; const orderRouter = express(); -orderRouter.post('/order/:id', authenticator.authenticateUser, authenticator.isUser, validator.validateOrder, orderController.purchaseOrder); +orderRouter.post('/order', authenticator.authenticateUser, authenticator.isUser, validator.validateOrder, orderController.purchaseOrder); orderRouter.patch('/order/:orderId/price', authenticator.authenticateUser, authenticator.isUser, validator.validateUpdateOrder, orderController.updatePurchase); export default orderRouter; diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js new file mode 100644 index 0000000..18c11bf --- /dev/null +++ b/server/router/uploadRoute.js @@ -0,0 +1,9 @@ +import express from 'express'; +import uploadController from '../controllers/uploadController'; +import validator from '../middleware/validator'; +import authenticator from '../middleware/authentication'; + +const uploadRouter = express(); +uploadRouter.post('/upload', authenticator.authenticateUser, authenticator.isUser, validator.validateImage, uploadController.upload); + +export default uploadRouter; diff --git a/server/test/data/car.js b/server/test/data/car.js index 86eda0e..92e1705 100644 --- a/server/test/data/car.js +++ b/server/test/data/car.js @@ -2,14 +2,14 @@ const car = [ { manufacturer: 'Toyota', model: 'Camry', - bodyType: 'car', + body_type: 'car', state: 'used', price: '70000000', }, { manufacturer: 'Toyota', model: 'Camry', - bodyType: 'car', + body_type: 'car', state: 'jhjhkjhk', price: 'jbkhjkhj', }, @@ -22,7 +22,7 @@ const car = [ { manufacturer: 'Toyota', model: 'Camry', - bodyType: 'car', + body_type: 'car', state: 'used', price: '-70000000', }, diff --git a/server/test/data/order.js b/server/test/data/order.js index f1c2a56..668ac0f 100644 --- a/server/test/data/order.js +++ b/server/test/data/order.js @@ -1,21 +1,24 @@ const orders = [ { - priceOffered: '50000000', + amount: '50000000', + car_id: '1', }, { - priceOffered: 'sdksdls', + amount: 'sdksdls', + car_id: '1', }, { - newPriceOffered: '30000000', + price: '30000000', }, { - newPriceOffered: 'sdksdls', + price: 'sdksdls', }, { - priceOffered: '-50000000', + amount: '-50000000', + car_id: '1', }, { - newPriceOffered: '-345453545', + price: '-345453545', }, ]; diff --git a/server/test/data/user.js b/server/test/data/user.js index f4a7692..b7cf3f0 100644 --- a/server/test/data/user.js +++ b/server/test/data/user.js @@ -1,16 +1,17 @@ const user = [ { - firstName: 'support', - lastName: 'automart', + first_name: 'support', + last_name: 'automart', email: 'support11@automart.com', password: 'automart', - phoneNumber: '09087897656', + address: '09087897656', }, { - lastName: 'automart', + first_name: 'as', + last_name: 'automart', email: 'support@automart.com', password: 'automart', - phoneNumber: '09087897656', + address: '09087897656', }, { email: 'support@automart.com', diff --git a/server/test/test.jpg b/server/test/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a52766cd08c6df56244a10de9b8290264a3c2dc6 GIT binary patch literal 15379 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 literal 0 HcmV?d00001 diff --git a/server/test/test.js b/server/test/test.js index aaa367b..4636009 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,10 +1,12 @@ import chai from 'chai'; import chaihttp from 'chai-http'; +// import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; +// import uploadController from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); @@ -65,7 +67,7 @@ describe('AutoMart Test', () => { .send({ firstName: '' }) .end((err, res) => { expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error').with.lengthOf(6); + expect(res.body).to.have.property('error').with.lengthOf(5); done(); }); }); @@ -143,9 +145,10 @@ describe('AutoMart Test', () => { .send(user[3]) .end((err, res) => { expect(res.statusCode).to.equal(200); + // console.log(res.body); expect(res.body).to.have.property('data'); expect(res.body.data).to.have.property('token'); - expect(res.body.data.firstName).to.equal('admin'); + expect(res.body.data.first_name).to.equal('admin'); adminToken = res.body.data.token; done(); }); @@ -176,7 +179,7 @@ describe('AutoMart Test', () => { it('should post a car ad for an existing user', (done) => { chai.request(app) .post('/api/v1/car/') - .set('authtoken', userToken) + .set('token', userToken) .send(car[0]) .end((err, res) => { expect(res.statusCode).to.equal(201); @@ -188,7 +191,7 @@ describe('AutoMart Test', () => { it('should not post an ad with negative car price', (done) => { chai.request(app) .post('/api/v1/car/') - .set('authtoken', userToken) + .set('token', userToken) .send(car[1]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -200,7 +203,7 @@ describe('AutoMart Test', () => { it('should not post an ad with invalid car details', (done) => { chai.request(app) .post('/api/v1/car/') - .set('authtoken', userToken) + .set('token', userToken) .send(car[4]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -209,10 +212,10 @@ describe('AutoMart Test', () => { }); }); - it('should not post cars with unauthorise token', (done) => { + it('should not post cars with unauthorised token', (done) => { chai.request(app) .post('/api/v1/car') - .set('authtoken', adminToken) + .set('token', adminToken) .send(car[0]) .end((err, res) => { expect(res.statusCode).to.equal(403); @@ -225,8 +228,8 @@ describe('AutoMart Test', () => { describe('Purchase Order', () => { it('should not make a purchase order with invalid input data', (done) => { chai.request(app) - .post('/api/v1/order/1') - .set('authtoken', userToken) + .post('/api/v1/order') + .set('token', userToken) .send(order[1]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -237,8 +240,8 @@ describe('AutoMart Test', () => { it('should create a purchase order', (done) => { chai.request(app) - .post('/api/v1/order/1') - .set('authtoken', userToken) + .post('/api/v1/order') + .set('token', userToken) .send(order[0]) .end((err, res) => { expect(res.statusCode).to.equal(201); @@ -250,8 +253,8 @@ describe('AutoMart Test', () => { it('should not make a purchase order with negative price', (done) => { chai.request(app) - .post('/api/v1/order/1') - .set('authtoken', userToken) + .post('/api/v1/order') + .set('token', userToken) .send(order[4]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -259,10 +262,10 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not create a purchase order with unauthorise id', (done) => { + it('should not create a purchase order with unauthorised id', (done) => { chai.request(app) - .post('/api/v1/order/1') - .set('authtoken', adminToken) + .post('/api/v1/order') + .set('token', adminToken) .send(order[0]) .end((err, res) => { expect(res.statusCode).to.equal(403); @@ -275,7 +278,7 @@ describe('AutoMart Test', () => { it('should not make a purchase order if car does not exist', (done) => { chai.request(app) .post('/api/v1/order/6') - .set('authtoken', userToken) + .set('token', userToken) .send(order[0]) .end((err, res) => { expect(res.statusCode).to.equal(404); @@ -289,7 +292,7 @@ describe('AutoMart Test', () => { it('should not update the price of an order if buyerId !== userId', (done) => { chai.request(app) .patch('/api/v1/order/1/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -301,7 +304,7 @@ describe('AutoMart Test', () => { it('should not update the price of a purchase order is status is approved', (done) => { chai.request(app) .patch('/api/v1/order/2/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -313,7 +316,7 @@ describe('AutoMart Test', () => { it('should not update the price of a purchase order with negative price', (done) => { chai.request(app) .patch('/api/v1/order/2/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[5]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -325,7 +328,7 @@ describe('AutoMart Test', () => { it('should update the price of a purchase order', (done) => { chai.request(app) .patch('/api/v1/order/3/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(200); @@ -339,7 +342,7 @@ describe('AutoMart Test', () => { it('should update the price of a purchase order', (done) => { chai.request(app) .patch('/api/v1/order/3/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(200); @@ -352,7 +355,7 @@ describe('AutoMart Test', () => { it('should return error if order is not found', (done) => { chai.request(app) .patch('/api/v1/order/9/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -364,7 +367,7 @@ describe('AutoMart Test', () => { it('should not update the order price with wrong input details', (done) => { chai.request(app) .patch('/api/v1/order/3/price') - .set('authtoken', userToken) + .set('token', userToken) .send(order[3]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -373,10 +376,10 @@ describe('AutoMart Test', () => { }); }); - it('should not update the order price with unauthorized user token', (done) => { + it('should not update the order price with unorized user token', (done) => { chai.request(app) .patch('/api/v1/order/3/price') - .set('authtoken', adminToken) + .set('token', adminToken) .send(order[2]) .end((err, res) => { expect(res.statusCode).to.equal(403); @@ -390,7 +393,7 @@ describe('AutoMart Test', () => { it('should not mark car as sold if not owner of car', (done) => { chai.request(app) .patch('/api/v1/car/1/status') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); @@ -401,7 +404,7 @@ describe('AutoMart Test', () => { it('should not mark car that does not exist', (done) => { chai.request(app) .patch('/api/v1/car/12/status') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); @@ -412,7 +415,7 @@ describe('AutoMart Test', () => { it('should mark a car as sold', (done) => { chai.request(app) .patch('/api/v1/car/3/status') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -421,10 +424,10 @@ describe('AutoMart Test', () => { }); }); - it('should not mark a car as sold with unauthorize token', (done) => { + it('should not mark a car as sold with unorize token', (done) => { chai.request(app) .patch('/api/v1/car/2/status') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(403); expect(res.body).to.have.property('error'); @@ -437,7 +440,7 @@ describe('AutoMart Test', () => { it('should not update the car price on invalid input', (done) => { chai.request(app) .patch('/api/v1/car/1/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[3]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -449,7 +452,7 @@ describe('AutoMart Test', () => { it('should not update a car price that does not exist', (done) => { chai.request(app) .patch('/api/v1/car/12/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -461,7 +464,7 @@ describe('AutoMart Test', () => { it('should not update a car price with negative input', (done) => { chai.request(app) .patch('/api/v1/car/12/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[5]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -473,7 +476,7 @@ describe('AutoMart Test', () => { it('should post a car ad for an existing user', (done) => { chai.request(app) .post('/api/v1/car/') - .set('authtoken', userToken) + .set('token', userToken) .send(car[0]) .end((err, res) => { expect(res.statusCode).to.equal(201); @@ -485,7 +488,7 @@ describe('AutoMart Test', () => { it('should not update a car price that has been sold', (done) => { chai.request(app) .patch('/api/v1/car/3/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -496,7 +499,7 @@ describe('AutoMart Test', () => { it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[2]) .end((err, res) => { expect(res.statusCode).to.equal(200); @@ -508,7 +511,7 @@ describe('AutoMart Test', () => { it('should not update a car price with invalid owner', (done) => { chai.request(app) .patch('/api/v1/car/1/price') - .set('authtoken', userToken) + .set('token', userToken) .send(car[2]) .end((err, res) => { expect(res.statusCode).to.equal(400); @@ -517,10 +520,10 @@ describe('AutoMart Test', () => { }); }); - it('should not update a car price with unauthorize token', (done) => { + it('should not update a car price with unorize token', (done) => { chai.request(app) .patch('/api/v1/car/3/price') - .set('authtoken', adminToken) + .set('token', adminToken) .send(car[2]) .end((err, res) => { expect(res.statusCode).to.equal(403); @@ -534,7 +537,7 @@ describe('AutoMart Test', () => { it('should not view a car that does not exist', (done) => { chai.request(app) .get('/api/v1/car/5/') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(404); expect(res.body).to.have.property('error'); @@ -545,7 +548,7 @@ describe('AutoMart Test', () => { it('should view a specific car', (done) => { chai.request(app) .get('/api/v1/car/3/') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -555,10 +558,10 @@ describe('AutoMart Test', () => { }); - it('should not view a specific car with unauthorise token', (done) => { + it('should not view a specific car with unauthorised token', (done) => { chai.request(app) .get('/api/v1/car/2/') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(403); expect(res.body).to.have.property('error'); @@ -571,7 +574,7 @@ describe('AutoMart Test', () => { it('should view all unsold car', (done) => { chai.request(app) .get('/api/v1/car?status=available') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -582,7 +585,7 @@ describe('AutoMart Test', () => { it('should not view all unsold car with invalid input', (done) => { chai.request(app) .get('/api/v1/car?status=avail') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); @@ -595,7 +598,7 @@ describe('AutoMart Test', () => { it('should view all unsold cars within a price range', (done) => { chai.request(app) .get('/api/v1/car?status=available&min_price=50000&max_price=90000000000') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -606,7 +609,7 @@ describe('AutoMart Test', () => { it('should not view all unsold car if it does not meet the price range', (done) => { chai.request(app) .get('/api/v1/car?status=available&min_price=500000000000&max_price=90000000000') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(404); expect(res.body).to.have.property('error'); @@ -632,7 +635,7 @@ describe('AutoMart Test', () => { it('should delete a car ad', (done) => { chai.request(app) .delete('/api/v1/car/2') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -643,7 +646,7 @@ describe('AutoMart Test', () => { it('should not delete a car ad that does not exist', (done) => { chai.request(app) .delete('/api/v1/car/7') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(404); expect(res.body).to.have.property('error'); @@ -654,7 +657,7 @@ describe('AutoMart Test', () => { it('should return an error with invild input details', (done) => { chai.request(app) .delete('/api/v1/car/hvhjv') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); @@ -665,7 +668,7 @@ describe('AutoMart Test', () => { it('should not delete a car ad with unathorise user', (done) => { chai.request(app) .delete('/api/v1/car/2') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(403); expect(res.body).to.have.property('error'); @@ -678,7 +681,7 @@ describe('AutoMart Test', () => { it('should view all car that exist', (done) => { chai.request(app) .get('/api/v1/car') - .set('authtoken', adminToken) + .set('token', adminToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -691,7 +694,7 @@ describe('AutoMart Test', () => { it('should view all car that exist', (done) => { chai.request(app) .get('/api/v1/car?body_type=car') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -701,7 +704,7 @@ describe('AutoMart Test', () => { it('should not view all car that does not exist with a particular body type', (done) => { chai.request(app) .get('/api/v1/car?body_type=van') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(404); expect(res.body).to.have.property('error'); @@ -710,11 +713,53 @@ describe('AutoMart Test', () => { }); }); + // describe('Upload', () => { + // let upload; + // beforeEach(() => { + // upload = sinon.stub(uploadController, 'upload').returns(() => {}); + // // upload.yields('result'); + // }); + // afterEach(() => { + // upload.restore(); + // }); + // it('should not view all car that does not exist with a particular body type', (done) => { + // upload.yields('result'); + // console.log(upload); + // // uploadImage.yields("link to image"); + // chai.request(app) + // // uploadImage.yields('link to image'); + // .post('/api/v1/upload') + // .set('token', userToken) + // .field('Content-Type', 'multipart/form-data') + // .attach('photo', './server/test/test.jpg', 'test.jpg') + // .end((err, res) => { + // console.log(res.body); + // // expect(res.statusCode).to.equal(200); + // expect(res.body).to.equal('result'); + // done(); + // }); + // }); + // }); + describe('UploadCarImage', () => { + it('should flag a car as fradulent', (done) => { + chai.request(app) + .patch('/api/v1/cars/2') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(200); + expect(res.body).to.have.property('data'); + // expect(res.body.data).to.have.property('id'); + done(); + }); + }); + }); + describe('Flag Report', () => { it('should flag a car as fradulent', (done) => { chai.request(app) .post('/api/v1/flag/3') - .set('authtoken', userToken) + .set('token', userToken) .send(flag[0]) .end((err, res) => { expect(res.statusCode).to.equal(201); @@ -727,7 +772,7 @@ describe('AutoMart Test', () => { it('should flag a car as fradulent', (done) => { chai.request(app) .post('/api/v1/flag/39') - .set('authtoken', userToken) + .set('token', userToken) .send(flag[0]) .end((err, res) => { expect(res.statusCode).to.equal(404); @@ -738,7 +783,7 @@ describe('AutoMart Test', () => { it('should not flag a car with invalid input details', (done) => { chai.request(app) .post('/api/v1/flag/2') - .set('authtoken', userToken) + .set('token', userToken) .end((err, res) => { expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); @@ -746,10 +791,10 @@ describe('AutoMart Test', () => { }); }); - it('should not flag a car with unauthorise access', (done) => { + it('should not flag a car with unauthorised access', (done) => { chai.request(app) .post('/api/v1/flag/3') - .set('authtoken', adminToken) + .set('token', adminToken) .send(flag[0]) .end((err, res) => { expect(res.statusCode).to.equal(403); @@ -759,11 +804,11 @@ describe('AutoMart Test', () => { }); }); - describe('Authentication', () => { - it('should not post a car ads with unauthorized id', (done) => { + describe('entication', () => { + it('should not post a car ads with unorized id', (done) => { chai.request(app) .post('/api/v1/car') - .set('authtoken', 'jhosjfhaojfhoa') + .set('token', 'jhosjfhaojfhoa') .end((err, res) => { expect(res.statusCode).to.equal(401); expect(res.body).to.have.property('error'); From 6adcd9dc811122a0abbc574abec1631510f19619 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2019 06:02:37 +0000 Subject: [PATCH 02/16] chore(deps): bump lodash from 4.17.11 to 4.17.14 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.14. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.14) Signed-off-by: dependabot[bot] --- package-lock.json | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8196ac0..5f485d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2951,7 +2951,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2972,12 +2973,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2992,17 +2995,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3119,7 +3125,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3131,6 +3138,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3145,6 +3153,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3152,12 +3161,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3176,6 +3187,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3256,7 +3268,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3268,6 +3281,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3353,7 +3367,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3389,6 +3404,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3408,6 +3424,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3451,12 +3468,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -4550,9 +4569,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==" }, "lodash.flattendeep": { "version": "4.4.0", From 7bd1a83faa79861909e41f02e5051000d255d076 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 03/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 2 +- server/controllers/uploadController.js | 23 +++++++++++---- server/helper/utilities.js | 2 ++ server/middleware/authentication.js | 2 ++ server/router/uploadRoute.js | 2 +- server/test/test.js | 41 +++++++++++++++++++++++--- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..ba8cd7f 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -90,7 +90,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 0c068bb..20b66e9 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -22,6 +22,8 @@ class authenticator { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; + console.log(req.body, '=====> body'); + console.log(req.params, '====> params'); return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..fc478a0 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -740,8 +742,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +783,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From 86283a24926d93a4d61052ad8bee4b110a681acb Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 04/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 10 ++--- server/controllers/uploadController.js | 23 +++++++++--- server/helper/utilities.js | 2 + server/middleware/authentication.js | 2 + server/router/uploadRoute.js | 2 +- server/test/test.js | 52 ++++++++++++++++++-------- 6 files changed, 63 insertions(+), 28 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..f25f7f3 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -57,13 +57,11 @@ class carController { if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (carCheck[0].status !== 'sold') { - await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); + await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails); - } return utilities.errorstatus(res, 400, 'Car Already Sold'); + return utilities.successStatus(res, 200, 'data', carDetails); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -90,7 +88,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 0c068bb..20b66e9 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -22,6 +22,8 @@ class authenticator { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; + console.log(req.body, '=====> body'); + console.log(req.params, '====> params'); return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..000eb29 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -485,17 +487,6 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not update a car price that has been sold', (done) => { - chai.request(app) - .patch('/api/v1/car/3/price') - .set('token', userToken) - .send(car[2]) - .end((err, res) => { - expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error'); - done(); - }); - }); it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') @@ -740,8 +731,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +772,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From d563f37f025b7212beaa6a63599fde29572ee54d Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 05/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 10 ++--- server/controllers/uploadController.js | 23 +++++++++--- server/helper/utilities.js | 2 + server/middleware/authentication.js | 2 + server/router/uploadRoute.js | 2 +- server/test/test.js | 52 ++++++++++++++++++-------- 6 files changed, 63 insertions(+), 28 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..8f9a0ea 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -57,13 +57,11 @@ class carController { if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (carCheck[0].status !== 'sold') { - await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); + await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails); - } return utilities.errorstatus(res, 400, 'Car Already Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -90,7 +88,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 0c068bb..20b66e9 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -22,6 +22,8 @@ class authenticator { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; + console.log(req.body, '=====> body'); + console.log(req.params, '====> params'); return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..000eb29 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -485,17 +487,6 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not update a car price that has been sold', (done) => { - chai.request(app) - .patch('/api/v1/car/3/price') - .set('token', userToken) - .send(car[2]) - .end((err, res) => { - expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error'); - done(); - }); - }); it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') @@ -740,8 +731,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +772,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From b622fe8d96dcc6fab6c169518db34054bc6d6c9a Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 06/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 28 +++++++------- server/controllers/uploadController.js | 23 +++++++++--- server/helper/utilities.js | 2 + server/middleware/authentication.js | 2 + server/router/uploadRoute.js | 2 +- server/test/test.js | 52 ++++++++++++++++++-------- 6 files changed, 73 insertions(+), 36 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..2d65cdd 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -28,18 +28,20 @@ class carController { try { const { id } = req.user; const { carId } = req.params; + console.log(req.body === {}, req.body === null, req.body === undefined); + if (JSON.stringify(req.body) === '{}') { + const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - - if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); + if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (id === carCheck[0].owner) { - await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); + if (id === carCheck[0].owner) { + await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails[0]); - } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); + } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); + } return utilities.errorstatus(res, 400, 'Request Body Should Not Have A Value'); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -57,13 +59,11 @@ class carController { if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (carCheck[0].status !== 'sold') { - await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); + await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails); - } return utilities.errorstatus(res, 400, 'Car Already Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -90,7 +90,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 0c068bb..20b66e9 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -22,6 +22,8 @@ class authenticator { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; + console.log(req.body, '=====> body'); + console.log(req.params, '====> params'); return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..000eb29 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -485,17 +487,6 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not update a car price that has been sold', (done) => { - chai.request(app) - .patch('/api/v1/car/3/price') - .set('token', userToken) - .send(car[2]) - .end((err, res) => { - expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error'); - done(); - }); - }); it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') @@ -740,8 +731,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +772,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From d282e4cfb7bff4917813204704a731985460a05d Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 07/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 31 ++++++++------- server/controllers/uploadController.js | 23 +++++++++--- server/helper/utilities.js | 2 + server/router/uploadRoute.js | 2 +- server/test/test.js | 52 ++++++++++++++++++-------- 5 files changed, 74 insertions(+), 36 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..3f84409 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -28,18 +28,23 @@ class carController { try { const { id } = req.user; const { carId } = req.params; + console.log(req.body, '=====> body'); + console.log(req.params, '====> params'); + // console.log(req.body === {}, req.body === null, req.body === undefined); + console.log(JSON.stringify(req.body) === '{}') + if (JSON.stringify(req.body) === '{}') { + const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - - if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); + if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (id === carCheck[0].owner) { - await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); + if (id === carCheck[0].owner) { + await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails[0]); - } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); + } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); + } return utilities.errorstatus(res, 500, 'Request Body Should Not Have A Value'); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -57,13 +62,11 @@ class carController { if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (carCheck[0].status !== 'sold') { - await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); + await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails); - } return utilities.errorstatus(res, 400, 'Car Already Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -90,7 +93,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..000eb29 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -485,17 +487,6 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not update a car price that has been sold', (done) => { - chai.request(app) - .patch('/api/v1/car/3/price') - .set('token', userToken) - .send(car[2]) - .end((err, res) => { - expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error'); - done(); - }); - }); it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') @@ -740,8 +731,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +772,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From a60415630e9bdfc47d47b578dc6873c1124031d4 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Mon, 15 Jul 2019 18:33:50 +0100 Subject: [PATCH 08/16] bg(feedback) implement feedback from auto grader >- implement user can view all cars [Fixes #167299563] --- server/controllers/carController.js | 10 ++-- server/controllers/uploadController.js | 23 ++++++--- server/helper/schema.js | 4 ++ server/helper/utilities.js | 2 + server/middleware/validator.js | 12 +++++ server/router/carRoute.js | 2 +- server/router/uploadRoute.js | 2 +- server/test/test.js | 65 ++++++++++++++++++++------ 8 files changed, 91 insertions(+), 29 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 117759f..8f9a0ea 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -57,13 +57,11 @@ class carController { if (id !== carCheck[0].owner) return utilities.errorstatus(res, 400, 'You Are not allowed to perform this action'); - if (carCheck[0].status !== 'sold') { - await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); + await dbMethods.updateDbRow('cars', { price: updatePrice }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails); - } return utilities.errorstatus(res, 400, 'Car Already Sold'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } @@ -90,7 +88,7 @@ class carController { const cars = await pool.query('select * from cars'); - if (isAdmin && !status && !bodyType) { + if (!status && !bodyType) { return utilities.successStatus(res, 200, 'data', cars.rows); } diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 1bcb2b9..6ed759f 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -2,20 +2,31 @@ import utilities from '../helper/utilities'; const cloudinary = require('cloudinary').v2; +export const obj = { + getImage: async file => new Promise((resolve, reject) => { + cloudinary.uploader.upload(file.tempFilePath, (err, result) => { + if (err) reject(err); + resolve(result.url); + }); + }), +}; + cloudinary.config({ cloud_name: process.env.cloud_name, api_key: process.env.api_key, api_secret: process.env.api_secret, }); -class uploadController { - static upload(req, res) { +export class uploadController { + static async upload(req, res) { const file = req.files.photo; - cloudinary.uploader.upload(file.tempFilePath, (err, result) => { - if (err) return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + try { + const result = await obj.getImage(file); return utilities.successStatus(res, 200, 'data', result.url); - }); + } catch (error) { + return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); + } } } -export default uploadController; +// export default { uploadController, getImage }; diff --git a/server/helper/schema.js b/server/helper/schema.js index 18ebe34..bb186fb 100644 --- a/server/helper/schema.js +++ b/server/helper/schema.js @@ -37,6 +37,10 @@ const schema = { car_id: Joi.number().required(), }), + sold: Joi.object().keys({ + status: Joi.string().required().valid('sold'), + }), + updateOrder: Joi.object().keys({ price: Joi.number().required(), }), diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 28e49e7..62a35b2 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,6 +37,7 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { + console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -55,6 +56,7 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; + console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/validator.js b/server/middleware/validator.js index e19e86b..dff62e5 100644 --- a/server/middleware/validator.js +++ b/server/middleware/validator.js @@ -169,6 +169,18 @@ class validate { * @memberof Controllers */ + static validateSold(req, res, next) { + const { status } = req.body; + const validateObject = { status }; + + const error = util.validateJoi(validateObject, schema.sold); + + if (error) { + return util.errorstatus(res, 400, error); + } + return next(); + } + static validateUpdateCar(req, res, next) { const { price } = req.body; const validateObject = { price }; diff --git a/server/router/carRoute.js b/server/router/carRoute.js index 91535ba..5a782e8 100644 --- a/server/router/carRoute.js +++ b/server/router/carRoute.js @@ -5,7 +5,7 @@ import authenticator from '../middleware/authentication'; const carRouter = express(); carRouter.post('/car/', authenticator.authenticateUser, authenticator.isUser, validator.validateCar, carController.postAds); -carRouter.patch('/car/:carId/status', authenticator.authenticateUser, authenticator.isUser, carController.markSold); +carRouter.patch('/car/:carId/status', authenticator.authenticateUser, authenticator.isUser, validator.validateSold, carController.markSold); carRouter.patch('/car/:carId/price', authenticator.authenticateUser, authenticator.isUser, validator.validateUpdateCar, carController.updateCar); carRouter.get('/car/:carId/', authenticator.authenticateUser, authenticator.isUser, carController.specificCar); carRouter.get('/car', authenticator.authenticateUser, validator.validateGetCar, carController.car); diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 18c11bf..6bb6819 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -1,5 +1,5 @@ import express from 'express'; -import uploadController from '../controllers/uploadController'; +import { uploadController } from '../controllers/uploadController'; import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; diff --git a/server/test/test.js b/server/test/test.js index 4636009..9ea8251 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -1,18 +1,19 @@ import chai from 'chai'; import chaihttp from 'chai-http'; -// import sinon from 'sinon'; +import sinon from 'sinon'; import app from '../app'; import user from './data/user'; import car from './data/car'; import order from './data/order'; import flag from './data/flag'; -// import uploadController from '../controllers/uploadController'; +import { obj } from '../controllers/uploadController'; const { expect } = chai; chai.use(chaihttp); let userToken; let adminToken; +let upload; describe('AutoMart Test', () => { describe('/Display welcome message', () => { @@ -257,6 +258,7 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { + console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -401,6 +403,18 @@ describe('AutoMart Test', () => { }); }); + it('should not mark car as sold if not owner of car', (done) => { + chai.request(app) + .patch('/api/v1/car/1/status') + .set('token', userToken) + .send({ email: '1' }) + .end((err, res) => { + expect(res.statusCode).to.equal(400); + expect(res.body).to.have.property('error'); + done(); + }); + }); + it('should not mark car that does not exist', (done) => { chai.request(app) .patch('/api/v1/car/12/status') @@ -416,6 +430,7 @@ describe('AutoMart Test', () => { chai.request(app) .patch('/api/v1/car/3/status') .set('token', userToken) + .send({ status: 'sold' }) .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); @@ -485,17 +500,6 @@ describe('AutoMart Test', () => { done(); }); }); - it('should not update a car price that has been sold', (done) => { - chai.request(app) - .patch('/api/v1/car/3/price') - .set('token', userToken) - .send(car[2]) - .end((err, res) => { - expect(res.statusCode).to.equal(400); - expect(res.body).to.have.property('error'); - done(); - }); - }); it('should update a car price', (done) => { chai.request(app) .patch('/api/v1/car/4/price') @@ -740,8 +744,40 @@ describe('AutoMart Test', () => { // }); // }); // }); - describe('UploadCarImage', () => { + + describe('Upload', () => { + beforeEach(async () => { + }); + afterEach(() => { + upload.restore(); + }); + it('should not view all car that does not exist with a particular body type', async () => { + upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); + const res = await chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .field('Content-Type', 'multipart/form-data') + .attach('photo', './server/test/test.jpg', 'test.jpg'); + console.log(res.body); + expect(res.statusCode).to.equal(200); + expect(res.body.data).to.equal('result'); + }); + it('should flag a car as fradulent', (done) => { + chai.request(app) + .post('/api/v1/upload') + .set('token', userToken) + .send({ car_image: '' }) + .end((err, res) => { + expect(res.statusCode).to.equal(404); + expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + describe('UploadCarImage', () => { + it('should', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) @@ -749,7 +785,6 @@ describe('AutoMart Test', () => { .end((err, res) => { expect(res.statusCode).to.equal(200); expect(res.body).to.have.property('data'); - // expect(res.body.data).to.have.property('id'); done(); }); }); From 6e1f3f614833684dca3064e60c58140ca19cce92 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Tue, 16 Jul 2019 00:20:19 +0100 Subject: [PATCH 09/16] Bug(Fix) mark car as sold [Fixes #167307923] --- server/controllers/carController.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 3f84409..8f9a0ea 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -28,23 +28,18 @@ class carController { try { const { id } = req.user; const { carId } = req.params; - console.log(req.body, '=====> body'); - console.log(req.params, '====> params'); - // console.log(req.body === {}, req.body === null, req.body === undefined); - console.log(JSON.stringify(req.body) === '{}') - if (JSON.stringify(req.body) === '{}') { - const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); + const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + + if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (id === carCheck[0].owner) { - await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); + if (id === carCheck[0].owner) { + await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails[0]); - } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); - } return utilities.errorstatus(res, 500, 'Request Body Should Not Have A Value'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); + } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } From ba64f0761c0e82d9ea8fdaf9447833a06d68cb61 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Tue, 16 Jul 2019 00:20:19 +0100 Subject: [PATCH 10/16] Bug(Fix) mark car as sold [Fixes #167307923] --- server/controllers/carController.js | 21 ++++++++------------ server/helper/utilities.js | 2 -- server/middleware/authentication.js | 6 ++++-- server/test/test.js | 30 ----------------------------- 4 files changed, 12 insertions(+), 47 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 3f84409..8f9a0ea 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -28,23 +28,18 @@ class carController { try { const { id } = req.user; const { carId } = req.params; - console.log(req.body, '=====> body'); - console.log(req.params, '====> params'); - // console.log(req.body === {}, req.body === null, req.body === undefined); - console.log(JSON.stringify(req.body) === '{}') - if (JSON.stringify(req.body) === '{}') { - const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); + const carCheck = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + + if (!carCheck[0]) return utilities.errorstatus(res, 400, 'Car Does Not Exist'); - if (id === carCheck[0].owner) { - await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); + if (id === carCheck[0].owner) { + await dbMethods.updateDbRow('cars', { status: 'sold' }, { id: Number(carId) }); - const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); + const carDetails = await dbMethods.readFromDb('cars', '*', { id: Number(carId) }); - return utilities.successStatus(res, 200, 'data', carDetails[0]); - } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); - } return utilities.errorstatus(res, 500, 'Request Body Should Not Have A Value'); + return utilities.successStatus(res, 200, 'data', carDetails[0]); + } return utilities.errorstatus(res, 400, 'User Can Not Mark This Car As Sold'); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); } diff --git a/server/helper/utilities.js b/server/helper/utilities.js index 62a35b2..28e49e7 100644 --- a/server/helper/utilities.js +++ b/server/helper/utilities.js @@ -37,7 +37,6 @@ class Utilities { */ static errorstatus(res, statusCode, errorMessage) { - console.log(errorMessage); return res.status(statusCode).json({ status: statusCode, error: errorMessage, @@ -56,7 +55,6 @@ class Utilities { static successStatus(res, status, key, object) { const response = { status }; response[key] = object; - console.log(response); return res.status(status).json(response); } diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 20b66e9..3c1e70a 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -16,14 +16,16 @@ class authenticator { }); } const verify = jwt.verify(token, process.env.secretKey, (err, decoded) => decoded); + req.decoder = verify.id; + const isUser = await dbMethods.readFromDb('users', '*', { id: verify.id }); if (!isUser[0]) { return Utilities.errorstatus(res, 401, 'Unauthorise User, Please Sign Up'); } + req.user = { id: isUser[0].id, email: isUser[0].email, isAdmin: isUser[0].is_admin }; - console.log(req.body, '=====> body'); - console.log(req.params, '====> params'); + return next(); } catch (error) { return Utilities.errorstatus(res, 401, 'Unauthorization User'); diff --git a/server/test/test.js b/server/test/test.js index 9ea8251..fe9b8e2 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -258,7 +258,6 @@ describe('AutoMart Test', () => { .set('token', userToken) .send(order[4]) .end((err, res) => { - console.log(res.body); expect(res.statusCode).to.equal(400); expect(res.body).to.have.property('error'); done(); @@ -717,34 +716,6 @@ describe('AutoMart Test', () => { }); }); - // describe('Upload', () => { - // let upload; - // beforeEach(() => { - // upload = sinon.stub(uploadController, 'upload').returns(() => {}); - // // upload.yields('result'); - // }); - // afterEach(() => { - // upload.restore(); - // }); - // it('should not view all car that does not exist with a particular body type', (done) => { - // upload.yields('result'); - // console.log(upload); - // // uploadImage.yields("link to image"); - // chai.request(app) - // // uploadImage.yields('link to image'); - // .post('/api/v1/upload') - // .set('token', userToken) - // .field('Content-Type', 'multipart/form-data') - // .attach('photo', './server/test/test.jpg', 'test.jpg') - // .end((err, res) => { - // console.log(res.body); - // // expect(res.statusCode).to.equal(200); - // expect(res.body).to.equal('result'); - // done(); - // }); - // }); - // }); - describe('Upload', () => { beforeEach(async () => { }); @@ -758,7 +729,6 @@ describe('AutoMart Test', () => { .set('token', userToken) .field('Content-Type', 'multipart/form-data') .attach('photo', './server/test/test.jpg', 'test.jpg'); - console.log(res.body); expect(res.statusCode).to.equal(200); expect(res.body.data).to.equal('result'); }); From 0772da4842472ff0e5b473d5b520da745225b66e Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Sat, 20 Jul 2019 07:06:18 +0100 Subject: [PATCH 11/16] Bug(swagger) fix swagger error [Fixes #167412348] --- server/controllers/uploadController.js | 2 +- server/controllers/userController.js | 12 +++---- server/test/test.js | 10 +++--- swagger.yaml | 50 ++++++++++++++------------ 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/server/controllers/uploadController.js b/server/controllers/uploadController.js index 6ed759f..c815732 100644 --- a/server/controllers/uploadController.js +++ b/server/controllers/uploadController.js @@ -22,7 +22,7 @@ export class uploadController { const file = req.files.photo; try { const result = await obj.getImage(file); - return utilities.successStatus(res, 200, 'data', result.url); + return utilities.successStatus(res, 200, 'data', result); } catch (error) { return utilities.errorstatus(res, 400, 'Network Error, Could not Upload Image'); } diff --git a/server/controllers/userController.js b/server/controllers/userController.js index 2a7b6c5..9557b3b 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -20,7 +20,7 @@ class userController { const user = await dbMethods.readFromDb('users', '*', { email }); if (user[0]) { - return utilities.errorstatus(res, 400, 'User Already Exist'); + return utilities.errorstatus(res, 409, 'User Already Exist'); } const is_admin = false; const hashpassword = secure.passwordhash(password); @@ -82,16 +82,16 @@ class userController { return utilities.errorstatus(res, 400, 'Invalid User'); } const { - id, firstname, lastname, phonenumber, profilepic, + id, first_name, last_name, address, profile_pic, } = user[0]; return utilities.successStatus(res, 200, 'data', { id, - firstName: firstname, - lastName: lastname, + first_name, + last_name, email, - phoneNumber: phonenumber, - profilepic, + address, + profile_pic, }); } catch (error) { return utilities.errorstatus(res, 500, 'SERVER ERROR'); diff --git a/server/test/test.js b/server/test/test.js index fe9b8e2..879271b 100644 --- a/server/test/test.js +++ b/server/test/test.js @@ -56,7 +56,7 @@ describe('AutoMart Test', () => { .post('/api/v1/auth/signup') .send(user[0]) .end((err, res) => { - expect(res.statusCode).to.equal(400); + expect(res.statusCode).to.equal(409); expect(res.body).to.have.property('error'); expect(res.body.error).to.equal('User Already Exist'); done(); @@ -722,7 +722,7 @@ describe('AutoMart Test', () => { afterEach(() => { upload.restore(); }); - it('should not view all car that does not exist with a particular body type', async () => { + it('should upload an image ', async () => { upload = sinon.stub(obj, 'getImage').resolves({ url: 'result' }); const res = await chai.request(app) .post('/api/v1/upload') @@ -730,10 +730,10 @@ describe('AutoMart Test', () => { .field('Content-Type', 'multipart/form-data') .attach('photo', './server/test/test.jpg', 'test.jpg'); expect(res.statusCode).to.equal(200); - expect(res.body.data).to.equal('result'); + expect(res.body.data.url).to.equal('result'); }); - it('should flag a car as fradulent', (done) => { + it('should not upload with an image file', (done) => { chai.request(app) .post('/api/v1/upload') .set('token', userToken) @@ -747,7 +747,7 @@ describe('AutoMart Test', () => { }); describe('UploadCarImage', () => { - it('should', (done) => { + it('should update car image url', (done) => { chai.request(app) .patch('/api/v1/cars/2') .set('token', userToken) diff --git a/swagger.yaml b/swagger.yaml index 3c34854..ade745b 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -34,8 +34,8 @@ paths: - Welcome summary : Test get request responses: - '201': - description: Created + '200': + description: Ok content: application/json: schema: @@ -54,16 +54,16 @@ paths: schema: type: object properties: - firstName: + first_name: type: string - lastName: + last_name: type: string email: type: string password: type: string - phoneNumber: - type: number + address: + type: string responses: 201: description: Created @@ -126,7 +126,7 @@ paths: type: string model: type: string - bodyType: + body_type: type: string state: type: string @@ -149,7 +149,7 @@ paths: get: tags: - - Admin + - Cars summary : View all posted ads whether sold or available. security: - ApiKeyAuth: [] @@ -168,20 +168,13 @@ paths: schema: $ref: "#/components/schemas/responce" - /order/{carId}: + /order/: post: tags: - Orders summary : Create a purchase order. security: - ApiKeyAuth: [] - parameters: - - name: carId - in: path - required: true - description: Car identity - schema: - type : integer requestBody: required: true @@ -190,7 +183,9 @@ paths: schema: type: object properties: - priceOffered: + amount: + type: number + car_id: type: number responses: @@ -229,7 +224,7 @@ paths: schema: type: object properties: - newPriceOffered: + price: type: number responses: @@ -262,6 +257,15 @@ paths: description: car Identity schema: type : number + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + status: + type: string responses: 200: @@ -501,7 +505,7 @@ components: ApiKeyAuth: type: apiKey in: header - name: authtoken + name: token description: Requests should pass an authtoken header. @@ -517,7 +521,7 @@ components: type: string createdOn: type: string - bodyType: + body_type: type: string state: type: string @@ -563,13 +567,13 @@ components: properties: token: type: string - firstName: + first_name: type: string - lastName: + last_name: type: string email: type: string - profilePic: + profile_pic: type: string responce: From de77be634555546d1257345380d4ccfe833cf9a4 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Sun, 21 Jul 2019 04:27:07 +0100 Subject: [PATCH 12/16] feat(main page) add functionality to user main page -> consume user api endpoints [Delivers #167412437] --- UI/css/main.css | 96 ++++++++- UI/css/style.css | 2 +- UI/index.html | 4 +- UI/js/automart.js | 112 ++++++++++ UI/js/config.js | 8 +- UI/js/login.js | 14 +- UI/js/main.js | 141 ++++++------ UI/js/onLoad.js | 165 ++++++++++++++ UI/js/user.js | 12 +- UI/main.html | 536 +++++++++------------------------------------- 10 files changed, 560 insertions(+), 530 deletions(-) create mode 100644 UI/js/automart.js create mode 100644 UI/js/onLoad.js diff --git a/UI/css/main.css b/UI/css/main.css index 320fba2..bc3138c 100644 --- a/UI/css/main.css +++ b/UI/css/main.css @@ -156,7 +156,8 @@ nav{ } .profile_img{ padding-top: 10px; - background: white; + background: white; + height: 210px; } .profile_img > img{ @@ -323,6 +324,38 @@ article{ font-size: 20px; } +.home::before{ + position: absolute; + content: '\f015'; + font-weight: 900; + font-size: 25px; + top:-5px; + right:200px; +} + +.pos::before{ + position: absolute; + content: '\f067'; + font-weight: 900; + left:70px; + font-size:20px +} + +.ord::before{ + position: absolute; + content: '\f218'; + font-weight: 900; + font-size: 20px; + left: 70px +} +.mads::before{ + position: absolute; + content: '\f02c'; + font-weight: 900; + left:70px; + font-size:20px +} + .grow { transform: scale(1); } @@ -339,7 +372,7 @@ article{ justify-content: center } -.tag-button > button{ +.tag-button > button, .postAds{ margin: 60px 10px 10px 10px; padding:20px; font-size: 16px; @@ -350,6 +383,11 @@ article{ transition: all 0.25s linear; } +.postAds{ + margin:0; + margin-right:120px; +} + .tag-button > button:nth-child(1){ background: red; } @@ -429,6 +467,53 @@ article > p{ margin: 7px } +.loader { + border: 5px solid #f3f3f3; + border-radius: 50%; + border-top: 5px solid #3498db; + width: 20px; + height: 20px; + animation: spin 1s linear infinite; + position: absolute; + /* top: auto; */ + /* bottom: auto; */ + left: 0; + right:0; + margin: auto; + /* margin-top: -5px; */ + /* padding: */ + + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + + .connn{ + display: flex; + align-items: center; + width: 100%; + /* position: relative; */ + } + .loaderw { + border: 5px solid #f3f3f3; + border-radius: 50%; + border-top: 5px solid #3498db; + width: 40px; + height: 40px; + animation: spin 1s linear infinite; + position: absolute; + top: 250px; + /* bottom: 0; */ + left: 0; + right:0; + margin: auto; + /* margin-top: -5px; */ + /* padding: */ + + } #main_bar{ height: 91vh; @@ -636,14 +721,15 @@ h3{ width:400px; height:300px; border:2px solid grey; - padding: 3px + padding: 3px; + margin-right: 150px; } .car-model > label{ display: flex; - margin: auto; + margin-left: 100px; margin-top: 20px; padding:10px; - width:25%; + width:20%; border: 2px solid slateblue; background: white; transition: all 0.25 linear ease; diff --git a/UI/css/style.css b/UI/css/style.css index 22c456e..e9366de 100644 --- a/UI/css/style.css +++ b/UI/css/style.css @@ -111,7 +111,7 @@ nav{ rgba(0,0,0,0.8), rgba(96,73,203,0.8) ), - url(../img/34.jpg) no-repeat; + url(http://res.cloudinary.com/amoslv/image/upload/v1563476573/eleouih7selykavbixk6.jpg) no-repeat; background-size: cover; display: flex; align-items: center; diff --git a/UI/index.html b/UI/index.html index bd43f83..2b10484 100644 --- a/UI/index.html +++ b/UI/index.html @@ -269,8 +269,8 @@

24 Hour

- - + + diff --git a/UI/js/automart.js b/UI/js/automart.js new file mode 100644 index 0000000..1d1c505 --- /dev/null +++ b/UI/js/automart.js @@ -0,0 +1,112 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-undef */ + +const showBox = document.querySelector('.scrolling-ads'); +const input = document.querySelector('.iin'); +const post = document.querySelector('.postAds'); +const spinne = document.querySelector('.spinne'); +const spin = document.querySelector('.spin'); +const Bar = document.querySelector('#bar'); +const modelDetails = document.querySelector('.model-details'); +const profile = document.querySelector('.pross'); + + +modelDetails.style.display = 'none'; +showBox.style.display = 'none'; +Bar.style.display = 'none'; +let carStatus; +const displayCars = (carObj) => { + carStatus = 'newest'; + const { + id, car_image, manufacturer, model, status, price, + } = carObj; + // console.log(carObj); + if (status === 'sold') carStatus = 'solder'; + const carHtml = ` + +
+ +

${manufacturer} ${model}

+

Nigeria

+

N${price}

+
+
`; + + return carHtml; +}; + +const getCarDetails = () => { + const manufacturer = document.querySelector('.manufacturer').value; + const model = document.querySelector('.model').value; + const bodyType = document.querySelector('.body-type').value; + const price = document.querySelector('.price').value; + const state = document.querySelector('.state').value; + // const location = document.querySelector('.locationn').value; + const carObj = { + manufacturer, model, body_type: bodyType, price, state, + }; + return carObj; +}; +let carimage; + +input.addEventListener('input', async (e) => { + // console.log(profile); + profile.attributes.src.value = URL.createObjectURL(input.files[0]); + const fet = async (formData) => { + const object = { + method: 'post', + headers: new Headers({ + token, + }), + body: formData, + }; + + const response = await fetch(`${devURL}upload`, object); + const statusCode = response.status; + const responseObj = await response.json(); + return { responseObj, statusCode }; + }; + + const formData = new FormData(); + formData.append('photo', input.files[0]); + formData.append('files', 'photo'); + + spin.showModal(); + + carimage = await fet(formData); + // console.log(carimage); + + spin.className = 'grow'; + + if (carimage.statusCode === 200) { + modelDetails.style.display = 'block'; + spin.close(); + // post.disable = false; + } + + if (carimage.statusCode === 400) { + // modelDetails.style.display = 'none'; + notify.textContent = 'Network Error, Please Reload'; + spin.close(); + } +}); +// console.log(post.disable = true); +post.addEventListener('click', async () => { + if (carimage.responseObj.data) { + const carDetails = getCarDetails(); + const url = `${devURL}/car/`; + const postCar = await fetcher(url, 'POST', carDetails); + + if (postCar.statusCode === 201) { + const urx = `${devURL}cars/${postCar.responseObj.data.id}`; + const { responseObj, statusCode } = await fetcher(urx, 'PATCH', { car_image: carimage.responseObj.data }); + if (statusCode === 200) { + // console.log(responseObj); + window.location = 'main.html'; + } + } + // if (statusCode === 400) { + + // } + } +}); diff --git a/UI/js/config.js b/UI/js/config.js index 69ef56e..2234363 100644 --- a/UI/js/config.js +++ b/UI/js/config.js @@ -1,7 +1,7 @@ /* eslint-disable no-unused-vars */ /* eslint-disable no-undef */ -const { authtoken } = localStorage; +const { token } = localStorage; // const devURL = 'http://localhost:3000/api/v1/'; @@ -13,13 +13,15 @@ const fetcher = async (url, method, body = undefined) => { method, headers: new Headers({ 'Content-Type': 'application/json', - authtoken, + token, }), body: JSON.stringify(body), }; + // console.log(object); const response = await fetch(url, object); + // console.log(response); const statusCode = response.status; const responseObj = await response.json(); - console.log(responseObj); + // console.log(responseObj); return { responseObj, statusCode }; }; diff --git a/UI/js/login.js b/UI/js/login.js index 0c19323..a652305 100644 --- a/UI/js/login.js +++ b/UI/js/login.js @@ -75,7 +75,7 @@ display.addEventListener('click', async (event) => { display.classList.add('effect'); display.classList.remove('uuu'); } - + if (checker && !submitFlag) { const url = `${devURL}user`; const { responseObj, statusCode } = await fetcher(url, 'POST', details); @@ -83,9 +83,10 @@ display.addEventListener('click', async (event) => { if (statusCode === 200) { add.classList.add('move-left'); add.classList.remove('move-right'); - userName.textContent = `${responseObj.data.firstName} ${responseObj.data.lastName}`; + console.log(responseObj); + userName.textContent = `${responseObj.data.first_name} ${responseObj.data.last_name}`; userEmail.textContent = `${responseObj.data.email}`; - image.attributes.src.value = 'img/avatar.png'; + image.attributes.src.value = `${responseObj.data.profile_pic}`; detailss.style.opacity = '1'; goBack.style.display = 'initial'; spinner.style.display = 'none'; @@ -127,7 +128,9 @@ display.addEventListener('click', async (event) => { no.style.display = 'block'; no.style.color = 'rgb(23, 148, 23)'; const { token } = responseObj.data; - localStorage.setItem('authtoken', token); + localStorage = ''; + localStorage.setItem('token', token); + localStorage.setItem('userDet', input[1].value); if (responseObj.data.email === 'admin@automart.com') { setTimeout(() => { window.location = 'admin.html'; }, 3000); @@ -146,7 +149,6 @@ display.addEventListener('click', async (event) => { } if (!checker) { - console.log('im here'); spinner.style.display = 'none'; display.classList.add('effect'); display.classList.remove('uuu'); @@ -181,4 +183,4 @@ window.addEventListener('load', () => { inputs.forEach((input) => { input.value = ''; }); -}); \ No newline at end of file +}); diff --git a/UI/js/main.js b/UI/js/main.js index b3a5dae..5afe160 100644 --- a/UI/js/main.js +++ b/UI/js/main.js @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ const a = document.querySelectorAll('a'); const imgg = document.querySelector('.amos'); const purchase = document.querySelector('.purchase-btn'); @@ -7,7 +8,7 @@ const purchaseDialog = document.querySelector('.purchase'); const leftBar = document.querySelector('#left_bar'); const mainBar = document.querySelector('#main_bar'); const rightBar = document.querySelector('#right_bar'); -const Bar = document.querySelector('#bar'); +// const Bar = document.querySelector('#bar'); const updateDialog = document.querySelector('.update-dialog'); const acceptDialog = document.querySelector('.accept-dialog'); const counterDialog = document.querySelector('.counter-dialog'); @@ -21,8 +22,6 @@ const harsh = document.querySelector('.harsh'); const harsh111 = document.querySelector('.harsh111'); const counterPrice = document.querySelectorAll('.counter'); const dialog = document.querySelectorAll('dialog'); -const input = document.querySelector('.iin'); -const profile = document.querySelector('.pro'); const search = document.querySelector('.search'); const changer = document.querySelector('.changer'); const myOrder = document.querySelector('.ord'); @@ -31,86 +30,80 @@ const myAds = document.querySelector('.mads'); harsh.addEventListener('click', (event) => { - event.preventDefault(); - leftBar.style.display = 'inline-grid'; - leftBar.style.left = '0px'; - harsh111.style.opacity = '0' - }); + event.preventDefault(); + leftBar.style.display = 'inline-grid'; + leftBar.style.left = '0px'; + harsh111.style.opacity = '0'; +}); - harsh111.addEventListener('click', (event) => { - event.preventDefault(); - rightBar.style.display = 'inline-grid'; - rightBar.style.right = '0px'; - mainBar.style.opacity='0.6'; - harsh.style.opacity = '0'; - }); +harsh111.addEventListener('click', (event) => { + event.preventDefault(); + rightBar.style.display = 'inline-grid'; + rightBar.style.right = '0px'; + mainBar.style.opacity = '0.6'; + harsh.style.opacity = '0'; +}); - search.addEventListener('click', (event) => { - event.preventDefault(); - rightBar.style.right = '-500px'; - harsh.style.opacity = '1'; - mainBar.style.opacity='1' - }); +search.addEventListener('click', (event) => { + event.preventDefault(); + rightBar.style.right = '-500px'; + harsh.style.opacity = '1'; + mainBar.style.opacity = '1'; +}); - if(rightBar.style.right === '-500px'){ - rightBar.style.opacity= '0' - } +if (rightBar.style.right === '-500px') { + rightBar.style.opacity = '0'; +} -input.addEventListener('input',(e)=>{ - profile.attributes.src.value = URL.createObjectURL(input.files[0]) -}) -a.forEach(car =>{ - car.addEventListener('click', (e) =>{ - let details = (e.path[0]); - imgg.attributes.src.value = `${details.attributes.src.value}`; - }) -}) +// input.addEventListener('input', () => { +// profile.attributes.src.value = URL.createObjectURL(input.files[0]); +// }); -updatePrice.forEach(up =>{ - up.addEventListener('click', (e) =>{ - updateDialog.showModal(); - }) -}) +updatePrice.forEach((up) => { + up.addEventListener('click', () => { + updateDialog.showModal(); + }); +}); -small.forEach(mall =>{ - mall.addEventListener('click', (e) =>{ - leftBar.style.left = '-500px'; - harsh111.style.opacity = '1' - }) -}) -acceptPrice.forEach(accept =>{ - accept.addEventListener('click', (e) =>{ - acceptDialog.showModal(); - }) -}) -rejectPrice.forEach(reject =>{ - reject.addEventListener('click', (e) =>{ - rejectDialog.showModal(); - }) -}) -counterPrice.forEach(counter =>{ - counter.addEventListener('click', (e) =>{ - counterDialog.showModal(); - }) -}) +small.forEach((mall) => { + mall.addEventListener('click', () => { + leftBar.style.left = '-500px'; + harsh111.style.opacity = '1'; + }); +}); +acceptPrice.forEach((accept) => { + accept.addEventListener('click', () => { + acceptDialog.showModal(); + }); +}); +rejectPrice.forEach((reject) => { + reject.addEventListener('click', () => { + rejectDialog.showModal(); + }); +}); +counterPrice.forEach((counter) => { + counter.addEventListener('click', () => { + counterDialog.showModal(); + }); +}); -purchase.addEventListener('click', (e) =>{ - purchaseDialog.showModal(); - dialog[1].className = 'grow'; +purchase.addEventListener('click', () => { + purchaseDialog.showModal(); + dialog[1].className = 'grow'; }); -report.addEventListener('click', (e) =>{ - reportDialog.showModal(); - dialog[0].className = 'grow'; -}) +report.addEventListener('click', () => { + reportDialog.showModal(); + dialog[0].className = 'grow'; +}); -close.forEach(clo =>{ -clo.addEventListener('click',(e)=>{ - dialog.forEach(dia =>{ - setTimeout( function(){dia.close();}, 300); - dialog[0].classList.remove('grow'); - }) -}) -}) \ No newline at end of file +close.forEach((clo) => { + clo.addEventListener('click', () => { + dialog.forEach((dia) => { + setTimeout(() => { dia.close(); }, 300); + dialog[0].classList.remove('grow'); + }); + }); +}); diff --git a/UI/js/onLoad.js b/UI/js/onLoad.js new file mode 100644 index 0000000..387d2f9 --- /dev/null +++ b/UI/js/onLoad.js @@ -0,0 +1,165 @@ +/* eslint-disable no-use-before-define */ +/* eslint-disable no-undef */ + +const name = document.querySelector('.name'); +const email = document.querySelector('.email'); +const photo = document.querySelector('.photo'); +const notify = document.querySelector('.notify'); +const roll = document.querySelector('.roll'); +const purchaseError = document.querySelector('.purchase-error'); +const manu = document.querySelector('.manu'); +const mod = document.querySelector('.mod'); +const boo = document.querySelector('.boo'); +const cost = document.querySelector('.cost'); +const sta = document.querySelector('.sta'); +const stat = document.querySelector('.stat'); +const dialogStatus = document.querySelector('.dia-status'); +const dialogPrice = document.querySelector('.dia-price'); +const purchaseOrder = document.querySelector('.purchase-order'); + + +let idPath; +window.addEventListener('load', async (event) => { + event.preventDefault(); + try { + carLoader(); + getUserProfile(); + // a.forEach((car) => { + // // console.log(car); + // car.addEventListener('click', () => { + // // const details = (e.path[0]); + // // console.log('i am here'); + // }); + // }); + } catch (error) { + notify.append = `${error}`; + } +}); + +showBox.addEventListener('click', async (e) => { + let initialPath = e.path[0]; + idPath = e.path[1].id; + let namePath = e.path[1]; + + if (initialPath.tagName !== 'IMG') { + initialPath = e.path[0].parentElement.firstElementChild; + namePath = e.path[1].lastChild.previousSibling.lastElementChild; + if (initialPath.tagName !== 'IMG') { initialPath = initialPath.firstElementChild; } + namePath = e.path[1].lastChild.previousSibling.lastElementChild; + } + + imgg.attributes.src.value = `${initialPath.attributes.src.value}`; + + if (idPath === '') idPath = e.path[0].id; + + const url = `${devURL}car/${idPath}`; + const { responseObj, statusCode } = await fetcher(url, 'GET'); + + if (statusCode === 200) { + manu.textContent = `Manufacturer: ${responseObj.data.manufacturer}`; + mod.textContent = `Model: ${responseObj.data.model}`; + boo.textContent = `Body Type: ${responseObj.data.body_type}`; + cost.textContent = `Price: N${responseObj.data.price}`; + stat.textContent = `State: ${responseObj.data.state}`; + sta.textContent = `status: ${responseObj.data.status}`; + sta.textContent = `status: ${responseObj.data.status}`; + dialogPrice.textContent = `Price: N${responseObj.data.price}`; + dialogStatus.textContent = `Status: ${responseObj.data.status}`; + } +}); + +const amountPurchase = document.querySelector('.price-offered'); +const priceOff = () => { + const amount = amountPurchase.value; + const price = { amount, car_id: idPath }; + return price; +}; + +roll.style.display = 'none'; + +purchaseOrder.addEventListener('click', async () => { + purchaseError.style.color = 'red'; + purchaseOrder.style.color = 'slateblue'; + roll.style.display = 'initial'; + const details = priceOff(); + + if (details.amount === '') { + purchaseError.textContent = 'Amount is required'; + roll.style.display = 'none'; + purchaseOrder.style.color = 'white'; + return; + } + + const url = `${devURL}order`; + const { responseObj, statusCode } = await fetcher(url, 'POST', details); + + if (statusCode === 201) { + purchaseError.style.color = 'green'; + purchaseError.textContent = 'Order Successfully Created'; + await setTimeout(() => { + purchaseDialog.close(); + roll.style.display = 'none'; + purchaseOrder.style.color = 'white'; + purchaseError.textContent = ''; + amountPurchase.value = ''; + }, 4000); + } + + if (statusCode === 400) { + purchaseError.textContent = `${responseObj.error}`; + roll.style.display = 'none'; + purchaseOrder.style.color = 'white'; + } +}); + +const carLoader = async () => { + try { + const url = `${devURL}car`; + const { responseObj, statusCode } = await fetcher(url, 'GET'); + + if (statusCode === 200) { + const { data } = responseObj; + data.forEach(async (cars) => { + const { + id, manufacturer, model, price, car_image, status, + } = cars; + const carObj = { + id, manufacturer, model, price, car_image, status, + }; + showBox.innerHTML += displayCars(carObj); + }); + + notify.style.display = 'none'; + spinne.style.display = 'none'; + Bar.style.display = 'block'; + showBox.style.display = 'flex'; + } else if (statusCode === 404) { + showBox.innerHTML = ''; + showBox.innerHTML = responseObj.error; + } else if (statusCode === 401) { + window.location = 'index.html'; + } + } catch (err) { + spinne.style.display = 'none'; + notify.textContent = 'Network Error, Please Reload'; + } +}; + +const details = { + email: localStorage.userDet, +}; + +const getUserProfile = async () => { + try { + const url = `${devURL}user`; + const { responseObj, statusCode } = await fetcher(url, 'POST', details); + + if (statusCode === 400) window.location = 'index.html'; + + photo.attributes.src.value = `${responseObj.data.profile_pic}`; + name.textContent = `${responseObj.data.first_name} ${responseObj.data.last_name}`; + email.textContent = `${responseObj.data.email}`; + } catch (err) { + notify.appendChild = `${err}`; + } +}; diff --git a/UI/js/user.js b/UI/js/user.js index 02dcd3e..383b554 100644 --- a/UI/js/user.js +++ b/UI/js/user.js @@ -12,9 +12,9 @@ const getSignUpDetails = () => { const lastName = document.querySelectorAll('.userName')[1].value; const email = document.querySelectorAll('.userName')[2].value; const password = document.querySelector('#password').value; - const phoneNumber = document.querySelector('#number').value; + const address = document.querySelector('#address').value; const obj = { - firstName, lastName, email, password, phoneNumber, + first_name: firstName, last_name: lastName, email, password, address, }; return obj; }; @@ -29,14 +29,20 @@ form.addEventListener('submit', async (event) => { spinner.style.display = 'initial'; const url = `${devURL}auth/signup`; deet.style.transform = 'scale(0)'; + const { responseObj, statusCode } = await fetcher(url, 'POST', details); + if (statusCode === 201) { deh.style.color = 'green'; deh.textContent = 'Registered Successful'; de.textContent = 'Welcome'; deet.style.transform = 'scale(1)'; + const { token } = responseObj.data; - localStorage.setItem('authtoken', token); + localStorage = ''; + localStorage.setItem('token', token); + localStorage.setItem('userDet', document.querySelectorAll('.userName')[2].value); + setTimeout(() => { window.location = 'main.html'; }, 3000); } else { deh.textContent = 'Error'; diff --git a/UI/main.html b/UI/main.html index bdb755e..2d4b068 100644 --- a/UI/main.html +++ b/UI/main.html @@ -11,18 +11,16 @@ - @@ -327,49 +128,22 @@

2018 Toyota Supra

Post Ad

+
- - + +
- - - - - - - -
+ + + + +
+ + +
@@ -386,7 +160,7 @@

2018 Toyota Supra

2018 Toyota Supra


@@ -714,6 +375,9 @@

Status: Approved

+ + + \ No newline at end of file From 991f424c1c1b2d84d122782e844798ed83f1d70d Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Wed, 24 Jul 2019 16:49:30 +0100 Subject: [PATCH 13/16] Bug(Feedback) Implement LFA Feedback >- rename isUser method to isRegularUser [Fixes #167491156] --- server/middleware/authentication.js | 2 +- server/router/carRoute.js | 12 ++++++------ server/router/orderRoute.js | 4 ++-- server/router/uploadRoute.js | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/server/middleware/authentication.js b/server/middleware/authentication.js index 3c1e70a..5e5631d 100644 --- a/server/middleware/authentication.js +++ b/server/middleware/authentication.js @@ -32,7 +32,7 @@ class authenticator { } } - static isUser(req, res, next) { + static isRegularUser(req, res, next) { const { isAdmin } = req.user; if (isAdmin) { return Utilities.errorstatus(res, 403, 'Forbidden, You Are not allowed to perform this action'); diff --git a/server/router/carRoute.js b/server/router/carRoute.js index 5a782e8..00d8ffe 100644 --- a/server/router/carRoute.js +++ b/server/router/carRoute.js @@ -4,13 +4,13 @@ import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; const carRouter = express(); -carRouter.post('/car/', authenticator.authenticateUser, authenticator.isUser, validator.validateCar, carController.postAds); -carRouter.patch('/car/:carId/status', authenticator.authenticateUser, authenticator.isUser, validator.validateSold, carController.markSold); -carRouter.patch('/car/:carId/price', authenticator.authenticateUser, authenticator.isUser, validator.validateUpdateCar, carController.updateCar); -carRouter.get('/car/:carId/', authenticator.authenticateUser, authenticator.isUser, carController.specificCar); +carRouter.post('/car/', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateCar, carController.postAds); +carRouter.patch('/car/:carId/status', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateSold, carController.markSold); +carRouter.patch('/car/:carId/price', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateUpdateCar, carController.updateCar); +carRouter.get('/car/:carId/', authenticator.authenticateUser, authenticator.isRegularUser, carController.specificCar); carRouter.get('/car', authenticator.authenticateUser, validator.validateGetCar, carController.car); -carRouter.post('/flag/:carId', authenticator.authenticateUser, authenticator.isUser, validator.validateFlag, carController.flagCar); -carRouter.patch('/cars/:car_id', authenticator.authenticateUser, authenticator.isUser, carController.updateCarImage); +carRouter.post('/flag/:carId', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateFlag, carController.flagCar); +carRouter.patch('/cars/:car_id', authenticator.authenticateUser, authenticator.isRegularUser, carController.updateCarImage); export default carRouter; diff --git a/server/router/orderRoute.js b/server/router/orderRoute.js index 2509ac6..0b8bcc4 100644 --- a/server/router/orderRoute.js +++ b/server/router/orderRoute.js @@ -4,7 +4,7 @@ import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; const orderRouter = express(); -orderRouter.post('/order', authenticator.authenticateUser, authenticator.isUser, validator.validateOrder, orderController.purchaseOrder); -orderRouter.patch('/order/:orderId/price', authenticator.authenticateUser, authenticator.isUser, validator.validateUpdateOrder, orderController.updatePurchase); +orderRouter.post('/order', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateOrder, orderController.purchaseOrder); +orderRouter.patch('/order/:orderId/price', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateUpdateOrder, orderController.updatePurchase); export default orderRouter; diff --git a/server/router/uploadRoute.js b/server/router/uploadRoute.js index 6bb6819..a4997e7 100644 --- a/server/router/uploadRoute.js +++ b/server/router/uploadRoute.js @@ -4,6 +4,6 @@ import validator from '../middleware/validator'; import authenticator from '../middleware/authentication'; const uploadRouter = express(); -uploadRouter.post('/upload', authenticator.authenticateUser, authenticator.isUser, validator.validateImage, uploadController.upload); +uploadRouter.post('/upload', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateImage, uploadController.upload); export default uploadRouter; From 8b987481f76568e71e4da57edce3f9bbc3f56624 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Tue, 8 Oct 2019 17:29:24 +0100 Subject: [PATCH 14/16] update get all car endpoint --- server/router/carRoute.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/router/carRoute.js b/server/router/carRoute.js index 00d8ffe..d33d62e 100644 --- a/server/router/carRoute.js +++ b/server/router/carRoute.js @@ -8,7 +8,7 @@ carRouter.post('/car/', authenticator.authenticateUser, authenticator.isRegularU carRouter.patch('/car/:carId/status', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateSold, carController.markSold); carRouter.patch('/car/:carId/price', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateUpdateCar, carController.updateCar); carRouter.get('/car/:carId/', authenticator.authenticateUser, authenticator.isRegularUser, carController.specificCar); -carRouter.get('/car', authenticator.authenticateUser, validator.validateGetCar, carController.car); +carRouter.get('/car', validator.validateGetCar, carController.car); carRouter.post('/flag/:carId', authenticator.authenticateUser, authenticator.isRegularUser, validator.validateFlag, carController.flagCar); carRouter.patch('/cars/:car_id', authenticator.authenticateUser, authenticator.isRegularUser, carController.updateCarImage); From 09b7d73843f367268a20f3ce65950c8f1d328bcf Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Tue, 8 Oct 2019 17:43:18 +0100 Subject: [PATCH 15/16] Update carController.js --- server/controllers/carController.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/controllers/carController.js b/server/controllers/carController.js index 8f9a0ea..8270eb4 100644 --- a/server/controllers/carController.js +++ b/server/controllers/carController.js @@ -82,7 +82,7 @@ class carController { } static async car(req, res) { - const { isAdmin } = req.user; +// const { isAdmin } = req.user; const { status } = req.query; const bodyType = req.query.body_type; @@ -92,7 +92,7 @@ class carController { return utilities.successStatus(res, 200, 'data', cars.rows); } - if (!isAdmin) { +// if (!isAdmin) { if (status) { if (req.query.min_price && req.query.max_price) { const unsoldCars = await dbMethods.readFromDb('cars', '*', { status: status.toLowerCase() }); @@ -116,7 +116,7 @@ class carController { if (!carType[0]) return utilities.errorstatus(res, 404, 'No Car With This Body Type Found'); return utilities.successStatus(res, 200, 'data', carType); } - } return utilities.errorstatus(res, 403, 'Forbidden, You Are not allowed to perform this action'); +// } return utilities.errorstatus(res, 403, 'Forbidden, You Are not allowed to perform this action'); } static async flagCar(req, res) { From 81c3058b5b67e84663d1986f2b6e89038ec2dd04 Mon Sep 17 00:00:00 2001 From: amoskeyz Date: Thu, 27 Feb 2020 12:36:48 +0100 Subject: [PATCH 16/16] Update style.css --- UI/css/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/css/style.css b/UI/css/style.css index e9366de..e52ca4c 100644 --- a/UI/css/style.css +++ b/UI/css/style.css @@ -111,7 +111,7 @@ nav{ rgba(0,0,0,0.8), rgba(96,73,203,0.8) ), - url(http://res.cloudinary.com/amoslv/image/upload/v1563476573/eleouih7selykavbixk6.jpg) no-repeat; + url(http://res.cloudinary.com/amoslv/image/upload/v1582802896/f2srootnaczaeav2agsv.jpg) no-repeat; background-size: cover; display: flex; align-items: center; @@ -980,4 +980,4 @@ footer{ font-size: 16px } -} \ No newline at end of file +}