From b8e7bfe69bb3b737ed0d1535295c5e4ed8bdc603 Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Mon, 19 Feb 2024 10:07:08 +0100 Subject: [PATCH 1/6] read database 1.02 --- .gitignore | 1 + database.js | 21 +++ index.js | 3 +- package-lock.json | 193 +++++++++++++++++++++++++++- package.json | 4 +- src/app.js | 4 + src/controllers/movieControllers.js | 32 +++-- src/controllers/userControllers.js | 42 ++++++ tests/users.test.js | 5 +- 9 files changed, 291 insertions(+), 14 deletions(-) create mode 100644 database.js create mode 100644 src/controllers/userControllers.js diff --git a/.gitignore b/.gitignore index 3c3629e64..37d7e7348 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.env diff --git a/database.js b/database.js new file mode 100644 index 000000000..ecc5e22c4 --- /dev/null +++ b/database.js @@ -0,0 +1,21 @@ +require("dotenv").config(); +const mysql = require("mysql2/promise"); + +const database = mysql.createPool({ + host: process.env.DB_HOST, // address of the server + port: process.env.DB_PORT, // port of the DB server (mysql), not to be confused with the APP_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); + }); + +module.exports = database; diff --git a/index.js b/index.js index d6626f115..6a5c56b9e 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ +require("dotenv").config(); const app = require("./src/app"); -const port = 5000; +const port = process.env.APP_PORT; app .listen(port, () => { diff --git a/package-lock.json b/package-lock.json index d6aeb7259..f1dd321c2 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.4.3", + "express": "^4.18.2", + "mysql2": "^3.9.1" }, "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.4.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.3.tgz", + "integrity": "sha512-II98GFrje5psQTSve0E7bnwMFybNLqT8Vu8JIFWRjsE3khyNUm/loZupuy5DVzG2IXf/ysxvrixYOQnM6mjD3A==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "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.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", + "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.4.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.3.tgz", + "integrity": "sha512-II98GFrje5psQTSve0E7bnwMFybNLqT8Vu8JIFWRjsE3khyNUm/loZupuy5DVzG2IXf/ysxvrixYOQnM6mjD3A==" + }, "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.9.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.1.tgz", + "integrity": "sha512-3njoWAAhGBYy0tWBabqUQcLtczZUxrmmtc2vszQUekg3kTJyZ5/IeLC3Fo04u6y6Iy5Sba7pIIa2P/gs8D3ZeQ==", + "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 64b8ae6d8..847b63150 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.4.3", + "express": "^4.18.2", + "mysql2": "^3.9.1" }, "devDependencies": { "jest": "^29.7.0", diff --git a/src/app.js b/src/app.js index 19f5d86d4..b03d9d7ee 100644 --- a/src/app.js +++ b/src/app.js @@ -3,8 +3,12 @@ const express = require("express"); const app = express(); const movieControllers = require("./controllers/movieControllers"); +const userControllers = require("./controllers/userControllers"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); +app.get("/api/users", userControllers.getUsers); +app.get("/api/users/:id", userControllers.getUserById); + module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index e3bb0053f..93db1ee95 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -25,20 +25,36 @@ 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); - - if (movie != null) { - res.json(movie); - } else { - res.status(404).send("Not Found"); - } + database + .query("SELECT * FROM movies WHERE id = ?", [id]) + .then(([movies]) => { + if (movies.length > 0) { + res.json(movies[0]); + } else { + res.sendStatus(404); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); }; module.exports = { diff --git a/src/controllers/userControllers.js b/src/controllers/userControllers.js new file mode 100644 index 000000000..ef8580f32 --- /dev/null +++ b/src/controllers/userControllers.js @@ -0,0 +1,42 @@ +const database = require("../../database"); + +const users = [ + { + id: 1, + name: "Paul Dubor", + email: "paul@wildecodeschool.com", + age: 28, + }, + { + id: 2, + name: "India", + email: "india@wildecodeschool.com", + age: 30, + }, + { + id: 3, + name: "Hyppo", + email: "hyppo@wildecodeschool.com", + age: 22, + }, +]; + +const getUsers = (req, res) => { + res.json(users); +}; + +const getUserById = (req, res) => { + const id = parseInt(req.params.id); + const user = users.find((user) => user.id === id); + + if (user) { + res.json(user); + } else { + res.sendStatus(404); + } +}; + +module.exports = { + getUsers, + getUserById, +}; diff --git a/tests/users.test.js b/tests/users.test.js index f69d5e9e0..62145ea90 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -1,5 +1,4 @@ const request = require("supertest"); - const app = require("../src/app"); describe("GET /api/users", () => { @@ -7,8 +6,8 @@ describe("GET /api/users", () => { const response = await request(app).get("/api/users"); expect(response.headers["content-type"]).toMatch(/json/); - expect(response.status).toEqual(200); + expect(response.body.length).toBeGreaterThan(0); }); }); @@ -17,8 +16,8 @@ describe("GET /api/users/:id", () => { const response = await request(app).get("/api/users/1"); expect(response.headers["content-type"]).toMatch(/json/); - expect(response.status).toEqual(200); + expect(response.body.id).toEqual(1); }); it("should return no user", async () => { From d1d9d8e79e94ec6582ca667c183869206242643f Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Mon, 19 Feb 2024 10:14:43 +0100 Subject: [PATCH 2/6] first commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..1fd4da0ef --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# express-quests From b6b80b99dc2f79c24bf713205045fc1a60a1532c Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Mon, 19 Feb 2024 10:45:38 +0100 Subject: [PATCH 3/6] post methode 2.01 --- src/app.js | 2 ++ src/controllers/movieControllers.js | 18 ++++++++++++++++++ src/controllers/userControllers.js | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/app.js b/src/app.js index b03d9d7ee..5bad42d88 100644 --- a/src/app.js +++ b/src/app.js @@ -7,8 +7,10 @@ const userControllers = require("./controllers/userControllers"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); +app.post("/api/movies", movieControllers.postMovie); app.get("/api/users", userControllers.getUsers); app.get("/api/users/:id", userControllers.getUserById); +app.post("/api/users", userControllers.postUser); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index 93db1ee95..622a21906 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -57,7 +57,25 @@ const getMovieById = (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); + }); +}; + module.exports = { getMovies, getMovieById, + postMovie, }; diff --git a/src/controllers/userControllers.js b/src/controllers/userControllers.js index ef8580f32..d32e70ba5 100644 --- a/src/controllers/userControllers.js +++ b/src/controllers/userControllers.js @@ -36,7 +36,26 @@ const getUserById = (req, res) => { } }; +const postUser = (req, res) => { + const { name, email, age } = req.body; + + database + .query("INSERT INTO users(name, email, age) VALUES (?, ?, ?)", [ + name, + email, + age, + ]) + .then(([result]) => { + res.status(201).send({ id: result.insertId }); + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + module.exports = { getUsers, getUserById, + postUser, }; From 10c44272df1289f34d8f6655be69701d252152b3 Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Mon, 19 Feb 2024 11:31:31 +0100 Subject: [PATCH 4/6] put method express-quest-3 --- src/app.js | 2 ++ src/controllers/movieControllers.js | 23 +++++++++++++++++++++++ src/controllers/userControllers.js | 23 +++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/app.js b/src/app.js index 5bad42d88..c89a5eb85 100644 --- a/src/app.js +++ b/src/app.js @@ -8,9 +8,11 @@ const userControllers = require("./controllers/userControllers"); app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.post("/api/movies", movieControllers.postMovie); +app.put("/api/movies/:id", movieControllers.updateMovie); app.get("/api/users", userControllers.getUsers); app.get("/api/users/:id", userControllers.getUserById); app.post("/api/users", userControllers.postUser); +app.put("/api/users/:id", userControllers.updateUser); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index 622a21906..d19e63c28 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -74,8 +74,31 @@ const postMovie = (req, res) => { }); }; +const updateMovie = (req, res) => { + const id = parseInt(req.params.id); + 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, postMovie, + updateMovie, }; diff --git a/src/controllers/userControllers.js b/src/controllers/userControllers.js index d32e70ba5..55a639afc 100644 --- a/src/controllers/userControllers.js +++ b/src/controllers/userControllers.js @@ -54,8 +54,31 @@ const postUser = (req, res) => { }); }; +const updateUser = (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 = { getUsers, getUserById, postUser, + updateUser, }; From 6750b5c9e749437c0eff35799b103ea8005cab37 Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Mon, 19 Feb 2024 11:44:43 +0100 Subject: [PATCH 5/6] delete method --- src/app.js | 2 ++ src/controllers/movieControllers.js | 19 +++++++++++++++++++ src/controllers/userControllers.js | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/app.js b/src/app.js index c89a5eb85..ef6e7a2ca 100644 --- a/src/app.js +++ b/src/app.js @@ -9,10 +9,12 @@ app.get("/api/movies", movieControllers.getMovies); app.get("/api/movies/:id", movieControllers.getMovieById); app.post("/api/movies", movieControllers.postMovie); app.put("/api/movies/:id", movieControllers.updateMovie); +app.delete("/api/movies/:id", movieControllers.deleteMovie); app.get("/api/users", userControllers.getUsers); app.get("/api/users/:id", userControllers.getUserById); app.post("/api/users", userControllers.postUser); app.put("/api/users/:id", userControllers.updateUser); +app.delete("/api/users/:id", userControllers.deleteUser); module.exports = app; diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index d19e63c28..31ed1b6d6 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -96,9 +96,28 @@ const updateMovie = (req, res) => { }); }; +const deleteMovie = (req, res) => { + const id = parseInt(req.params.id); + + database + .query("delete from movies where id = ?", [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, postMovie, updateMovie, + deleteMovie, }; diff --git a/src/controllers/userControllers.js b/src/controllers/userControllers.js index 55a639afc..823f8b12d 100644 --- a/src/controllers/userControllers.js +++ b/src/controllers/userControllers.js @@ -76,9 +76,28 @@ const updateUser = (req, res) => { }); }; +const deleteUser = (req, res) => { + const id = parseInt(req.params.id); + + database + .query("delete from users where id = ?", [id]) + .then(([result]) => { + if (result.affectedRows === 0) { + res.sendStatus(404); + } else { + res.sendStatus(204); + } + }) + .catch((err) => { + console.error(err); + res.sendStatus(500); + }); +}; + module.exports = { getUsers, getUserById, postUser, updateUser, + deleteUser, }; From 74beb936b9ce0801a71b17ac54aa3c217aad44a4 Mon Sep 17 00:00:00 2001 From: marcopoltergeist Date: Tue, 20 Feb 2024 11:51:35 +0100 Subject: [PATCH 6/6] test route post --- database.js | 4 +-- src/app.js | 2 ++ src/controllers/movieControllers.js | 1 - src/controllers/userControllers.js | 31 +++++++++++--------- tests/movies.test.js | 43 ++++++++++++++++++++++++++- tests/users.test.js | 45 +++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 17 deletions(-) diff --git a/database.js b/database.js index ecc5e22c4..545c7fce4 100644 --- a/database.js +++ b/database.js @@ -2,8 +2,8 @@ require("dotenv").config(); const mysql = require("mysql2/promise"); const database = mysql.createPool({ - host: process.env.DB_HOST, // address of the server - port: process.env.DB_PORT, // port of the DB server (mysql), not to be confused with the APP_PORT ! + host: process.env.DB_HOST, + port: process.env.DB_PORT, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, diff --git a/src/app.js b/src/app.js index ef6e7a2ca..18873ba16 100644 --- a/src/app.js +++ b/src/app.js @@ -2,6 +2,8 @@ const express = require("express"); const app = express(); +app.use(express.json()); + const movieControllers = require("./controllers/movieControllers"); const userControllers = require("./controllers/userControllers"); diff --git a/src/controllers/movieControllers.js b/src/controllers/movieControllers.js index 31ed1b6d6..f7c666518 100644 --- a/src/controllers/movieControllers.js +++ b/src/controllers/movieControllers.js @@ -69,7 +69,6 @@ const postMovie = (req, res) => { res.status(201).send({ id: result.insertId }); }) .catch((err) => { - console.error(err); res.sendStatus(500); }); }; diff --git a/src/controllers/userControllers.js b/src/controllers/userControllers.js index 823f8b12d..b05073635 100644 --- a/src/controllers/userControllers.js +++ b/src/controllers/userControllers.js @@ -3,21 +3,27 @@ const database = require("../../database"); const users = [ { id: 1, - name: "Paul Dubor", + firstname: "Paul", + lastname: "Dubor", email: "paul@wildecodeschool.com", - age: 28, + city: "Bordeaux", + language: "Francais", }, { id: 2, - name: "India", + firstname: "India", + lastname: "Chameroy", email: "india@wildecodeschool.com", - age: 30, + city: "Bordeaux", + language: "Francais", }, { id: 3, - name: "Hyppo", + firstname: "Hyppo", + lastname: "Chameroy", email: "hyppo@wildecodeschool.com", - age: 22, + city: "Bordeaux", + language: "Francais", }, ]; @@ -37,14 +43,13 @@ const getUserById = (req, res) => { }; const postUser = (req, res) => { - const { name, email, age } = req.body; + const { firstname, lastname, email, city, language } = req.body; database - .query("INSERT INTO users(name, email, age) VALUES (?, ?, ?)", [ - name, - email, - age, - ]) + .query( + "INSERT INTO users(firstname, lastname, email, city, language) VALUES (?, ?, ?, ?, ?)", + [firstname, lastname, email, city, language] + ) .then(([result]) => { res.status(201).send({ id: result.insertId }); }) @@ -80,7 +85,7 @@ const deleteUser = (req, res) => { const id = parseInt(req.params.id); database - .query("delete from users where id = ?", [id]) + .query("DELETE FROM users WHERE id = ?", [id]) .then(([result]) => { if (result.affectedRows === 0) { res.sendStatus(404); diff --git a/tests/movies.test.js b/tests/movies.test.js index 09621f56f..1cd174d2e 100644 --- a/tests/movies.test.js +++ b/tests/movies.test.js @@ -1,6 +1,6 @@ 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 +27,44 @@ describe("GET /api/movies/:id", () => { expect(response.status).toEqual(404); }); }); + +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.title).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); + }); +}); diff --git a/tests/users.test.js b/tests/users.test.js index 62145ea90..d688d8de5 100644 --- a/tests/users.test.js +++ b/tests/users.test.js @@ -1,5 +1,7 @@ const request = require("supertest"); const app = require("../src/app"); +const database = require("../database"); +const crypto = require("crypto"); describe("GET /api/users", () => { it("should return all users", async () => { @@ -26,3 +28,46 @@ describe("GET /api/users/:id", () => { expect(response.status).toEqual(404); }); }); + +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.firstname).toEqual(newUser.firstname); + expect(userInDatabase.lastname).toEqual(newUser.lastname); + expect(userInDatabase.email).toEqual(newUser.email); + expect(userInDatabase.city).toEqual(newUser.city); + expect(userInDatabase.language).toEqual(newUser.language); + }); + + it("should return an error", async () => { + const userWithMissingProps = { firstname: "Marie" }; + + const response = await request(app) + .post("/api/users") + .send(userWithMissingProps); + + expect(response.status).toEqual(500); + }); +});