diff --git a/package.json b/package.json index c63bc01..abca99c 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,10 @@ "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", + "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/booksControllers.js b/src/controllers/booksControllers.js new file mode 100644 index 0000000..4c2f9a1 --- /dev/null +++ b/src/controllers/booksControllers.js @@ -0,0 +1,65 @@ +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 }); +} + +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 }) +} + +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 }) +} + +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 }) +} + +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 }) +} + +module.exports = { getAllBooks, createBook, getBookById, deleteBookById, updateBookById }; diff --git a/src/controllers/filmsControllers.js b/src/controllers/filmsControllers.js new file mode 100644 index 0000000..bc06a66 --- /dev/null +++ b/src/controllers/filmsControllers.js @@ -0,0 +1,79 @@ +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 }); +} + +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++; + res.status(201).json({ film }); +} + +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 }); +} + +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 }); +} + +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 }); +} + +module.exports = { + getAllFilms, + createFilm, + getFilmById, + deleteFilmById, + updateFilmById, + getFilmByDirector, +}; diff --git a/src/controllers/usersControllers.js b/src/controllers/usersControllers.js new file mode 100644 index 0000000..216d313 --- /dev/null +++ b/src/controllers/usersControllers.js @@ -0,0 +1,63 @@ +const data = require("../../data/index.js"); +const users = data.users; +let idCounter = 4 +const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = require("../errors/errors.js") + +function getAllUsers(req, res) { + res.status(200).json({ users }); +} + +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++ + res.status(201).json({ user: newUser}) +} + +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 }) +} + +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 }) +} + +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 }) +} + +module.exports = { getAllUsers, createUser, getUserById, deleteUser, updateUser }; diff --git a/src/errors/errors.js b/src/errors/errors.js new file mode 100644 index 0000000..5875e75 --- /dev/null +++ b/src/errors/errors.js @@ -0,0 +1,5 @@ +class MissingFieldsError extends Error {} +class DataAlreadyExistsError extends Error {} +class DataNotFoundError extends Error {} + +module.exports = { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError} \ No newline at end of file diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..c36645f 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,17 @@ -// Import data here... +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); -// Write routes here... +module.exports = booksRouter; diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..3b0ca2a 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,25 @@ +const express = require("express"); +const filmsRouter = express.Router(); +const { + getAllFilms, + createFilm, + getFilmById, + deleteFilmById, + updateFilmById, + getFilmByDirector, +} = require("../controllers/filmsControllers.js"); + +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); +filmsRouter.patch("/:id", updateFilmById); + +module.exports = filmsRouter; 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..19ecde6 100644 --- a/src/server.js +++ b/src/server.js @@ -10,9 +10,42 @@ app.use(express.json()); app.use(morgan("dev")); // REQUIRE ROUTERS -const usersRouter = require("./routers/users"); +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) + +// ADD ERRORS +const { MissingFieldsError, DataAlreadyExistsError, DataNotFoundError } = 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 + }) + } + + if (error instanceof DataNotFoundError) { + return res.status(404).json({ + error: error.message + }) + } + res.status(500).json({ + message: 'Something went wrong' + }) +}) module.exports = app