From f24be835e9442a1c5a40912a089874bcbe370512 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Mon, 13 Nov 2023 17:07:56 +0100 Subject: [PATCH 01/13] =?UTF-8?q?Qu=C3=AAte=20Express=2001.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.sample | 6 +- .gitignore | 1 + database.js | 41 ++++++ package-lock.json | 193 +++++++++++++++++++++++++++- package.json | 4 +- src/app.js | 5 + src/controllers/movieControllers.js | 62 ++++++++- tests/movies.test.js | 3 + tests/users.test.js | 3 + 9 files changed, 308 insertions(+), 10 deletions(-) create mode 100644 database.js diff --git a/.env.sample b/.env.sample index d5349ec8..cf37ffe8 100644 --- a/.env.sample +++ b/.env.sample @@ -1 +1,5 @@ -APP_PORT=5000 +DB_HOST=localhost +DB_PORT=5000 +DB_USER=REPLACE_WITH_YOUR_USENAME +DB_PASSWORD=REPLACE_WIH_YOUR_PASSWORD +DB_NAME=REPLACE_BY_DB_NAME \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3c3629e6..28a76bc8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +env \ No newline at end of file diff --git a/database.js b/database.js new file mode 100644 index 00000000..af1b1b14 --- /dev/null +++ b/database.js @@ -0,0 +1,41 @@ +require("dotenv").config(); + +const mysql = require("mysql2/promise"); + +const database = mysql.createPool({ + hots: process.env.DB_HOST, + port: process.env.DB_PORT, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, +}); + +database + .getConnection() + .then(() => { + console.log("Can reach database"); + }) + .catch((err) => { + console.error(err); + }); + +database + .query("select * from movies") + .then(([movies]) => { + console.log(movies); + }) + .catch((err) => { + console.error(err); + }); + +database + .query("select * from users") + .then(([users]) => { + console.log(users); + }) + + .catch((err) => { + console.error(err); + }); + +module.exports = database; diff --git a/package-lock.json b/package-lock.json index d6aeb725..a52f2c29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,9 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "express": "^4.18.2" + "dotenv": "^16.3.1", + "express": "^4.18.2", + "mysql2": "^3.6.3" }, "devDependencies": { "jest": "^29.7.0", @@ -1809,6 +1811,14 @@ "node": ">=0.4.0" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1854,6 +1864,17 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2169,6 +2190,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2493,6 +2522,11 @@ "node": ">=0.12.0" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -3306,6 +3340,11 @@ "node": ">=8" } }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3468,6 +3507,62 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/mysql2": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.3.tgz", + "integrity": "sha512-qYd/1CDuW1KYZjD4tzg2O8YS3X/UWuGH8ZMHyMeggMTXL3yOdMisbwZ5SNkHzDGlZXKYLAvV8tMrEH+NUMz3fw==", + "dependencies": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4044,6 +4139,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -4164,6 +4264,14 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -6048,6 +6156,11 @@ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -6080,6 +6193,11 @@ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true }, + "dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -6324,6 +6442,14 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -6552,6 +6678,11 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -7171,6 +7302,11 @@ "p-locate": "^4.1.0" } }, + "long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -7293,6 +7429,51 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "mysql2": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.3.tgz", + "integrity": "sha512-qYd/1CDuW1KYZjD4tzg2O8YS3X/UWuGH8ZMHyMeggMTXL3yOdMisbwZ5SNkHzDGlZXKYLAvV8tMrEH+NUMz3fw==", + "requires": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==" + } + } + }, + "named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "requires": { + "lru-cache": "^7.14.1" + }, + "dependencies": { + "lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==" + } + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7705,6 +7886,11 @@ } } }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -7803,6 +7989,11 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" + }, "stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", diff --git a/package.json b/package.json index 64b8ae6d..164181a8 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ }, "homepage": "https://github.com/WildCodeSchool/Express-Quests#readme", "dependencies": { - "express": "^4.18.2" + "dotenv": "^16.3.1", + "express": "^4.18.2", + "mysql2": "^3.6.3" }, "devDependencies": { "jest": "^29.7.0", diff --git a/src/app.js b/src/app.js index 19f5d86d..fca2ecbc 100644 --- a/src/app.js +++ b/src/app.js @@ -1,3 +1,6 @@ +require("dotenv").config(); + +const port = process.env.APP_PORT const express = require("express"); const app = express(); @@ -6,5 +9,7 @@ const movieControllers = require("./controllers/movieControllers"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); +app.get("/api/users", movieControllers.getUsers); +app.get("/api/users/:id", movieControllers.getUsersById); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index e3bb0053..f29b8f0c 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -25,23 +25,71 @@ const movies = [ }, ]; +const database = require("../../database"); + const getMovies = (req, res) => { - res.json(movies); + database + .query("select * from movies") + .then(([movies]) => { + res.json(movies); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); }; const getMovieById = (req, res) => { const id = parseInt(req.params.id); - const movie = movies.find((movie) => movie.id === id); + database + .query("select * from movies where id = ?", [id]) + .then((movies) => { + if (movies[0] != null) { + res.json(movies[0]); + } else { + res.sendStatus(404); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + +const getUsers = (req, res) => { + database + .query("select * from users") + .then(([users]) => { + res.status(200).json(users); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + +const getUsersById = (req, res) => { + const id = parseInt(req.params.id); - if (movie != null) { - res.json(movie); - } else { - res.status(404).send("Not Found"); - } + database + .query("select * from users where id = ?", [id]) + .then((users) => { + if (users[0] != null) { + res.status(200).json(users[0]); + } else { + res.sendStatus(404); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); }; module.exports = { getMovies, getMovieById, + getUsers, + getUsersById, }; diff --git a/tests/movies.test.js b/tests/movies.test.js index 09621f56..48799393 100644 --- a/tests/movies.test.js +++ b/tests/movies.test.js @@ -1,6 +1,7 @@ const request = require("supertest"); const app = require("../src/app"); +const database = require("../database"); describe("GET /api/movies", () => { it("should return all movies", async () => { @@ -27,3 +28,5 @@ describe("GET /api/movies/:id", () => { expect(response.status).toEqual(404); }); }); + +afterAll(() => database.end()); diff --git a/tests/users.test.js b/tests/users.test.js index f69d5e9e..a72c2ad0 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -1,6 +1,7 @@ const request = require("supertest"); const app = require("../src/app"); +const database = require ("../database") describe("GET /api/users", () => { it("should return all users", async () => { @@ -27,3 +28,5 @@ describe("GET /api/users/:id", () => { expect(response.status).toEqual(404); }); }); + +afterAll(() => database.end()); From a3b5070e1c360edb7977f2f9e19658bfe2794a11 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Tue, 21 Nov 2023 11:59:52 +0100 Subject: [PATCH 02/13] =?UTF-8?q?Qu=C3=AAte=20Express=2001.2bis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/movieControllers.js | 36 +++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index f29b8f0c..da115daa 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -28,14 +28,30 @@ const movies = [ const database = require("../../database"); const getMovies = (req, res) => { + let sql = "select * from movies"; + const sqlValues = []; + + if (req.query.color != null) { + sql += "where color = ?"; + sqlValues.push(req.query.color); + + if (req.query.max_duration != null) { + sql += "and duration <= ?"; + sqlValues.push(req.query.max_duration); + } + } else if (req.query.max_duration != null) { + sql += "where duration <= ?"; + sqlValues.push(req.query.max_duration); + } + database - .query("select * from movies") + .query(sql, sqlValues) .then(([movies]) => { res.json(movies); }) .catch((err) => { console.error(err); - res.sendStatus(500); + res.status(500).send("Error retrieving data from database"); }); }; @@ -58,6 +74,22 @@ const getMovieById = (req, res) => { }; const getUsers = (req, res) => { + let sql = "select * from users"; + const sqlValues = []; + + if (req.query.langage != null) { + sql += "where langage = ?"; + sqlValues.push(req.query.langage); + + if (req.query.city != null) { + sql += "and city = ?"; + sqlValues.push(req.query.city); + } + } else if (req.query.city != null) { + sql += "where city = ?"; + sqlValues.push(req.query.city); + } + database .query("select * from users") .then(([users]) => { From dd8c5db7cf2008a59bf2c38d060d619978fe70be Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 29 Nov 2023 18:00:33 +0100 Subject: [PATCH 03/13] =?UTF-8?q?Qu=C3=AAte=20Express=2002?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 5 ++++ express_quests.sql | 1 + src/app.js | 4 +++ src/controllers/movieControllers.js | 38 ++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 00000000..e79f513c --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +DB_HOST=localhost +DB_PORT=3306 +DB_USER=root +DB_PASSWORD=39942521Bw! +DB_NAME=express_quests \ No newline at end of file diff --git a/express_quests.sql b/express_quests.sql index 1a634e37..4f2e4333 100644 --- a/express_quests.sql +++ b/express_quests.sql @@ -1,3 +1,4 @@ +-- Active: 1698236999326@@127.0.0.1@3306@express_quests DROP TABLE IF EXISTS movies; CREATE TABLE movies ( diff --git a/src/app.js b/src/app.js index fca2ecbc..87ef04f6 100644 --- a/src/app.js +++ b/src/app.js @@ -5,11 +5,15 @@ const express = require("express"); const app = express(); +app.use(express.json()); + const movieControllers = require("./controllers/movieControllers"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); +app.post("/api/movies", movieControllers.postMovie); +app.post("/api/users", movieControllers.postUsers); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index da115daa..ca695965 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -89,7 +89,7 @@ const getUsers = (req, res) => { sql += "where city = ?"; sqlValues.push(req.query.city); } - + database .query("select * from users") .then(([users]) => { @@ -119,9 +119,45 @@ const getUsersById = (req, res) => { }); }; +const postMovie = (req, res) => { + const { title, director, year, color, duration } = req.body; + + database + .query( + "INSERT INTO movies(title, director, year, color, duration) VALUES (?, ?, ?, ?, ?)", + [title, director, year, color, duration] + ) + .then(([result]) => { + res.status(201).send({ id: result.insertId }); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + +const postUsers = (req, res) => { + const { firstname, lastname, email, city, language } = req.body; + + database + .query( + "INSERT INTO users(firstname, lastname, email, city, language) VALUES (?, ?, ?, ?, ?)", + [firstname, lastname, email, city, language] + ) + .then(([result]) => { + res.status(201).send({ id: result.insertId }); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + module.exports = { getMovies, getMovieById, getUsers, getUsersById, + postMovie, + postUsers, }; From bd273b0452925c2615df4458f2161695b3e401a0 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Thu, 30 Nov 2023 11:39:58 +0100 Subject: [PATCH 04/13] =?UTF-8?q?Qu=C3=AAte=20Express=2002.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controllers/movieControllers.js | 6 ++-- tests/movies.test.js | 41 +++++++++++++++++++++++++++ tests/users.test.js | 44 ++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index ca695965..48a129cb 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -77,9 +77,9 @@ const getUsers = (req, res) => { let sql = "select * from users"; const sqlValues = []; - if (req.query.langage != null) { - sql += "where langage = ?"; - sqlValues.push(req.query.langage); + if (req.query.language != null) { + sql += "where language = ?"; + sqlValues.push(req.query.language); if (req.query.city != null) { sql += "and city = ?"; diff --git a/tests/movies.test.js b/tests/movies.test.js index 48799393..30423906 100644 --- a/tests/movies.test.js +++ b/tests/movies.test.js @@ -29,4 +29,45 @@ describe("GET /api/movies/:id", () => { }); }); +describe("POST /api/movies", () => { + it("should return created movie", async () => { + const newMovie = { + title: "Star Wars", + director: "George Lucas", + year: "1977", + color: "1", + duration: 120, + }; + + const response = await request(app).post("/api/movies").send(newMovie); + + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toEqual(201); + expect(response.body).toHaveProperty("id"); + expect(typeof response.body.id).toBe("number"); + + const [result] = await database.query( + "SELECT * FROM movies WHERE id=?", + response.body.id + ); + + const [movieInDatabase] = result; + + expect(movieInDatabase).toHaveProperty("id"); + + expect(movieInDatabase).toHaveProperty("title"); + expect(movieInDatabase).toStrictEqual(newMovie.title); + }); + + it("should return an error", async () => { + const movieWithMissingProps = {title: "Harry Potter"}; + + const response = await request(app) + .post("/api/movies") + .send(movieWithMissingProps); + + expect(response.status).toEqual(500); + }); +}); + afterAll(() => database.end()); diff --git a/tests/users.test.js b/tests/users.test.js index a72c2ad0..44c20813 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -1,7 +1,8 @@ const request = require("supertest"); const app = require("../src/app"); -const database = require ("../database") +const database = require("../database"); +const crypto = require("node:crypto"); describe("GET /api/users", () => { it("should return all users", async () => { @@ -29,4 +30,45 @@ describe("GET /api/users/:id", () => { }); }); +describe("POST /api/users", () => { + it("should return created user", async () => { + const newUser = { + firstname: "Marie", + lastname: "Martin", + email: `${crypto.randomUUID()}@wild.co`, + city: "Paris", + language: "French", + }; + + const response = await request(app).post("/api/users").send(newUser); + + expect(response.headers["content-type"]).toMatch(/json/); + expect(response.status).toEqual(201); + expect(response.body).toHaveProperty("id"); + expect(typeof response.body.id).toBe("number"); + + const [result] = await database.query( + "SELECT * FROM users WHERE id=?", + response.body.id + ); + + const [userInDatabase] = result; + + expect(userInDatabase).toHaveProperty("id"); + + expect(userInDatabase).toHaveProperty("firstname"); + expect(userInDatabase).toStrictEqual(newUser.firstname); + }); + + it("should return an error", async () => { + const userWithMissingProps = { firstname: "Claude" }; + + const response = await request(app) + .post("api/users") + .send(userWithMissingProps); + + expect(response.status).toEqual(500); + }); +}); + afterAll(() => database.end()); From 70cc7acc3a5bdfaa106aebc2c2aaf9da3b6636b8 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 6 Dec 2023 09:26:23 +0100 Subject: [PATCH 05/13] Enregistrement provisoire pour modification --- src/app.js | 1 + src/controllers/movieControllers.js | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/app.js b/src/app.js index 87ef04f6..09091310 100644 --- a/src/app.js +++ b/src/app.js @@ -15,5 +15,6 @@ app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); app.post("/api/movies", movieControllers.postMovie); app.post("/api/users", movieControllers.postUsers); +app.put("/api/movies/:id", movieControllers.updateMovie); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index 48a129cb..741fcec3 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -153,6 +153,27 @@ const postUsers = (req, res) => { }); }; +const updateMovie = (req, res) => { + const { title, director, year, color, duration } = req.body; + + database + .query( + "UPDATE movies SET title = ?, director = ?, year = ?, color = ?, duration = ? where id = ?", + [title, director, year, color, duration, id] + ) + .then(([result]) => { + if (result.affectedRows === 0) { + res.sendStatus(404); + } else { + res.sendStatus(204); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + module.exports = { getMovies, getMovieById, @@ -160,4 +181,5 @@ module.exports = { getUsersById, postMovie, postUsers, + updateMovie, }; From f653ed9ea092e8ae775d6258943ff15e1e588ae8 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 12:39:24 +0200 Subject: [PATCH 06/13] =?UTF-8?q?Qu=C3=AAte=20Express=2003=20(PUT/UPDATE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.js | 1 + src/controllers/movieControllers.js | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/app.js b/src/app.js index 09091310..a15ffa85 100644 --- a/src/app.js +++ b/src/app.js @@ -16,5 +16,6 @@ app.get("/api/users/:id", movieControllers.getUsersById); app.post("/api/movies", movieControllers.postMovie); app.post("/api/users", movieControllers.postUsers); app.put("/api/movies/:id", movieControllers.updateMovie); +app.put("/api/users/:id", movieControllers.updateUsers); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index 741fcec3..b1a73628 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -154,6 +154,7 @@ const postUsers = (req, res) => { }; const updateMovie = (req, res) => { + const id = parseInt(req.params.id); const { title, director, year, color, duration } = req.body; database @@ -174,6 +175,28 @@ const updateMovie = (req, res) => { }); }; +const updateUsers = (req, res) => { + const id = parseInt(req.params.id); + const { firstname, lastname, email, city, language } = req.body; + + database + .query( + "UPDATE users SET firstname = ?, lastname = ?, email = ?, city = ?, language = ? where id = ?", + [firstname, lastname, email, city, language, id] + ) + .then(([result]) => { + if (result.affectedRows === 0) { + res.sendStatus(404); + } else { + res.sendStatus(204); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + module.exports = { getMovies, getMovieById, @@ -182,4 +205,5 @@ module.exports = { postMovie, postUsers, updateMovie, + updateUsers, }; From 295a51af6577856750736a615863aaa8764b4d3e Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 13:21:14 +0200 Subject: [PATCH 07/13] =?UTF-8?q?Qu=C3=AAte=20Express=2003.1=20:=20Tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/movies.test.js | 78 ++++++++++++++++++++++++++++++++++++++++++ tests/users.test.js | 80 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/tests/movies.test.js b/tests/movies.test.js index 30423906..09774ded 100644 --- a/tests/movies.test.js +++ b/tests/movies.test.js @@ -70,4 +70,82 @@ describe("POST /api/movies", () => { }); }); +describe("PUT /api/movies/id", () => { + it("should edit movie", async () => { + const newMovie = { + title: "Avatar", + director: "James Cameron", + year: "2009", + color: "1", + duration: 162, + }; + + const [result] = await database.query( + "INSERT INTO movies(title, director, year, color, duration) VALUES (?, ?, ?, ?, ?)", + [newMovie.title, newMovie.director, newMovie.year, newMovie.color, newMovie.duration] + ); + + const id = result.insertId; + + const updatedMovie = { + title: "Wild is life", + director: "Alan Smithee", + year: "2023", + color: "0", + duration: 120, + }; + + const response = await request(app) + .put(`/api/movies/${id}`) + .send(updatedMovie); + + expect(response.status).toEqual(204); + + const [movies] = await database.query("SELECT * FROM movies WHERE id= ?", id); + + const [movieInDatabase] = movies; + + except(movieInDatabase).toHaveProperty("id"); + + except(movieInDatabase).toHaveProperty("title"); + expect(movieInDatabase).toStrictEqual(updatedMovie.title); + + except(movieInDatabase).toHaveProperty("director"); + expect(movieInDatabase).toStrictEqual(updatedMovie.director); + + except(movieInDatabase).toHaveProperty("year"); + expect(movieInDatabase).toStrictEqual(updatedMovie.year); + + except(movieInDatabase).toHaveProperty("color"); + expect(movieInDatabase).toStrictEqual(updatedMovie.color); + + except(movieInDatabase).toHaveProperty("duration"); + expect(movieInDatabase).toStrictEqual(updatedMovie.duration); + }); + + it("should return an error", async () => { + const movieWithMissingProps = {title: "Harry Potter"}; + + const response = await request(app) + .put(`/api/movies/1`) + .send(movieWithMissingProps); + + expect(response.status).toEqual(500); + }); + + it("should return no movie", async () => { + const newMovie = { + title: "Avatar", + director: "James Cameron", + year: "2009", + color: "1", + duration: 162, + }; + + const response = (await request(app).put("/api/movies/0")).send(newMovie); + + expect(response.status).toEqual(404); + }); +}); + afterAll(() => database.end()); diff --git a/tests/users.test.js b/tests/users.test.js index 44c20813..c9077591 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -71,4 +71,84 @@ describe("POST /api/users", () => { }); }); +describe("PUT /api/users/id", () => { + it("should edit user", async () => { + const newUser = { + firstname: "Alan", + lastname: "Wake", + email: "alan.wake@wildcodeschool.com", + city: "New York", + language: "English" + }; + + const [result] = await database.query( + "INSERT INTO users (firstname, lastname, email, city, language) VALUES (?, ?, ?, ?, ?)", + [newUser.firstname, newUser.lastname, newUser.email, newUser.city, newUser.language] + ); + + const id = result.insertId; + + const updatedUser = { + firstname: "Thomas", + lastname: "Zane", + email: "thomas.zane@yotonyo.com", + city: "Helsinki", + language: "Finnish", + }; + + const response = await request(app) + .put(`/api/users/${id}`) + .send(updatedUser); + + expect(response.status).toEqual(204); + + const [users] = await database.query("SELECT * FROM users WHERE id= ?", id); + + const [userInDatabase] = users; + + except(userInDatabase).toHaveProperty("id"); + + except(userInDatabase).toHaveProperty("firstname"); + expect(userInDatabase).toStrictEqual(updatedUser.firstname); + + except(userInDatabase).toHaveProperty("lastname"); + expect(userInDatabase).toStrictEqual(updatedUser.lastname); + + except(userInDatabase).toHaveProperty("email"); + expect(userInDatabase).toStrictEqual(updatedUser.email); + + except(userInDatabase).toHaveProperty("city"); + expect(userInDatabase).toStrictEqual(updatedUser.city); + + except(userInDatabase).toHaveProperty("language"); + expect(userInDatabase).toStrictEqual(updatedUser.language); + }); + + it("should return an error", async () => { + const userWithMissingProps = { firstname: "Claude" }; + + const response = await request(app) + .post("api/users") + .send(userWithMissingProps); + + expect(response.status).toEqual(500); + }); + + it("should return no user", async () => { + const newUser = { + firstname: "Alex", + lastname: "James Cameron", + email: "2009", + city: "1", + language: 162, + }; + + const response = (await request(app).put("/api/movies/0")).send(newMovie); + + expect(response.status).toEqual(404); + }); + + +}) + afterAll(() => database.end()); From 5e6df51d0a476c7fb3bb89e2c45fa203d87725af Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 16:44:38 +0200 Subject: [PATCH 08/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20validateMovie=20-?= =?UTF-8?q?=20Champs=20manquants=20:=20M=C3=A8thode=201=20de=20validation?= =?UTF-8?q?=20manuelle=20de=20la=20saisie=20de=20l'utilsateur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.js | 3 ++- src/middlewares/validateMovie.js | 19 +++++++++++++++++++ tests/movies.test.js | 4 ++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/middlewares/validateMovie.js diff --git a/src/app.js b/src/app.js index a15ffa85..1bf6209a 100644 --- a/src/app.js +++ b/src/app.js @@ -8,12 +8,13 @@ const app = express(); app.use(express.json()); const movieControllers = require("./controllers/movieControllers"); +const validateMovie = require("./middlewares/validateMovie"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); -app.post("/api/movies", movieControllers.postMovie); +app.post("/api/movies", validateMovie, movieControllers.postMovie); app.post("/api/users", movieControllers.postUsers); app.put("/api/movies/:id", movieControllers.updateMovie); app.put("/api/users/:id", movieControllers.updateUsers); diff --git a/src/middlewares/validateMovie.js b/src/middlewares/validateMovie.js new file mode 100644 index 00000000..98ab0398 --- /dev/null +++ b/src/middlewares/validateMovie.js @@ -0,0 +1,19 @@ +const validateMovie = (req, res, next) => { + const { title, director, year, color, duration } = req.body; + + if (title == null) { + res.status(422).send("The field 'title' is required"); + } else if (director == null) { + res.status(422).send("The field 'director' is required"); + } else if (year == null) { + res.status(422).send("The field 'year' is required"); + } else if (color == null) { + res.status(422).send("The field 'color' is required"); + } else if (duration = null) { + res.status(422).send("The field 'duration' is required"); + } else { + next(); + } +}; + +module.exports = validateMovie; \ No newline at end of file diff --git a/tests/movies.test.js b/tests/movies.test.js index 09774ded..ad5585fe 100644 --- a/tests/movies.test.js +++ b/tests/movies.test.js @@ -66,7 +66,7 @@ describe("POST /api/movies", () => { .post("/api/movies") .send(movieWithMissingProps); - expect(response.status).toEqual(500); + expect(response.status).toEqual(422); }); }); @@ -130,7 +130,7 @@ describe("PUT /api/movies/id", () => { .put(`/api/movies/1`) .send(movieWithMissingProps); - expect(response.status).toEqual(500); + expect(response.status).toEqual(422); }); it("should return no movie", async () => { From c6cad435149dfec676cbb10d68b5500c475edc26 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 16:50:24 +0200 Subject: [PATCH 09/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20validateMovie=20-?= =?UTF-8?q?=20Champs=20manquants=20:=20M=C3=A8thode=202=20de=20validation?= =?UTF-8?q?=20manuelle=20de=20la=20saisie=20de=20l'utilsateur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/middlewares/validateMovie.js | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/middlewares/validateMovie.js b/src/middlewares/validateMovie.js index 98ab0398..315918cf 100644 --- a/src/middlewares/validateMovie.js +++ b/src/middlewares/validateMovie.js @@ -1,19 +1,30 @@ const validateMovie = (req, res, next) => { const { title, director, year, color, duration } = req.body; - + const errors = []; + if (title == null) { - res.status(422).send("The field 'title' is required"); - } else if (director == null) { - res.status(422).send("The field 'director' is required"); - } else if (year == null) { - res.status(422).send("The field 'year' is required"); - } else if (color == null) { - res.status(422).send("The field 'color' is required"); - } else if (duration = null) { - res.status(422).send("The field 'duration' is required"); + errors.push({ field: "title", message: "This field is required" }); + } else if (title.length >= 255) { + errors.push({field: "title", message: "Le titre contient trop de caractères (+255), réduis !"}) + } + if (director == null) { + errors.push({ field: "director", message: "This field is required" }); + } + if (year == null) { + errors.push({ field: "year", message: "This field is required" }); + } + if (color == null) { + errors.push({ field: "color", message: "This field is required" }); + } + if (duration == null) { + errors.push({ field: "duration", message: "This field is required" }); + } + + if (errors.length) { + res.status(422).json({ validationErrors: errors }); } else { - next(); + next(); } -}; + }; -module.exports = validateMovie; \ No newline at end of file + module.exports = validateMovie; \ No newline at end of file From aba6006b42e7fe9c3928287c2fcc5dcd8f10ee75 Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 16:55:27 +0200 Subject: [PATCH 10/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20validateUser=20-?= =?UTF-8?q?=20Email=20:=20M=C3=A8thode=20de=20validation=20manuelle=20de?= =?UTF-8?q?=20la=20saisie=20de=20l'email=20de=20l'utilsateur.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.js | 3 ++- src/middlewares/validateUser.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/middlewares/validateUser.js diff --git a/src/app.js b/src/app.js index 1bf6209a..745fd93e 100644 --- a/src/app.js +++ b/src/app.js @@ -9,13 +9,14 @@ app.use(express.json()); const movieControllers = require("./controllers/movieControllers"); const validateMovie = require("./middlewares/validateMovie"); +const validateUser = require("./middlewares/validateUser"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); app.post("/api/movies", validateMovie, movieControllers.postMovie); -app.post("/api/users", movieControllers.postUsers); +app.post("/api/users", validateUser, movieControllers.postUsers); app.put("/api/movies/:id", movieControllers.updateMovie); app.put("/api/users/:id", movieControllers.updateUsers); diff --git a/src/middlewares/validateUser.js b/src/middlewares/validateUser.js new file mode 100644 index 00000000..751e52f0 --- /dev/null +++ b/src/middlewares/validateUser.js @@ -0,0 +1,18 @@ +const validateUser = (req, res, next) => { + const { email } = req.body; + const errors = []; + + const emailRegex = /[a-z0-9._]+@[a-z0-9-]+\.[a-z]{2,3}/; + + if (!emailRegex.test(email)) { + errors.push({ field: 'email', message: 'Invalid email' }); + } + + if (errors.length) { + res.status(422).json({ validationErrors: errors }); + } else { + next(); + } + }; + + module.exports = validateUser; \ No newline at end of file From cfd9c9d4f671e673da7274f37d52921fd9f104dc Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 17:09:08 +0200 Subject: [PATCH 11/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20validateUser=20-?= =?UTF-8?q?=20M=C3=A8thode=20de=20validation=20de=20la=20saisie=20de=20l'e?= =?UTF-8?q?mail=20de=20l'utilsateur=20via=20le=20module=20(Joi).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 87 +++++++++++++++++++++++++++++++++ package.json | 1 + src/middlewares/validateUser.js | 38 ++++++++------ 3 files changed, 111 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index a52f2c29..b5abbfcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "dotenv": "^16.3.1", "express": "^4.18.2", + "joi": "^17.13.1", "mysql2": "^3.6.3" }, "devDependencies": { @@ -700,6 +701,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1051,6 +1065,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -3255,6 +3287,18 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/joi": { + "version": "17.13.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz", + "integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5290,6 +5334,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -5568,6 +5625,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -7241,6 +7316,18 @@ } } }, + "joi": { + "version": "17.13.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz", + "integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==", + "requires": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 164181a8..1df83b37 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "dotenv": "^16.3.1", "express": "^4.18.2", + "joi": "^17.13.1", "mysql2": "^3.6.3" }, "devDependencies": { diff --git a/src/middlewares/validateUser.js b/src/middlewares/validateUser.js index 751e52f0..3de5eedd 100644 --- a/src/middlewares/validateUser.js +++ b/src/middlewares/validateUser.js @@ -1,18 +1,26 @@ +const Joi = require("joi"); + +const userSchema = Joi.object({ + email: Joi.string().email().max(255).required(), + firstname: Joi.string().max(255).required(), + lastname: Joi.string().max(255).required(), + city: Joi.string().max(255).required(), + language: Joi.string().max(255).required(), +}); + const validateUser = (req, res, next) => { - const { email } = req.body; - const errors = []; - - const emailRegex = /[a-z0-9._]+@[a-z0-9-]+\.[a-z]{2,3}/; - - if (!emailRegex.test(email)) { - errors.push({ field: 'email', message: 'Invalid email' }); - } - - if (errors.length) { - res.status(422).json({ validationErrors: errors }); - } else { - next(); - } - }; + const { firstname, lastname, email, city, language } = req.body; + + const { error } = userSchema.validate( + { firstname, lastname, email, city, language }, + { abortEarly: false } + ); + + if (error) { + res.status(422).json({ validationErrors: error.details }); + } else { + next(); + } +}; module.exports = validateUser; \ No newline at end of file From 7d391fc2cfdeb961da2e02e38cd9435aedf24fef Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 17:31:40 +0200 Subject: [PATCH 12/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20validateUser=20-?= =?UTF-8?q?=20M=C3=A8thode=20de=20validation=20de=20la=20saisie=20de=20l'e?= =?UTF-8?q?mail=20de=20l'utilsateur=20via=20le=20module=20(express-validat?= =?UTF-8?q?or).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 59 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ src/app.js | 22 +++++++++++++++--- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5abbfcf..ac7eda55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "dependencies": { "dotenv": "^16.3.1", "express": "^4.18.2", + "express-validator": "^7.1.0", + "install": "^0.13.0", "joi": "^17.13.1", "mysql2": "^3.6.3" }, @@ -2086,6 +2088,18 @@ "node": ">= 0.10.0" } }, + "node_modules/express-validator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.1.0.tgz", + "integrity": "sha512-ePn6NXjHRZiZkwTiU1Rl2hy6aUqmi6Cb4/s8sfUsKH7j2yYl9azSpl8xEHcOj1grzzQ+UBEoLWtE1s6FDxW++g==", + "dependencies": { + "lodash": "^4.17.21", + "validator": "~13.12.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2468,6 +2482,14 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3384,6 +3406,11 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -4697,6 +4724,14 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -6412,6 +6447,15 @@ "vary": "~1.1.2" } }, + "express-validator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.1.0.tgz", + "integrity": "sha512-ePn6NXjHRZiZkwTiU1Rl2hy6aUqmi6Cb4/s8sfUsKH7j2yYl9azSpl8xEHcOj1grzzQ+UBEoLWtE1s6FDxW++g==", + "requires": { + "lodash": "^4.17.21", + "validator": "~13.12.0" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -6691,6 +6735,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7389,6 +7438,11 @@ "p-locate": "^4.1.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -8343,6 +8397,11 @@ "convert-source-map": "^2.0.0" } }, + "validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index 1df83b37..f98bd67a 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "dependencies": { "dotenv": "^16.3.1", "express": "^4.18.2", + "express-validator": "^7.1.0", + "install": "^0.13.0", "joi": "^17.13.1", "mysql2": "^3.6.3" }, diff --git a/src/app.js b/src/app.js index 745fd93e..bfd2becb 100644 --- a/src/app.js +++ b/src/app.js @@ -1,6 +1,6 @@ require("dotenv").config(); -const port = process.env.APP_PORT +const port = process.env.APP_PORT; const express = require("express"); const app = express(); @@ -9,14 +9,30 @@ app.use(express.json()); const movieControllers = require("./controllers/movieControllers"); const validateMovie = require("./middlewares/validateMovie"); -const validateUser = require("./middlewares/validateUser"); +// const validateUser = require("./middlewares/validateUser"); +const { body, validationResult } = require('express-validator'); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); app.post("/api/movies", validateMovie, movieControllers.postMovie); -app.post("/api/users", validateUser, movieControllers.postUsers); +app.post( + "/api/users", + body("firstname").isLength({ min: 1, max: 255 }), + body("lastname").isLength({ min: 1, max: 255 }), + body("email").isEmail(), + (req, res, next) => { + const errors = validationResult(req); + + if (!errors.isEmpty()) { + res.status(422).json({ validationErrors: errors.array() }); + } else { + next(); + } + }, + movieControllers.postUsers +); app.put("/api/movies/:id", movieControllers.updateMovie); app.put("/api/users/:id", movieControllers.updateUsers); From 761784b9503ebcde4f17cd9e1beb5fb6acd48d7a Mon Sep 17 00:00:00 2001 From: Younes SEFIANI Date: Wed, 22 May 2024 18:36:18 +0200 Subject: [PATCH 13/13] =?UTF-8?q?Qu=C3=AAte=2003.2=20-=20Challenge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.js | 24 +++----------- src/middlewares/validateMovie.js | 52 ++++++++++++++---------------- src/middlewares/validateUser.js | 54 +++++++++++++++++++------------- tests/users.test.js | 18 +++++------ 4 files changed, 68 insertions(+), 80 deletions(-) diff --git a/src/app.js b/src/app.js index bfd2becb..a5e0073c 100644 --- a/src/app.js +++ b/src/app.js @@ -9,31 +9,15 @@ app.use(express.json()); const movieControllers = require("./controllers/movieControllers"); const validateMovie = require("./middlewares/validateMovie"); -// const validateUser = require("./middlewares/validateUser"); -const { body, validationResult } = require('express-validator'); +const validateUser = require("./middlewares/validateUser"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.get("/api/users", movieControllers.getUsers); app.get("/api/users/:id", movieControllers.getUsersById); app.post("/api/movies", validateMovie, movieControllers.postMovie); -app.post( - "/api/users", - body("firstname").isLength({ min: 1, max: 255 }), - body("lastname").isLength({ min: 1, max: 255 }), - body("email").isEmail(), - (req, res, next) => { - const errors = validationResult(req); - - if (!errors.isEmpty()) { - res.status(422).json({ validationErrors: errors.array() }); - } else { - next(); - } - }, - movieControllers.postUsers -); -app.put("/api/movies/:id", movieControllers.updateMovie); -app.put("/api/users/:id", movieControllers.updateUsers); +app.post("/api/users", validateUser, movieControllers.postUsers); +app.put("/api/movies/:id", validateMovie, movieControllers.updateMovie); +app.put("/api/users/:id", validateUser, movieControllers.updateUsers); module.exports = app; diff --git a/src/middlewares/validateMovie.js b/src/middlewares/validateMovie.js index 315918cf..40c13c68 100644 --- a/src/middlewares/validateMovie.js +++ b/src/middlewares/validateMovie.js @@ -1,30 +1,26 @@ +const Joi = require("joi"); + +const userSchema = Joi.object({ + title: Joi.string().max(255).required(), + director: Joi.string().max(255).required(), + year: Joi.string().min(4).max(4).required(), + color: Joi.string().max(1).required(), + duration: Joi.string().max(3).required(), +}); + const validateMovie = (req, res, next) => { - const { title, director, year, color, duration } = req.body; - const errors = []; - - if (title == null) { - errors.push({ field: "title", message: "This field is required" }); - } else if (title.length >= 255) { - errors.push({field: "title", message: "Le titre contient trop de caractères (+255), réduis !"}) - } - if (director == null) { - errors.push({ field: "director", message: "This field is required" }); - } - if (year == null) { - errors.push({ field: "year", message: "This field is required" }); - } - if (color == null) { - errors.push({ field: "color", message: "This field is required" }); - } - if (duration == null) { - errors.push({ field: "duration", message: "This field is required" }); - } - - if (errors.length) { - res.status(422).json({ validationErrors: errors }); - } else { - next(); - } - }; + const { title, director, year, color, duration } = req.body; + + const { error } = userSchema.validate( + { title, director, year, color, duration }, + { abortEarly: false } + ); + + if (error) { + res.status(422).json({ validationErrors: error.details }); + } else { + next(); + } +}; - module.exports = validateMovie; \ No newline at end of file +module.exports = validateMovie; \ No newline at end of file diff --git a/src/middlewares/validateUser.js b/src/middlewares/validateUser.js index 3de5eedd..a476be13 100644 --- a/src/middlewares/validateUser.js +++ b/src/middlewares/validateUser.js @@ -1,26 +1,36 @@ -const Joi = require("joi"); - -const userSchema = Joi.object({ - email: Joi.string().email().max(255).required(), - firstname: Joi.string().max(255).required(), - lastname: Joi.string().max(255).required(), - city: Joi.string().max(255).required(), - language: Joi.string().max(255).required(), -}); - const validateUser = (req, res, next) => { - const { firstname, lastname, email, city, language } = req.body; - - const { error } = userSchema.validate( - { firstname, lastname, email, city, language }, - { abortEarly: false } - ); + const { firstname, lastname, email, city, language } = req.body; + const errors = []; - if (error) { - res.status(422).json({ validationErrors: error.details }); - } else { - next(); - } -}; + const emailRegex = /[a-z0-9._]+@[a-z0-9-]+\.[a-z]{2,3}$/; + + if (firstname == null) { + errors.push({ field: "firstname", message: "This field is required" }); + } else if (firstname.length >= 255) { + errors.push({field: "firstname", message: "Le prénom doit faire moins de 255 caractères"}) + } + if (lastname == null) { + errors.push({ field: "lastname", message: "This field is required" }); + } else if (lastname.length >= 255) { + errors.push({field: "lastname", message: "Le nom doit faire moins de 255 caractères"}) + } + if (email == null) { + errors.push({ field: "email", message: "This field is required" }); + } else if (!emailRegex.test(email)) { + errors.push({field: 'email', message: 'Invalid email' }); + } + if (city == null) { + errors.push({ field: "city", message: "This field is required" }); + } + if (language == null) { + errors.push({ field: "language", message: "This field is required" }); + } + + if (errors.length) { + res.status(422).json({ validationErrors: errors }); + } else { + next(); + } + }; module.exports = validateUser; \ No newline at end of file diff --git a/tests/users.test.js b/tests/users.test.js index c9077591..67d854a0 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -67,7 +67,7 @@ describe("POST /api/users", () => { .post("api/users") .send(userWithMissingProps); - expect(response.status).toEqual(500); + expect(response.status).toEqual(422); }); }); @@ -131,24 +131,22 @@ describe("PUT /api/users/id", () => { .post("api/users") .send(userWithMissingProps); - expect(response.status).toEqual(500); + expect(response.status).toEqual(422); }); it("should return no user", async () => { const newUser = { firstname: "Alex", - lastname: "James Cameron", - email: "2009", - city: "1", - language: 162, + lastname: "Casey", + email: "alex.casey@coldcase.com", + city: "New York", + language: "English", }; - const response = (await request(app).put("/api/movies/0")).send(newMovie); + const response = (await request(app).put("/api/users/0")).send(newUser); expect(response.status).toEqual(404); }); - - -}) +}); afterAll(() => database.end());