From bd57b8eca88cb3dfc8691c6cab1cae9b08784849 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 13:27:27 +0100 Subject: [PATCH 01/18] Routes and controllers for users --- src/controllers/filmsControllers.js | 0 src/controllers/usersControllers.js | 40 +++++++++++++++++++++++++++++ src/routers/users.js | 12 +++++++++ src/server.js | 5 ++-- 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/controllers/filmsControllers.js create mode 100644 src/controllers/usersControllers.js diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js new file mode 100644 index 0000000..e69de29 diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js new file mode 100644 index 0000000..015ba61 --- /dev/null +++ b/src/controllers/usersControllers.js @@ -0,0 +1,40 @@ +const data = require("../../data/index.js"); +const users = data.users; +let idCounter = 4 + +function getAllUsers(req, res) { + res.status(200).json({ users }); +} + +function createUser(req, res) { + const newUser = req.body + newUser.id = idCounter + users.push(newUser) + idCounter++ + res.status(201).json({ user: newUser}) +} + +function getUserById(req, res) { + const userId = Number(req.params.id) + const user = users.find((user) => user.id === userId) + res.status(200).json({ user }) +} + +function deleteUser(req, res) { + const userId = Number(req.params.id) + const user = users.find((user) => user.id === userId) + const index = users.indexOf(user) + users.splice(index, 1) + res.status(200).json({ user }) +} + +function updateUser(req, res){ + const updatedParameters = req.body + const userId = Number(req.params.id) + const user = users.find((user) => user.id === userId) + Object.assign(user, updatedParameters) + + res.status(200).json({ user }) +} + +module.exports = { getAllUsers, createUser, getUserById, deleteUser, updateUser }; diff --git a/src/routers/users.js b/src/routers/users.js index e69de29..7ef1e7f 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -0,0 +1,12 @@ +const express = require('express') +const usersRouter = express.Router() +const { getAllUsers, createUser, getUserById, deleteUser, updateUser } = require("../controllers/usersControllers.js") + + +usersRouter.get("/", getAllUsers) +usersRouter.post("/", createUser) +usersRouter.get("/:id", getUserById) +usersRouter.delete("/:id", deleteUser) +usersRouter.put("/:id", updateUser) + +module.exports = usersRouter \ No newline at end of file diff --git a/src/server.js b/src/server.js index 715321f..704e4e8 100644 --- a/src/server.js +++ b/src/server.js @@ -10,9 +10,10 @@ app.use(express.json()); app.use(morgan("dev")); // REQUIRE ROUTERS -const usersRouter = require("./routers/users"); +const usersRouter = require("./routers/users.js"); -// ADD ROUTERS TO APP +// ADD ROUTERS TO APP +app.use("/users", usersRouter) module.exports = app From ce2f9b79463280e73c1eac95541c20669ff5e86a Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 13:44:10 +0100 Subject: [PATCH 02/18] Film routes with getall and post controllers --- src/controllers/filmsControllers.js | 17 +++++++++++++++++ src/routers/films.js | 8 ++++++++ src/server.js | 2 ++ 3 files changed, 27 insertions(+) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index e69de29..fc48df6 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -0,0 +1,17 @@ +const data = require("../../data/index.js"); +const films = data.films; +let idCounter = 5 + +function getAllFilms(req, res){ + res.status(200).json({ films }) +} + +function createFilm(req, res){ + const film = req.body + film.id = idCounter + films.push(film) + idCounter++ + res.status(201).json({ film }) +} + +module.exports = { getAllFilms, createFilm } \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..691e2d6 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,8 @@ +const express = require('express') +const filmsRouter = express.Router() +const { getAllFilms, createFilm } = require("../controllers/filmsControllers.js") + +filmsRouter.get("/", getAllFilms) +filmsRouter.post("/", createFilm) + +module.exports = filmsRouter \ No newline at end of file diff --git a/src/server.js b/src/server.js index 704e4e8..91c2543 100644 --- a/src/server.js +++ b/src/server.js @@ -11,9 +11,11 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users.js"); +const filmsRouter = require("./routers/films.js") // ADD ROUTERS TO APP app.use("/users", usersRouter) +app.use("/films", filmsRouter) module.exports = app From 41651f5c8d2cab9ca8dc33a06ab5568f8b3016ff Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 13:46:21 +0100 Subject: [PATCH 03/18] Get film by ID --- src/controllers/filmsControllers.js | 9 ++++++++- src/routers/films.js | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index fc48df6..e4d1402 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -14,4 +14,11 @@ function createFilm(req, res){ res.status(201).json({ film }) } -module.exports = { getAllFilms, createFilm } \ No newline at end of file + +function getFilmById(req, res){ + const filmId = Number(req.params.id) + const film = films.find((film) => film.id === filmId) + res.status(200).json({ film }) +} + +module.exports = { getAllFilms, createFilm, getFilmById } \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index 691e2d6..6cc295f 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,8 +1,9 @@ const express = require('express') const filmsRouter = express.Router() -const { getAllFilms, createFilm } = require("../controllers/filmsControllers.js") +const { getAllFilms, createFilm, getFilmById } = require("../controllers/filmsControllers.js") filmsRouter.get("/", getAllFilms) filmsRouter.post("/", createFilm) +filmsRouter.get("/:id", getFilmById) module.exports = filmsRouter \ No newline at end of file From d38c887e32f1461e4500753748b7f16f675f8bfb Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 13:48:00 +0100 Subject: [PATCH 04/18] Delete film by ID --- src/controllers/filmsControllers.js | 10 +++++++++- src/routers/films.js | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index e4d1402..864bf5f 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -21,4 +21,12 @@ function getFilmById(req, res){ res.status(200).json({ film }) } -module.exports = { getAllFilms, createFilm, getFilmById } \ No newline at end of file +function deleteFilmById(req, res){ + const filmId = Number(req.params.id) + const film = films.find((film) => film.id === filmId) + const index = films.indexOf(film) + films.splice(index, 1) + res.status(200).json( {film} ) +} + +module.exports = { getAllFilms, createFilm, getFilmById, deleteFilmById } \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index 6cc295f..1562a57 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,9 +1,10 @@ const express = require('express') const filmsRouter = express.Router() -const { getAllFilms, createFilm, getFilmById } = require("../controllers/filmsControllers.js") +const { getAllFilms, createFilm, getFilmById, deleteFilmById } = require("../controllers/filmsControllers.js") filmsRouter.get("/", getAllFilms) filmsRouter.post("/", createFilm) filmsRouter.get("/:id", getFilmById) +filmsRouter.delete("/:id", deleteFilmById) module.exports = filmsRouter \ No newline at end of file From 578e7d84ac9ca69a8c1365fa433e212a78135656 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 13:51:04 +0100 Subject: [PATCH 05/18] Edit film by ID --- src/controllers/filmsControllers.js | 53 ++++++++++++++++++----------- src/routers/films.js | 3 +- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index 864bf5f..c7c75be 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -1,32 +1,45 @@ const data = require("../../data/index.js"); const films = data.films; -let idCounter = 5 +let idCounter = 5; -function getAllFilms(req, res){ - res.status(200).json({ films }) +function getAllFilms(req, res) { + res.status(200).json({ films }); } -function createFilm(req, res){ - const film = req.body - film.id = idCounter - films.push(film) - idCounter++ - res.status(201).json({ film }) +function createFilm(req, res) { + const film = req.body; + film.id = idCounter; + films.push(film); + idCounter++; + res.status(201).json({ film }); } +function getFilmById(req, res) { + const filmId = Number(req.params.id); + const film = films.find((film) => film.id === filmId); + res.status(200).json({ film }); +} -function getFilmById(req, res){ - const filmId = Number(req.params.id) - const film = films.find((film) => film.id === filmId) - res.status(200).json({ film }) +function deleteFilmById(req, res) { + const filmId = Number(req.params.id); + const film = films.find((film) => film.id === filmId); + const index = films.indexOf(film); + films.splice(index, 1); + res.status(200).json({ film }); } -function deleteFilmById(req, res){ - const filmId = Number(req.params.id) - const film = films.find((film) => film.id === filmId) - const index = films.indexOf(film) - films.splice(index, 1) - res.status(200).json( {film} ) +function updateFilmById(req, res) { + const updatedParameters = req.body; + const filmId = Number(req.params.id); + const film = films.find((film) => film.id === filmId); + Object.assign(film, updatedParameters); + res.status(200).json({ film }); } -module.exports = { getAllFilms, createFilm, getFilmById, deleteFilmById } \ No newline at end of file +module.exports = { + getAllFilms, + createFilm, + getFilmById, + deleteFilmById, + updateFilmById, +}; diff --git a/src/routers/films.js b/src/routers/films.js index 1562a57..4c53a65 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,10 +1,11 @@ const express = require('express') const filmsRouter = express.Router() -const { getAllFilms, createFilm, getFilmById, deleteFilmById } = require("../controllers/filmsControllers.js") +const { getAllFilms, createFilm, getFilmById, deleteFilmById, updateFilmById } = require("../controllers/filmsControllers.js") filmsRouter.get("/", getAllFilms) filmsRouter.post("/", createFilm) filmsRouter.get("/:id", getFilmById) filmsRouter.delete("/:id", deleteFilmById) +filmsRouter.put("/:id", updateFilmById) module.exports = filmsRouter \ No newline at end of file From bba38a31243c563ff56a8a22a44823d759ab0c60 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 14:03:12 +0100 Subject: [PATCH 06/18] Get all books --- src/controllers/booksControllers.js | 9 +++++++++ src/routers/books.js | 8 ++++++-- src/server.js | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/controllers/booksControllers.js diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js new file mode 100644 index 0000000..dfc4034 --- /dev/null +++ b/src/controllers/booksControllers.js @@ -0,0 +1,9 @@ +const data = require("../../data/index.js"); +const books = data.books; +let idCounter = 5; + +function getAllBooks(req, res) { + res.status(200).json({ books }); +} + +module.exports = { getAllBooks }; diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..5174e0f 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,8 @@ -// Import data here... +const express = require('express') +const booksRouter = express.Router() +const { getAllBooks } = require('../controllers/booksControllers.js') -// Write routes here... +booksRouter.get("/", getAllBooks) + +module.exports = booksRouter \ No newline at end of file diff --git a/src/server.js b/src/server.js index 91c2543..981f3d3 100644 --- a/src/server.js +++ b/src/server.js @@ -12,10 +12,12 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users.js"); const filmsRouter = require("./routers/films.js") +const booksRouter = require("./routers/books.js") // ADD ROUTERS TO APP app.use("/users", usersRouter) app.use("/films", filmsRouter) +app.use("/books", booksRouter) module.exports = app From 1913d66e8e59259a8e8d434a28b2f4efc3e13d93 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 14:13:55 +0100 Subject: [PATCH 07/18] Get book by ID --- src/controllers/booksControllers.js | 14 +++++++++++++- src/routers/books.js | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js index dfc4034..eb35d7a 100644 --- a/src/controllers/booksControllers.js +++ b/src/controllers/booksControllers.js @@ -6,4 +6,16 @@ function getAllBooks(req, res) { res.status(200).json({ books }); } -module.exports = { getAllBooks }; +function createBook(req, res) { + const book = req.body + books.push(book) + res.status(201).json({ book }) +} + +function getBookById(req, res) { + const bookId = Number(req.params.id) + const book = books.find((book) => book.id === bookId) + res.status(200).json({ book }) +} + +module.exports = { getAllBooks, createBook, getBookById }; diff --git a/src/routers/books.js b/src/routers/books.js index 5174e0f..472d38f 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,8 +1,10 @@ const express = require('express') const booksRouter = express.Router() -const { getAllBooks } = require('../controllers/booksControllers.js') +const { getAllBooks, createBook, getBookById } = require('../controllers/booksControllers.js') booksRouter.get("/", getAllBooks) +booksRouter.post("/", createBook) +booksRouter.get("/:id", getBookById) module.exports = booksRouter \ No newline at end of file From 2b995bb66625a4deb6eaf59bc64d77d0bf29135b Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 14:20:30 +0100 Subject: [PATCH 08/18] Update book by ID --- src/controllers/booksControllers.js | 18 +++++++++++++++++- src/routers/books.js | 4 +++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js index eb35d7a..eb9e310 100644 --- a/src/controllers/booksControllers.js +++ b/src/controllers/booksControllers.js @@ -18,4 +18,20 @@ function getBookById(req, res) { res.status(200).json({ book }) } -module.exports = { getAllBooks, createBook, getBookById }; +function deleteBookById(req, res) { + const bookId = Number(req.params.id) + const book = books.find((book) => book.id === bookId) + const index = books.indexOf(book) + books.splice(index, 1) + res.status(200).json({ book }) +} + +function updateBookById(req, res) { + const updatedParams = req.body + const bookId = Number(req.params.id) + const book = books.find((book) => book.id === bookId) + Object.assign(book, updatedParams) + res.status(200).json({ book }) +} + +module.exports = { getAllBooks, createBook, getBookById, deleteBookById, updateBookById }; diff --git a/src/routers/books.js b/src/routers/books.js index 472d38f..21edff8 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,10 +1,12 @@ const express = require('express') const booksRouter = express.Router() -const { getAllBooks, createBook, getBookById } = require('../controllers/booksControllers.js') +const { getAllBooks, createBook, getBookById, deleteBookById, updateBookById } = require('../controllers/booksControllers.js') booksRouter.get("/", getAllBooks) booksRouter.post("/", createBook) booksRouter.get("/:id", getBookById) +booksRouter.delete("/:id", deleteBookById) +booksRouter.put("/:id", updateBookById) module.exports = booksRouter \ No newline at end of file From 1768003dc7b0e9a252773533c8192ec3cc0ad7bf Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 15:37:34 +0100 Subject: [PATCH 09/18] Throw errors for adding users without an email address and for a user that already exists --- src/controllers/usersControllers.js | 8 ++++++++ src/errors/errors.js | 4 ++++ src/server.js | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/errors/errors.js diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js index 015ba61..91d59e9 100644 --- a/src/controllers/usersControllers.js +++ b/src/controllers/usersControllers.js @@ -1,6 +1,7 @@ const data = require("../../data/index.js"); const users = data.users; let idCounter = 4 +const { MissingFieldsError, DataAlreadyExistsError } = require("../errors/errors.js") function getAllUsers(req, res) { res.status(200).json({ users }); @@ -8,6 +9,13 @@ function getAllUsers(req, res) { function createUser(req, res) { const newUser = req.body + if (!newUser.email) { + throw new MissingFieldsError('Missing fields in request body') + } + if (users.find((user) => user.email === newUser.email)) { + throw new DataAlreadyExistsError('A user with the provided email already exists') + } + newUser.id = idCounter users.push(newUser) idCounter++ diff --git a/src/errors/errors.js b/src/errors/errors.js new file mode 100644 index 0000000..2a784be --- /dev/null +++ b/src/errors/errors.js @@ -0,0 +1,4 @@ +class MissingFieldsError extends Error {} +class DataAlreadyExistsError extends Error {} + +module.exports = { MissingFieldsError, DataAlreadyExistsError } \ No newline at end of file diff --git a/src/server.js b/src/server.js index 981f3d3..840cc37 100644 --- a/src/server.js +++ b/src/server.js @@ -20,4 +20,26 @@ app.use("/users", usersRouter) app.use("/films", filmsRouter) app.use("/books", booksRouter) +// ADD ERRORS +const { MissingFieldsError, DataAlreadyExistsError } = require("./errors/errors.js") + +app.use((error, req, res, next) => { + console.log(error) + if (error instanceof MissingFieldsError) { + return res.status(400).json({ + error: error.message + }) + } + + if (error instanceof DataAlreadyExistsError) { + return res.status(409).json({ + error: error.message + }) + } + + res.status(500).json({ + message: 'Something went wrong' + }) +}) + module.exports = app From 0ef949ba134d2fcf880a47fba33d167c1daef1a8 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 15:39:51 +0100 Subject: [PATCH 10/18] Throw error when no user found wiht specific ID --- src/controllers/usersControllers.js | 5 ++++- src/errors/errors.js | 3 ++- src/server.js | 8 +++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js index 91d59e9..654bea5 100644 --- a/src/controllers/usersControllers.js +++ b/src/controllers/usersControllers.js @@ -1,7 +1,7 @@ const data = require("../../data/index.js"); const users = data.users; let idCounter = 4 -const { MissingFieldsError, DataAlreadyExistsError } = require("../errors/errors.js") +const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = require("../errors/errors.js") function getAllUsers(req, res) { res.status(200).json({ users }); @@ -31,6 +31,9 @@ function getUserById(req, res) { function deleteUser(req, res) { const userId = Number(req.params.id) const user = users.find((user) => user.id === userId) + if (!user) { + throw new DataNotFoundError('A user with the provided ID does not exist') + } const index = users.indexOf(user) users.splice(index, 1) res.status(200).json({ user }) diff --git a/src/errors/errors.js b/src/errors/errors.js index 2a784be..5875e75 100644 --- a/src/errors/errors.js +++ b/src/errors/errors.js @@ -1,4 +1,5 @@ class MissingFieldsError extends Error {} class DataAlreadyExistsError extends Error {} +class DataNotFoundError extends Error {} -module.exports = { MissingFieldsError, DataAlreadyExistsError } \ No newline at end of file +module.exports = { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError} \ No newline at end of file diff --git a/src/server.js b/src/server.js index 840cc37..19ecde6 100644 --- a/src/server.js +++ b/src/server.js @@ -21,7 +21,7 @@ app.use("/films", filmsRouter) app.use("/books", booksRouter) // ADD ERRORS -const { MissingFieldsError, DataAlreadyExistsError } = require("./errors/errors.js") +const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = require("./errors/errors.js") app.use((error, req, res, next) => { console.log(error) @@ -37,6 +37,12 @@ app.use((error, req, res, next) => { }) } + if (error instanceof DataNotFoundError) { + return res.status(404).json({ + error: error.message + }) + } + res.status(500).json({ message: 'Something went wrong' }) From 5e026fd4fda1e1440a25456674ce0b5bdb31e724 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:02:05 +0100 Subject: [PATCH 11/18] Returns error if creating a film with no title/director or repeating data --- package.json | 3 ++- src/controllers/filmsControllers.js | 7 +++++++ src/controllers/usersControllers.js | 12 ++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c63bc01..5b69b20 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "npx nodemon src/index.js", "test": "npx jest -i test/api/routes --forceExit --runInBand", - "test-extensions": "npx jest -i test/api/extensions --forceExit" + "test-extensions": "npx jest -i test/api/extensions --forceExit", + "test-extensions-films": "npx jest -i test/api/extensions/films.spec.js --forceExit" }, "dependencies": { "cors": "^2.8.5", diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index c7c75be..12f8c2b 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -1,6 +1,7 @@ const data = require("../../data/index.js"); const films = data.films; let idCounter = 5; +const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = require('../errors/errors.js') function getAllFilms(req, res) { res.status(200).json({ films }); @@ -8,6 +9,12 @@ function getAllFilms(req, res) { function createFilm(req, res) { const film = req.body; + if (!film.title || !film.director) { + throw new MissingFieldsError('Missing fields in request body') + } + if (films.find((f) => f.title === film.title)) { + throw new DataAlreadyExistsError('A film with the provided title already exists') + } film.id = idCounter; films.push(film); idCounter++; diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js index 654bea5..216d313 100644 --- a/src/controllers/usersControllers.js +++ b/src/controllers/usersControllers.js @@ -25,6 +25,9 @@ function createUser(req, res) { function getUserById(req, res) { const userId = Number(req.params.id) const user = users.find((user) => user.id === userId) + if (!user) { + throw new DataNotFoundError('A user with the provided ID does not exist') + } res.status(200).json({ user }) } @@ -41,8 +44,17 @@ function deleteUser(req, res) { function updateUser(req, res){ const updatedParameters = req.body + if (!updatedParameters.email) { + throw new MissingFieldsError('Missing fields in request body') + } + if (users.find((user) => user.email === updatedParameters.email)) { + throw new DataAlreadyExistsError('A user with the provided email already exists') + } const userId = Number(req.params.id) const user = users.find((user) => user.id === userId) + if (!user) { + throw new DataNotFoundError('A user with the provided ID does not exist') + } Object.assign(user, updatedParameters) res.status(200).json({ user }) From 0a1996cb285f96f0fa30951ba53b3ee59413d888 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:04:31 +0100 Subject: [PATCH 12/18] Throws error when no film with ID found --- src/controllers/filmsControllers.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index 12f8c2b..39ff188 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -24,6 +24,9 @@ function createFilm(req, res) { function getFilmById(req, res) { const filmId = Number(req.params.id); const film = films.find((film) => film.id === filmId); + if (!film) { + throw new DataNotFoundError('A film with provided ID does not exist') + } res.status(200).json({ film }); } From 9355b56ac3c04251320cf823d35ffee887c6a0c3 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:25:34 +0100 Subject: [PATCH 13/18] find film by director --- src/controllers/filmsControllers.js | 24 ++++++++++++++++++---- src/routers/films.js | 31 ++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index 39ff188..e03dab7 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -1,7 +1,11 @@ const data = require("../../data/index.js"); const films = data.films; let idCounter = 5; -const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = require('../errors/errors.js') +const { + MissingFieldsError, + DataAlreadyExistsError, + DataNotFoundError, +} = require("../errors/errors.js"); function getAllFilms(req, res) { res.status(200).json({ films }); @@ -10,10 +14,12 @@ function getAllFilms(req, res) { function createFilm(req, res) { const film = req.body; if (!film.title || !film.director) { - throw new MissingFieldsError('Missing fields in request body') + throw new MissingFieldsError("Missing fields in request body"); } if (films.find((f) => f.title === film.title)) { - throw new DataAlreadyExistsError('A film with the provided title already exists') + throw new DataAlreadyExistsError( + "A film with the provided title already exists" + ); } film.id = idCounter; films.push(film); @@ -25,7 +31,7 @@ function getFilmById(req, res) { const filmId = Number(req.params.id); const film = films.find((film) => film.id === filmId); if (!film) { - throw new DataNotFoundError('A film with provided ID does not exist') + throw new DataNotFoundError("A film with provided ID does not exist"); } res.status(200).json({ film }); } @@ -33,6 +39,9 @@ function getFilmById(req, res) { function deleteFilmById(req, res) { const filmId = Number(req.params.id); const film = films.find((film) => film.id === filmId); + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist"); + } const index = films.indexOf(film); films.splice(index, 1); res.status(200).json({ film }); @@ -46,10 +55,17 @@ function updateFilmById(req, res) { res.status(200).json({ film }); } +function getFilmByDirector(req, res) { + const director = req.query.director; + const filteredFilms = films.filter((film) => film.director === director) + res.status(200).json({ films: filteredFilms }) +} + module.exports = { getAllFilms, createFilm, getFilmById, deleteFilmById, updateFilmById, + getFilmByDirector, }; diff --git a/src/routers/films.js b/src/routers/films.js index 4c53a65..7cdf5f8 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,11 +1,24 @@ -const express = require('express') -const filmsRouter = express.Router() -const { getAllFilms, createFilm, getFilmById, deleteFilmById, updateFilmById } = require("../controllers/filmsControllers.js") +const express = require("express"); +const filmsRouter = express.Router(); +const { + getAllFilms, + createFilm, + getFilmById, + deleteFilmById, + updateFilmById, + getFilmByDirector, +} = require("../controllers/filmsControllers.js"); -filmsRouter.get("/", getAllFilms) -filmsRouter.post("/", createFilm) -filmsRouter.get("/:id", getFilmById) -filmsRouter.delete("/:id", deleteFilmById) -filmsRouter.put("/:id", updateFilmById) +filmsRouter.get("/", (req, res) => { + if (req.query.director) { + return getFilmByDirector(req, res); + } else { + return getAllFilms(req, res); + } +}); +filmsRouter.post("/", createFilm); +filmsRouter.get("/:id", getFilmById); +filmsRouter.delete("/:id", deleteFilmById); +filmsRouter.put("/:id", updateFilmById); -module.exports = filmsRouter \ No newline at end of file +module.exports = filmsRouter; From cee59d8951b2bde2819b807c8525f8c0cdb42d68 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:28:26 +0100 Subject: [PATCH 14/18] Return error when updating film that doesn't exist or if title already exists --- src/controllers/filmsControllers.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index e03dab7..bc06a66 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -49,16 +49,24 @@ function deleteFilmById(req, res) { function updateFilmById(req, res) { const updatedParameters = req.body; + if (films.find((film) => film.title === updatedParameters.title)) { + throw new DataAlreadyExistsError( + "A film with the provided title already exists" + ); + } const filmId = Number(req.params.id); const film = films.find((film) => film.id === filmId); + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist"); + } Object.assign(film, updatedParameters); res.status(200).json({ film }); } function getFilmByDirector(req, res) { const director = req.query.director; - const filteredFilms = films.filter((film) => film.director === director) - res.status(200).json({ films: filteredFilms }) + const filteredFilms = films.filter((film) => film.director === director); + res.status(200).json({ films: filteredFilms }); } module.exports = { From 7e4ef8d3cbd916ba4d18d49509b9b41bc4e2a7d7 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:36:35 +0100 Subject: [PATCH 15/18] Errors when patching film with no title/director or repeating film name --- package.json | 4 +++- src/controllers/filmsControllers.js | 20 ++++++++++++++++++++ src/routers/films.js | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b69b20..abca99c 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "start": "npx nodemon src/index.js", "test": "npx jest -i test/api/routes --forceExit --runInBand", "test-extensions": "npx jest -i test/api/extensions --forceExit", - "test-extensions-films": "npx jest -i test/api/extensions/films.spec.js --forceExit" + "test-extensions-films": "npx jest -i test/api/extensions/films.spec.js --forceExit", + "test-extensions-users": "npx jest -i test/api/extensions/users.spec.js --forceExit", + "test-extensions-books": "npx jest -i test/api/extensions/books.spec.js --forceExit" }, "dependencies": { "cors": "^2.8.5", diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index bc06a66..c637ea2 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -69,6 +69,25 @@ function getFilmByDirector(req, res) { res.status(200).json({ films: filteredFilms }); } +function patchFilmById(req, res) { + const filmId = Number(req.params.id); + const updatedParameters = req.body; + if (!updatedParameters.title && !updatedParameters.director) { + throw new MissingFieldsError("Missing fields in request body"); + } + const film = films.find((film) => film.id === filmId); + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist"); + } + if (films.find((film) => film.title === updatedParameters.title)) { + throw new DataAlreadyExistsError( + "A film with the provided title already exists" + ); + } + Object.assign(film, updatedParameters); + res.status(200).json({ film }); +} + module.exports = { getAllFilms, createFilm, @@ -76,4 +95,5 @@ module.exports = { deleteFilmById, updateFilmById, getFilmByDirector, + patchFilmById, }; diff --git a/src/routers/films.js b/src/routers/films.js index 7cdf5f8..dc180a9 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -7,6 +7,7 @@ const { deleteFilmById, updateFilmById, getFilmByDirector, + patchFilmById } = require("../controllers/filmsControllers.js"); filmsRouter.get("/", (req, res) => { @@ -20,5 +21,6 @@ filmsRouter.post("/", createFilm); filmsRouter.get("/:id", getFilmById); filmsRouter.delete("/:id", deleteFilmById); filmsRouter.put("/:id", updateFilmById); +filmsRouter.patch("/:id", patchFilmById) module.exports = filmsRouter; From 449fbb25c1c87d695d95711bdecb34a2b3369de9 Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:40:52 +0100 Subject: [PATCH 16/18] Throw error finding book that don't exist --- src/controllers/booksControllers.js | 8 ++++++++ src/routers/books.js | 25 +++++++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js index eb9e310..3b59021 100644 --- a/src/controllers/booksControllers.js +++ b/src/controllers/booksControllers.js @@ -1,6 +1,11 @@ const data = require("../../data/index.js"); const books = data.books; let idCounter = 5; +const { + MissingFieldsError, + DataAlreadyExistsError, + DataNotFoundError, + } = require("../errors/errors.js"); function getAllBooks(req, res) { res.status(200).json({ books }); @@ -15,6 +20,9 @@ function createBook(req, res) { function getBookById(req, res) { const bookId = Number(req.params.id) const book = books.find((book) => book.id === bookId) + if (!book) { + throw new DataNotFoundError('A book the provided ID does not exist') + } res.status(200).json({ book }) } diff --git a/src/routers/books.js b/src/routers/books.js index 21edff8..c36645f 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,12 +1,17 @@ -const express = require('express') -const booksRouter = express.Router() -const { getAllBooks, createBook, getBookById, deleteBookById, updateBookById } = require('../controllers/booksControllers.js') +const express = require("express"); +const booksRouter = express.Router(); +const { + getAllBooks, + createBook, + getBookById, + deleteBookById, + updateBookById, +} = require("../controllers/booksControllers.js"); +booksRouter.get("/", getAllBooks); +booksRouter.post("/", createBook); +booksRouter.get("/:id", getBookById); +booksRouter.delete("/:id", deleteBookById); +booksRouter.put("/:id", updateBookById); -booksRouter.get("/", getAllBooks) -booksRouter.post("/", createBook) -booksRouter.get("/:id", getBookById) -booksRouter.delete("/:id", deleteBookById) -booksRouter.put("/:id", updateBookById) - -module.exports = booksRouter \ No newline at end of file +module.exports = booksRouter; From db3e65c5dd1ad59ba2f14a49632d9c13d54c03cb Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:48:03 +0100 Subject: [PATCH 17/18] Errors thrown for ALL KINDS of book problems --- src/controllers/booksControllers.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/controllers/booksControllers.js b/src/controllers/booksControllers.js index 3b59021..4c2f9a1 100644 --- a/src/controllers/booksControllers.js +++ b/src/controllers/booksControllers.js @@ -13,6 +13,12 @@ function getAllBooks(req, res) { function createBook(req, res) { const book = req.body + if (!book.title || !book.type || !book.author) { + throw new MissingFieldsError('Missing fields in request body') + } + if (books.find((b) => b.title === book.title)) { + throw new DataAlreadyExistsError('A book with the provided title already exists') + } books.push(book) res.status(201).json({ book }) } @@ -29,6 +35,9 @@ function getBookById(req, res) { function deleteBookById(req, res) { const bookId = Number(req.params.id) const book = books.find((book) => book.id === bookId) + if (!book) { + throw new DataNotFoundError('A book the provided ID does not exist') + } const index = books.indexOf(book) books.splice(index, 1) res.status(200).json({ book }) @@ -36,8 +45,19 @@ function deleteBookById(req, res) { function updateBookById(req, res) { const updatedParams = req.body + if (!updatedParams.title || !updatedParams.type || !updatedParams.author) { + throw new MissingFieldsError('Missing fields in request body') + } const bookId = Number(req.params.id) const book = books.find((book) => book.id === bookId) + if (!book) { + throw new DataNotFoundError('A book the provided ID does not exist') + } + + if (books.find((b) => b.title === updatedParams.title)) { + throw new DataAlreadyExistsError('A book with the provided title already exists') + + } Object.assign(book, updatedParams) res.status(200).json({ book }) } From 9504df580d9c728528995f1fd1b2ba00a5ee02be Mon Sep 17 00:00:00 2001 From: Will Baxter Date: Tue, 18 Jun 2024 16:50:55 +0100 Subject: [PATCH 18/18] Refactored patch requests to use same function as put in films API --- src/controllers/filmsControllers.js | 20 -------------------- src/routers/films.js | 3 +-- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js index c637ea2..bc06a66 100644 --- a/src/controllers/filmsControllers.js +++ b/src/controllers/filmsControllers.js @@ -69,25 +69,6 @@ function getFilmByDirector(req, res) { res.status(200).json({ films: filteredFilms }); } -function patchFilmById(req, res) { - const filmId = Number(req.params.id); - const updatedParameters = req.body; - if (!updatedParameters.title && !updatedParameters.director) { - throw new MissingFieldsError("Missing fields in request body"); - } - const film = films.find((film) => film.id === filmId); - if (!film) { - throw new DataNotFoundError("A film with provided ID does not exist"); - } - if (films.find((film) => film.title === updatedParameters.title)) { - throw new DataAlreadyExistsError( - "A film with the provided title already exists" - ); - } - Object.assign(film, updatedParameters); - res.status(200).json({ film }); -} - module.exports = { getAllFilms, createFilm, @@ -95,5 +76,4 @@ module.exports = { deleteFilmById, updateFilmById, getFilmByDirector, - patchFilmById, }; diff --git a/src/routers/films.js b/src/routers/films.js index dc180a9..3b0ca2a 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -7,7 +7,6 @@ const { deleteFilmById, updateFilmById, getFilmByDirector, - patchFilmById } = require("../controllers/filmsControllers.js"); filmsRouter.get("/", (req, res) => { @@ -21,6 +20,6 @@ filmsRouter.post("/", createFilm); filmsRouter.get("/:id", getFilmById); filmsRouter.delete("/:id", deleteFilmById); filmsRouter.put("/:id", updateFilmById); -filmsRouter.patch("/:id", patchFilmById) +filmsRouter.patch("/:id", updateFilmById); module.exports = filmsRouter;