From ef70d3b99c0e118b3d7cf0ffa192eb5f9ffd0235 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 12:55:14 +0200 Subject: [PATCH 01/11] add get, put and delete functions for users --- src/controllers/users/usersController.js | 43 ++++++++++++++++++++++++ src/domain/users/usersRepository.js | 24 +++++++++++++ src/routers/users.js | 13 +++++++ src/server.js | 2 +- 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/controllers/users/usersController.js create mode 100644 src/domain/users/usersRepository.js diff --git a/src/controllers/users/usersController.js b/src/controllers/users/usersController.js new file mode 100644 index 0000000..e5e279c --- /dev/null +++ b/src/controllers/users/usersController.js @@ -0,0 +1,43 @@ +const { getAllUsers, newUser, getUserById, deleteUserById } = require("../../domain/users/usersRepository") + +let idCounter = 4 + +const getAll = (req, res) => { + const users = getAllUsers() + + res.json({users}) +} + +const createUser = (req, res) => { + const user = req.body + + user.id = idCounter + newUser(user) + + idCounter++ + + res.status(201).json({user}) +} + +const findUser = (req, res) => { + const userID = Number(req.params.id) + const user = getUserById(userID) + + res.json({user}) +} + +const deleteUser = (req, res) => { + const userID = Number(req.params.id) + const user = getUserById(userID) + + deleteUserById(userID) + + res.json({user}) +} + +module.exports = { + getAll, + createUser, + findUser, + deleteUser +} \ No newline at end of file diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js new file mode 100644 index 0000000..850ad97 --- /dev/null +++ b/src/domain/users/usersRepository.js @@ -0,0 +1,24 @@ +let { users } = require("../../../data/index") + +function getAllUsers() { + return users +} + +function newUser(user) { + users.push(user) +} + +function getUserById(id) { + return users.find((user) => user.id === id) +} + +function deleteUserById(id) { + users = users.filter((user) => user.id !== id) +} + +module.exports = { + getAllUsers, + newUser, + getUserById, + deleteUserById +} \ No newline at end of file diff --git a/src/routers/users.js b/src/routers/users.js index e69de29..b987793 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -0,0 +1,13 @@ +const express = require('express') +const { getAll, createUser, findUser, deleteUser } = require('../controllers/users/usersController') +const router = express.Router() + +router.get('/', getAll) + +router.post('/', createUser) + +router.get('/:id', findUser) + +router.delete('/:id', deleteUser) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index 715321f..4c97071 100644 --- a/src/server.js +++ b/src/server.js @@ -13,6 +13,6 @@ app.use(morgan("dev")); const usersRouter = require("./routers/users"); // ADD ROUTERS TO APP - +app.use('/users', usersRouter) module.exports = app From cdfccba999d0fd4575dded15eb0d1d6d34751d1a Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 13:01:53 +0200 Subject: [PATCH 02/11] add update user by id functions --- src/controllers/users/usersController.js | 16 ++++++++++++++-- src/domain/users/usersRepository.js | 7 ++++++- src/routers/users.js | 4 +++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/controllers/users/usersController.js b/src/controllers/users/usersController.js index e5e279c..2af2d82 100644 --- a/src/controllers/users/usersController.js +++ b/src/controllers/users/usersController.js @@ -1,4 +1,4 @@ -const { getAllUsers, newUser, getUserById, deleteUserById } = require("../../domain/users/usersRepository") +const { getAllUsers, newUser, getUserById, deleteUserById, updateUserById } = require("../../domain/users/usersRepository") let idCounter = 4 @@ -35,9 +35,21 @@ const deleteUser = (req, res) => { res.json({user}) } +const updateUser = (req, res) => { + const newUserInfo = req.body + const userID = Number(req.params.id) + + newUserInfo.id = userID + + updateUserById(newUserInfo) + + res.json({user: newUserInfo}) +} + module.exports = { getAll, createUser, findUser, - deleteUser + deleteUser, + updateUser } \ No newline at end of file diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js index 850ad97..69d3473 100644 --- a/src/domain/users/usersRepository.js +++ b/src/domain/users/usersRepository.js @@ -16,9 +16,14 @@ function deleteUserById(id) { users = users.filter((user) => user.id !== id) } +function updateUserById(updatedUser) { + Object.assign(users, updatedUser) +} + module.exports = { getAllUsers, newUser, getUserById, - deleteUserById + deleteUserById, + updateUserById } \ No newline at end of file diff --git a/src/routers/users.js b/src/routers/users.js index b987793..5b0e9f7 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -1,5 +1,5 @@ const express = require('express') -const { getAll, createUser, findUser, deleteUser } = require('../controllers/users/usersController') +const { getAll, createUser, findUser, deleteUser, updateUser } = require('../controllers/users/usersController') const router = express.Router() router.get('/', getAll) @@ -10,4 +10,6 @@ router.get('/:id', findUser) router.delete('/:id', deleteUser) +router.put('/:id', updateUser) + module.exports = router \ No newline at end of file From 1d444c7fce78da72e1512f0822f51d1c4d99bc4f Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 13:45:23 +0200 Subject: [PATCH 03/11] add functions for films --- src/controllers/films/filmsController.js | 56 ++++++++++++++++++++++++ src/domain/films/filmsRepository.js | 29 ++++++++++++ src/domain/users/usersRepository.js | 2 +- src/routers/films.js | 16 +++++++ src/server.js | 2 + 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/controllers/films/filmsController.js create mode 100644 src/domain/films/filmsRepository.js diff --git a/src/controllers/films/filmsController.js b/src/controllers/films/filmsController.js new file mode 100644 index 0000000..0515e07 --- /dev/null +++ b/src/controllers/films/filmsController.js @@ -0,0 +1,56 @@ +const { getAllFilms, newFilm, getFilmById, deleteFilmById, updateFilmById } = require("../../domain/films/filmsRepository") + + +let idCounter = 5 + +const getAll = (req, res) => { + const films = getAllFilms() + + res.json({films}) +} + +const createFilm = (req, res) => { + const film = req.body + + film.id = idCounter + newFilm(film) + + idCounter++ + + res.status(201).json({film}) +} + +const findFilm = (req, res) => { + const filmID = Number(req.params.id) + const film = getFilmById(filmID) + + res.json({film}) +} + +const deleteFilm = (req, res) => { + const filmID = Number(req.params.id) + const film = getFilmById(filmID) + + deleteFilmById(filmID) + + res.json({film}) +} + +const updateFilm = (req, res) => { + const newFilmInfo = req.body + const filmID = Number(req.params.id) + + newFilmInfo.id = filmID + + updateFilmById(filmID) + + res.json({film: newFilmInfo}) +} + +module.exports = { + getAll, + createFilm, + findFilm, + deleteFilm, + updateFilm +} \ No newline at end of file diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js new file mode 100644 index 0000000..22dcd94 --- /dev/null +++ b/src/domain/films/filmsRepository.js @@ -0,0 +1,29 @@ +let { films } = require("../../../data/index.js") + +function getAllFilms() { + return films +} + +function newFilm(film) { + films.push(film) +} + +function getFilmById(id) { + return films.find((film) => film.id === id) +} + +function deleteFilmById(id) { + films = films.filter((film) => film.id !== id) +} + +function updateFilmById(updatedFilm) { + Object.assign(films, updatedFilm) +} + +module.exports = { + getAllFilms, + newFilm, + getFilmById, + deleteFilmById, + updateFilmById +} \ No newline at end of file diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js index 69d3473..0b4b8c5 100644 --- a/src/domain/users/usersRepository.js +++ b/src/domain/users/usersRepository.js @@ -1,4 +1,4 @@ -let { users } = require("../../../data/index") +let { users } = require("../../../data/index.js") function getAllUsers() { return users diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..0610e58 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,16 @@ +const express = require('express') +const { getAll, createFilm, findFilm, deleteFilm, updateFilm } = require('../controllers/films/filmsController') + +const router = express.Router() + +router.get('/', getAll) + +router.post('/', createFilm) + +router.get('/:id', findFilm) + +router.delete('/:id', deleteFilm) + +router.put('/:id', updateFilm) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index 4c97071..f429c55 100644 --- a/src/server.js +++ b/src/server.js @@ -11,8 +11,10 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); +const filmsRouter = require('./routers/films') // ADD ROUTERS TO APP app.use('/users', usersRouter) +app.use('/films', filmsRouter) module.exports = app From 1e6e3b2f5eb37aa1f67bc0aa5c8daa65179f9bc8 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 13:55:13 +0200 Subject: [PATCH 04/11] add books functions --- src/controllers/books/booksController.js | 55 ++++++++++++++++++++++++ src/controllers/films/filmsController.js | 1 - src/domain/books/booksRepository.js | 29 +++++++++++++ src/routers/books.js | 16 ++++++- src/server.js | 2 + 5 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 src/controllers/books/booksController.js create mode 100644 src/domain/books/booksRepository.js diff --git a/src/controllers/books/booksController.js b/src/controllers/books/booksController.js new file mode 100644 index 0000000..f64a451 --- /dev/null +++ b/src/controllers/books/booksController.js @@ -0,0 +1,55 @@ +const { getAllBooks, newBook, getBookById, deleteBookById, updateBookById } = require("../../domain/books/booksRepository") + +let idCounter = 5 + +const getAll = (req, res) => { + const books = getAllBooks() + + res.json({books}) +} + +const createBook = (req, res) => { + const book = req.body + + book.id = idCounter + newBook(book) + + idCounter++ + + res.status(201).json({book}) +} + +const findBook = (req, res) => { + const bookID = Number(req.params.id) + const book = getBookById(bookID) + + res.json({book}) +} + +const deleteBook = (req, res) => { + const bookID = Number(req.params.id) + const book = getBookById(bookID) + + deleteBookById(bookID) + + res.json({book}) +} + +const updateBook = (req, res) => { + const newBookInfo = req.body + const bookID = Number(req.params.id) + + newBookInfo.id = bookID + + updateBookById(bookID) + + res.json({book: newBookInfo}) +} + +module.exports = { + getAll, + createBook, + findBook, + deleteBook, + updateBook +} \ No newline at end of file diff --git a/src/controllers/films/filmsController.js b/src/controllers/films/filmsController.js index 0515e07..185307b 100644 --- a/src/controllers/films/filmsController.js +++ b/src/controllers/films/filmsController.js @@ -1,6 +1,5 @@ const { getAllFilms, newFilm, getFilmById, deleteFilmById, updateFilmById } = require("../../domain/films/filmsRepository") - let idCounter = 5 const getAll = (req, res) => { diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js new file mode 100644 index 0000000..cac4ed9 --- /dev/null +++ b/src/domain/books/booksRepository.js @@ -0,0 +1,29 @@ +let { books } = require("../../../data/index.js") + +function getAllBooks() { + return books +} + +function newBook(book) { + books.push(book) +} + +function getBookById(id) { + return books.find((book) => book.id === id) +} + +function deleteBookById(id) { + books = books.filter((book) => book.id !== id) +} + +function updateBookById(updatedBook) { + Object.assign(books, updatedBook) +} + +module.exports = { + getAllBooks, + newBook, + getBookById, + deleteBookById, + updateBookById +} \ No newline at end of file diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..4fa4a33 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,16 @@ -// Import data here... +const express = require('express') +const { getAll, createBook, findBook, deleteBook, updateBook } = require('../controllers/books/booksController') +const router = express.Router() -// Write routes here... +router.get('/', getAll) + +router.post('/', createBook) + +router.get('/:id', findBook) + +router.delete('/:id', deleteBook) + +router.put('/:id', updateBook) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index f429c55..b06ffa3 100644 --- a/src/server.js +++ b/src/server.js @@ -12,9 +12,11 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); const filmsRouter = require('./routers/films') +const booksRouter = require('./routers/books') // ADD ROUTERS TO APP app.use('/users', usersRouter) app.use('/films', filmsRouter) +app.use('/books', booksRouter) module.exports = app From b8aa689b23207799589e66d15bf68f021643eaaa Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 14:19:53 +0200 Subject: [PATCH 05/11] add error handling for unknown id --- src/controllers/books/booksController.js | 2 +- src/controllers/films/filmsController.js | 2 +- src/controllers/users/usersController.js | 2 +- src/domain/books/booksRepository.js | 23 +++++++++++++++++++++-- src/domain/films/filmsRepository.js | 23 +++++++++++++++++++++-- src/domain/users/usersRepository.js | 23 +++++++++++++++++++++-- src/errors/notFoundError.js | 5 +++++ src/server.js | 15 ++++++++++++++- 8 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 src/errors/notFoundError.js diff --git a/src/controllers/books/booksController.js b/src/controllers/books/booksController.js index f64a451..1e968c7 100644 --- a/src/controllers/books/booksController.js +++ b/src/controllers/books/booksController.js @@ -41,7 +41,7 @@ const updateBook = (req, res) => { newBookInfo.id = bookID - updateBookById(bookID) + updateBookById(bookID, newBookInfo) res.json({book: newBookInfo}) } diff --git a/src/controllers/films/filmsController.js b/src/controllers/films/filmsController.js index 185307b..90ff26f 100644 --- a/src/controllers/films/filmsController.js +++ b/src/controllers/films/filmsController.js @@ -41,7 +41,7 @@ const updateFilm = (req, res) => { newFilmInfo.id = filmID - updateFilmById(filmID) + updateFilmById(filmID, newFilmInfo) res.json({film: newFilmInfo}) } diff --git a/src/controllers/users/usersController.js b/src/controllers/users/usersController.js index 2af2d82..cd1e8c7 100644 --- a/src/controllers/users/usersController.js +++ b/src/controllers/users/usersController.js @@ -41,7 +41,7 @@ const updateUser = (req, res) => { newUserInfo.id = userID - updateUserById(newUserInfo) + updateUserById(userID, newUserInfo) res.json({user: newUserInfo}) } diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js index cac4ed9..7eb4172 100644 --- a/src/domain/books/booksRepository.js +++ b/src/domain/books/booksRepository.js @@ -1,4 +1,5 @@ let { books } = require("../../../data/index.js") +const NotFoundError = require("../../errors/notFoundError.js") function getAllBooks() { return books @@ -9,14 +10,32 @@ function newBook(book) { } function getBookById(id) { - return books.find((book) => book.id === id) + const found = books.find((book) => book.id === id) + + if (!found) { + throw new NotFoundError('A book the provided ID does not exist') + } + + return found } function deleteBookById(id) { + const found = getBookById(id) + + if (!found) { + throw new NotFoundError('A book the provided ID does not exist') + } + books = books.filter((book) => book.id !== id) } -function updateBookById(updatedBook) { +function updateBookById(id, updatedBook) { + const found = getBookById(id) + + if (!found) { + throw new NotFoundError('A book the provided ID does not exist') + } + Object.assign(books, updatedBook) } diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index 22dcd94..36692b2 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -1,4 +1,5 @@ let { films } = require("../../../data/index.js") +const NotFoundError = require("../../errors/notFoundError.js") function getAllFilms() { return films @@ -9,14 +10,32 @@ function newFilm(film) { } function getFilmById(id) { - return films.find((film) => film.id === id) + const found = films.find((film) => film.id === id) + + if (!found) { + throw new NotFoundError('A film with provided ID does not exist') + } + + return found } function deleteFilmById(id) { + const found = films.find((film) => film.id === id) + + if (!found) { + throw new NotFoundError('A film with provided ID does not exist') + } + films = films.filter((film) => film.id !== id) } -function updateFilmById(updatedFilm) { +function updateFilmById(id, updatedFilm) { + const found = films.find((film) => film.id === id) + + if (!found) { + throw new NotFoundError('A film with provided ID does not exist') + } + Object.assign(films, updatedFilm) } diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js index 0b4b8c5..8bef745 100644 --- a/src/domain/users/usersRepository.js +++ b/src/domain/users/usersRepository.js @@ -1,4 +1,5 @@ let { users } = require("../../../data/index.js") +const NotFoundError = require("../../errors/notFoundError.js") function getAllUsers() { return users @@ -9,14 +10,32 @@ function newUser(user) { } function getUserById(id) { - return users.find((user) => user.id === id) + const found = users.find((user) => user.id === id) + + if (!found) { + throw new NotFoundError('A user with the provided ID does not exist') + } + + return found } function deleteUserById(id) { + const found = users.find((user) => user.id === id) + + if (!found) { + throw new NotFoundError('A user with the provided ID does not exist') + } + users = users.filter((user) => user.id !== id) } -function updateUserById(updatedUser) { +function updateUserById(id, updatedUser) { + const found = users.find((user) => user.id === id) + + if (!found) { + throw new NotFoundError('A user with the provided ID does not exist') + } + Object.assign(users, updatedUser) } diff --git a/src/errors/notFoundError.js b/src/errors/notFoundError.js new file mode 100644 index 0000000..0a1f7ab --- /dev/null +++ b/src/errors/notFoundError.js @@ -0,0 +1,5 @@ +class NotFoundError extends Error { + +} + +module.exports = NotFoundError \ No newline at end of file diff --git a/src/server.js b/src/server.js index b06ffa3..df6cfa7 100644 --- a/src/server.js +++ b/src/server.js @@ -12,11 +12,24 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); const filmsRouter = require('./routers/films') -const booksRouter = require('./routers/books') +const booksRouter = require('./routers/books'); +const NotFoundError = require("./errors/notFoundError"); // ADD ROUTERS TO APP app.use('/users', usersRouter) app.use('/films', filmsRouter) app.use('/books', booksRouter) +app.use((error, req, res, next) => { + if (error instanceof NotFoundError) { + return res.status(404).json({ + error: error.message + }) + } + + res.status(500).json({ + message: 'Something went wrong' + }) +}) + module.exports = app From 69d228644d24f7b9b07fe906a6c053d07f25ddca Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 14:33:44 +0200 Subject: [PATCH 06/11] add error handling for missing fields in body --- src/domain/books/booksRepository.js | 21 +++++++++++++++++++++ src/domain/films/filmsRepository.js | 23 ++++++++++++++++++++++- src/domain/users/usersRepository.js | 23 ++++++++++++++++++++++- src/errors/missingFieldsError.js | 5 +++++ src/server.js | 7 +++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/errors/missingFieldsError.js diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js index 7eb4172..dc87918 100644 --- a/src/domain/books/booksRepository.js +++ b/src/domain/books/booksRepository.js @@ -1,4 +1,5 @@ let { books } = require("../../../data/index.js") +const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") function getAllBooks() { @@ -6,6 +7,10 @@ function getAllBooks() { } function newBook(book) { + if (!verifyBookProperties(book)) { + throw new MissingFieldsError('Missing fields in request body') + } + books.push(book) } @@ -36,9 +41,25 @@ function updateBookById(id, updatedBook) { throw new NotFoundError('A book the provided ID does not exist') } + if (!verifyBookProperties(updatedBook)) { + throw new MissingFieldsError('Missing fields in request body') + } + Object.assign(books, updatedBook) } +function verifyBookProperties(object) { + const neededProperties = ['title', 'type', 'author'] + + for (const item of neededProperties) { + if (object[item] === undefined) { + return false + } + } + + return true +} + module.exports = { getAllBooks, newBook, diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index 36692b2..43c42e0 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -1,4 +1,5 @@ let { films } = require("../../../data/index.js") +const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") function getAllFilms() { @@ -6,6 +7,10 @@ function getAllFilms() { } function newFilm(film) { + if (!verifyFilmProperties(film)) { + throw new MissingFieldsError('Missing fields in request body') + } + films.push(film) } @@ -35,10 +40,26 @@ function updateFilmById(id, updatedFilm) { if (!found) { throw new NotFoundError('A film with provided ID does not exist') } - + + if (!verifyFilmProperties(updatedFilm)) { + throw new MissingFieldsError('Missing fields in request body') + } + Object.assign(films, updatedFilm) } +function verifyFilmProperties(object) { + const neededProperties = ['title', 'director'] + + for (const item of neededProperties) { + if (object[item] === undefined) { + return false + } + } + + return true +} + module.exports = { getAllFilms, newFilm, diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js index 8bef745..3fe8aae 100644 --- a/src/domain/users/usersRepository.js +++ b/src/domain/users/usersRepository.js @@ -1,4 +1,5 @@ let { users } = require("../../../data/index.js") +const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") function getAllUsers() { @@ -6,6 +7,10 @@ function getAllUsers() { } function newUser(user) { + if (!verifyUserProperties(user)) { + throw new MissingFieldsError('Missing fields in request body') + } + users.push(user) } @@ -35,10 +40,26 @@ function updateUserById(id, updatedUser) { if (!found) { throw new NotFoundError('A user with the provided ID does not exist') } - + + if (!verifyUserProperties(updatedUser)) { + throw new MissingFieldsError('Missing fields in request body') + } + Object.assign(users, updatedUser) } +function verifyUserProperties(object) { + const neededProperties = 'email' + + if (object[neededProperties] === undefined) { + return false + } + + return true +} + + + module.exports = { getAllUsers, newUser, diff --git a/src/errors/missingFieldsError.js b/src/errors/missingFieldsError.js new file mode 100644 index 0000000..7359cc1 --- /dev/null +++ b/src/errors/missingFieldsError.js @@ -0,0 +1,5 @@ +class MissingFieldsError extends Error { + +} + +module.exports = MissingFieldsError \ No newline at end of file diff --git a/src/server.js b/src/server.js index df6cfa7..9fe97bc 100644 --- a/src/server.js +++ b/src/server.js @@ -14,6 +14,7 @@ const usersRouter = require("./routers/users"); const filmsRouter = require('./routers/films') const booksRouter = require('./routers/books'); const NotFoundError = require("./errors/notFoundError"); +const MissingFieldsError = require("./errors/missingFieldsError"); // ADD ROUTERS TO APP app.use('/users', usersRouter) @@ -27,6 +28,12 @@ app.use((error, req, res, next) => { }) } + if (error instanceof MissingFieldsError) { + return res.status(400).json({ + error: error.message + }) + } + res.status(500).json({ message: 'Something went wrong' }) From 2f0855ba40122db5e02e85a8c13e03f4266c83bd Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 14:57:31 +0200 Subject: [PATCH 07/11] add error throwing for already existing properties --- src/domain/books/booksRepository.js | 23 ++++++++++++++++++-- src/domain/films/filmsRepository.js | 19 +++++++++++++++++ src/domain/users/usersRepository.js | 19 ++++++++++++++++- src/errors/alreadyExistsError.js | 5 +++++ src/server.js | 33 +++++++++++++++++------------ 5 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 src/errors/alreadyExistsError.js diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js index dc87918..1f56690 100644 --- a/src/domain/books/booksRepository.js +++ b/src/domain/books/booksRepository.js @@ -1,4 +1,5 @@ let { books } = require("../../../data/index.js") +const AlreadyExistsError = require("../../errors/alreadyExistsError.js") const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") @@ -11,6 +12,10 @@ function newBook(book) { throw new MissingFieldsError('Missing fields in request body') } + if (verifyBook(book)) { + throw new AlreadyExistsError('A book with the provided title already exists') + } + books.push(book) } @@ -35,14 +40,18 @@ function deleteBookById(id) { } function updateBookById(id, updatedBook) { + if (!verifyBookProperties(updatedBook)) { + throw new MissingFieldsError('Missing fields in request body') + } + const found = getBookById(id) if (!found) { throw new NotFoundError('A book the provided ID does not exist') } - if (!verifyBookProperties(updatedBook)) { - throw new MissingFieldsError('Missing fields in request body') + if (verifyBook(updatedBook)) { + throw new AlreadyExistsError('A book with the provided title already exists') } Object.assign(books, updatedBook) @@ -60,6 +69,16 @@ function verifyBookProperties(object) { return true } +function verifyBook(object) { + const foundBook = books.find((book) => book.title === object.title) + + if (foundBook) { + return true + } + + return false +} + module.exports = { getAllBooks, newBook, diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index 43c42e0..7651125 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -1,4 +1,5 @@ let { films } = require("../../../data/index.js") +const AlreadyExistsError = require("../../errors/alreadyExistsError.js") const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") @@ -11,6 +12,10 @@ function newFilm(film) { throw new MissingFieldsError('Missing fields in request body') } + if (verifyFilm(film)) { + throw new AlreadyExistsError('A film with the provided title already exists') + } + films.push(film) } @@ -45,6 +50,10 @@ function updateFilmById(id, updatedFilm) { throw new MissingFieldsError('Missing fields in request body') } + if (verifyFilm(updatedFilm)) { + throw new AlreadyExistsError('A film with the provided title already exists') + } + Object.assign(films, updatedFilm) } @@ -60,6 +69,16 @@ function verifyFilmProperties(object) { return true } +function verifyFilm(object) { + const foundFilm = films.find((film) => film.title === object.title) + + if (foundFilm) { + return true + } + + return false +} + module.exports = { getAllFilms, newFilm, diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js index 3fe8aae..a6a4aa0 100644 --- a/src/domain/users/usersRepository.js +++ b/src/domain/users/usersRepository.js @@ -1,6 +1,7 @@ let { users } = require("../../../data/index.js") const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") +const AlreadyExistsError = require("../../errors/alreadyExistsError.js") function getAllUsers() { return users @@ -11,6 +12,10 @@ function newUser(user) { throw new MissingFieldsError('Missing fields in request body') } + if (verifyEmail(user)) { + throw new AlreadyExistsError('A user with the provided email already exists') + } + users.push(user) } @@ -45,6 +50,10 @@ function updateUserById(id, updatedUser) { throw new MissingFieldsError('Missing fields in request body') } + if (verifyEmail(updatedUser)) { + throw new AlreadyExistsError('A user with the provided email already exists') + } + Object.assign(users, updatedUser) } @@ -58,7 +67,15 @@ function verifyUserProperties(object) { return true } - +function verifyEmail(object) { + const foundEmail = users.find((user) => user.email === object.email) + + if (foundEmail) { + return true + } + + return false +} module.exports = { getAllUsers, diff --git a/src/errors/alreadyExistsError.js b/src/errors/alreadyExistsError.js new file mode 100644 index 0000000..42518a8 --- /dev/null +++ b/src/errors/alreadyExistsError.js @@ -0,0 +1,5 @@ +class AlreadyExistsError extends Error { + +} + +module.exports = AlreadyExistsError \ No newline at end of file diff --git a/src/server.js b/src/server.js index 9fe97bc..d933946 100644 --- a/src/server.js +++ b/src/server.js @@ -1,20 +1,21 @@ -const express = require("express"); -const app = express(); +const express = require("express") +const app = express() -const cors = require("cors"); -const morgan = require("morgan"); +const cors = require("cors") +const morgan = require("morgan") // SETUP MIDDLEWARE -app.use(cors()); -app.use(express.json()); -app.use(morgan("dev")); +app.use(cors()) +app.use(express.json()) +app.use(morgan("dev")) // REQUIRE ROUTERS -const usersRouter = require("./routers/users"); +const usersRouter = require("./routers/users") const filmsRouter = require('./routers/films') -const booksRouter = require('./routers/books'); -const NotFoundError = require("./errors/notFoundError"); -const MissingFieldsError = require("./errors/missingFieldsError"); +const booksRouter = require('./routers/books') +const NotFoundError = require("./errors/notFoundError") +const MissingFieldsError = require("./errors/missingFieldsError") +const AlreadyExistsError = require("./errors/alreadyExistsError") // ADD ROUTERS TO APP app.use('/users', usersRouter) @@ -22,14 +23,20 @@ app.use('/films', filmsRouter) app.use('/books', booksRouter) app.use((error, req, res, next) => { + if (error instanceof MissingFieldsError) { + return res.status(400).json({ + error: error.message + }) + } + if (error instanceof NotFoundError) { return res.status(404).json({ error: error.message }) } - if (error instanceof MissingFieldsError) { - return res.status(400).json({ + if (error instanceof AlreadyExistsError) { + return res.status(409).json({ error: error.message }) } From e96f6a5488751351ab18bd4ad97e04cfbb8d8fad Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 15:18:33 +0200 Subject: [PATCH 08/11] add function to filter films by director --- src/controllers/films/filmsController.js | 8 ++++++++ src/domain/films/filmsRepository.js | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/controllers/films/filmsController.js b/src/controllers/films/filmsController.js index 90ff26f..f6e66b3 100644 --- a/src/controllers/films/filmsController.js +++ b/src/controllers/films/filmsController.js @@ -3,6 +3,14 @@ const { getAllFilms, newFilm, getFilmById, deleteFilmById, updateFilmById } = re let idCounter = 5 const getAll = (req, res) => { + const director = req.query.director + + if (director) { + const filteredFilms = getAllFilms(director) + + return res.json({films: filteredFilms}) + } + const films = getAllFilms() res.json({films}) diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index 7651125..6791a61 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -3,7 +3,13 @@ const AlreadyExistsError = require("../../errors/alreadyExistsError.js") const MissingFieldsError = require("../../errors/missingFieldsError.js") const NotFoundError = require("../../errors/notFoundError.js") -function getAllFilms() { +function getAllFilms(director) { + if (director) { + console.log(director) + const filteredFilms = films.filter((film) => film.director === director) + return filteredFilms + } + return films } From 6e5944999218f996ba568151d3013d0a3cbe9c0a Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 15:41:37 +0200 Subject: [PATCH 09/11] add function to patch film --- src/controllers/films/filmsController.js | 16 ++++++++++++++-- src/domain/films/filmsRepository.js | 20 +++++++++++++++++++- src/routers/films.js | 4 +++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/controllers/films/filmsController.js b/src/controllers/films/filmsController.js index f6e66b3..2c96e54 100644 --- a/src/controllers/films/filmsController.js +++ b/src/controllers/films/filmsController.js @@ -1,4 +1,4 @@ -const { getAllFilms, newFilm, getFilmById, deleteFilmById, updateFilmById } = require("../../domain/films/filmsRepository") +const { getAllFilms, newFilm, getFilmById, deleteFilmById, updateFilmById, patchFilmById } = require("../../domain/films/filmsRepository") let idCounter = 5 @@ -54,10 +54,22 @@ const updateFilm = (req, res) => { res.json({film: newFilmInfo}) } +const update = (req, res) => { + const newFilmInfo = req.body + const filmID = Number(req.params.id) + + newFilmInfo.id = filmID + + const patchedFilm = patchFilmById(filmID, newFilmInfo) + + res.json({film: patchedFilm}) +} + module.exports = { getAll, createFilm, findFilm, deleteFilm, - updateFilm + updateFilm, + update } \ No newline at end of file diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index 6791a61..cb34a45 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -63,6 +63,23 @@ function updateFilmById(id, updatedFilm) { Object.assign(films, updatedFilm) } +function patchFilmById(id, updatedFilm) { + const found = films.find((film) => film.id === id) + const foundIndex = films.indexOf(found) + + if (!found) { + throw new NotFoundError('A film with provided ID does not exist') + } + + if (verifyFilm(updatedFilm)) { + throw new AlreadyExistsError('A film with the provided title already exists') + } + + Object.assign(films[foundIndex], updatedFilm) + + return films[foundIndex] +} + function verifyFilmProperties(object) { const neededProperties = ['title', 'director'] @@ -90,5 +107,6 @@ module.exports = { newFilm, getFilmById, deleteFilmById, - updateFilmById + updateFilmById, + patchFilmById } \ No newline at end of file diff --git a/src/routers/films.js b/src/routers/films.js index 0610e58..338c186 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -1,5 +1,5 @@ const express = require('express') -const { getAll, createFilm, findFilm, deleteFilm, updateFilm } = require('../controllers/films/filmsController') +const { getAll, createFilm, findFilm, deleteFilm, updateFilm, update } = require('../controllers/films/filmsController') const router = express.Router() @@ -13,4 +13,6 @@ router.delete('/:id', deleteFilm) router.put('/:id', updateFilm) +router.patch('/:id', update) + module.exports = router \ No newline at end of file From 7059ca95a4d35e717d0d4c1ffc3c649282e287ad Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 15:50:11 +0200 Subject: [PATCH 10/11] add function to patch books --- src/controllers/books/booksController.js | 16 ++++++++++++++-- src/domain/books/booksRepository.js | 22 ++++++++++++++++++++-- src/domain/films/filmsRepository.js | 1 - src/routers/books.js | 4 +++- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/controllers/books/booksController.js b/src/controllers/books/booksController.js index 1e968c7..45a5d42 100644 --- a/src/controllers/books/booksController.js +++ b/src/controllers/books/booksController.js @@ -1,4 +1,4 @@ -const { getAllBooks, newBook, getBookById, deleteBookById, updateBookById } = require("../../domain/books/booksRepository") +const { getAllBooks, newBook, getBookById, deleteBookById, updateBookById, patchBookById } = require("../../domain/books/booksRepository") let idCounter = 5 @@ -46,10 +46,22 @@ const updateBook = (req, res) => { res.json({book: newBookInfo}) } +const update = (req, res) => { + const newBookInfo = req.body + const bookID = Number(req.params.id) + + newBookInfo.id = bookID + + const patchedBook = patchBookById(bookID, newBookInfo) + + res.json({book: patchedBook}) +} + module.exports = { getAll, createBook, findBook, deleteBook, - updateBook + updateBook, + update } \ No newline at end of file diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js index 1f56690..7df9546 100644 --- a/src/domain/books/booksRepository.js +++ b/src/domain/books/booksRepository.js @@ -43,7 +43,7 @@ function updateBookById(id, updatedBook) { if (!verifyBookProperties(updatedBook)) { throw new MissingFieldsError('Missing fields in request body') } - + const found = getBookById(id) if (!found) { @@ -57,6 +57,23 @@ function updateBookById(id, updatedBook) { Object.assign(books, updatedBook) } +function patchBookById(id, updatedBook) { + const found = books.find((book) => book.id === id) + const foundIndex = books.indexOf(found) + + if (!found) { + throw new NotFoundError('A book the provided ID does not exist') + } + + if (verifyBook(updatedBook)) { + throw new AlreadyExistsError('A book with the provided title already exists') + } + + Object.assign(books[foundIndex], updatedBook) + + return books[foundIndex] +} + function verifyBookProperties(object) { const neededProperties = ['title', 'type', 'author'] @@ -84,5 +101,6 @@ module.exports = { newBook, getBookById, deleteBookById, - updateBookById + updateBookById, + patchBookById } \ No newline at end of file diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js index cb34a45..0142899 100644 --- a/src/domain/films/filmsRepository.js +++ b/src/domain/films/filmsRepository.js @@ -5,7 +5,6 @@ const NotFoundError = require("../../errors/notFoundError.js") function getAllFilms(director) { if (director) { - console.log(director) const filteredFilms = films.filter((film) => film.director === director) return filteredFilms } diff --git a/src/routers/books.js b/src/routers/books.js index 4fa4a33..7784a83 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,5 +1,5 @@ const express = require('express') -const { getAll, createBook, findBook, deleteBook, updateBook } = require('../controllers/books/booksController') +const { getAll, createBook, findBook, deleteBook, updateBook, update } = require('../controllers/books/booksController') const router = express.Router() @@ -13,4 +13,6 @@ router.delete('/:id', deleteBook) router.put('/:id', updateBook) +router.patch('/:id', update) + module.exports = router \ No newline at end of file From 897d4b0667405cd7767718db8b577168575ace39 Mon Sep 17 00:00:00 2001 From: Myrthe Dullaart Date: Tue, 18 Jun 2024 15:52:01 +0200 Subject: [PATCH 11/11] change put to patch in test --- test/api/extensions/books.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/api/extensions/books.spec.js b/test/api/extensions/books.spec.js index 4889b8f..66bd88f 100644 --- a/test/api/extensions/books.spec.js +++ b/test/api/extensions/books.spec.js @@ -70,7 +70,7 @@ describe("Books Extension Endpoint", () => { describe("PATCH /books", () => { it("will return 404 when updating a book that does not exist", async () => { - const response = await supertest(app).put("/books/999").send({ + const response = await supertest(app).patch("/books/999").send({ title: "test1", type: "test1", author: "test1", @@ -80,7 +80,7 @@ describe("Books Extension Endpoint", () => { expect(response.body.error).toEqual('A book the provided ID does not exist') }) it("will return 409 when updating a book with title that already exists", async () => { - const response = await supertest(app).put("/books/1").send({ + const response = await supertest(app).patch("/books/1").send({ title: "1984", type: "test1", author: "test1",