From 6296f5b15d4840f6daa97ae78ba2ac806601a44c Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 11:35:47 +0100 Subject: [PATCH 01/13] get movies --- .env.example | 6 ------ src/controllers/movie.js | 13 +++++++++++++ src/domains/movie.js | 8 ++++++++ src/routers/movie.js | 8 ++++++++ src/server.js | 3 +++ 5 files changed, 32 insertions(+), 6 deletions(-) delete mode 100644 .env.example create mode 100644 src/controllers/movie.js create mode 100644 src/domains/movie.js create mode 100644 src/routers/movie.js diff --git a/.env.example b/.env.example deleted file mode 100644 index 60f3a816..00000000 --- a/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -DATABASE_URL="YOUR_DB_URL" - -# We need the following URL environment variable for test purposes: -# - TEST_DATABASE_URL must be a **completely separate** database from any other used in this file - -TEST_DATABASE_URL="YOUR_TEST_DB_URL" diff --git a/src/controllers/movie.js b/src/controllers/movie.js new file mode 100644 index 00000000..9406e6cc --- /dev/null +++ b/src/controllers/movie.js @@ -0,0 +1,13 @@ +const { getAllMovies } = require('../domains/movie.js') + +const getAll = async (req, res) => { + + const allMovies = (await getAllMovies()).map(m => m) + res.status(200).json({ + movies: allMovies + }) +} + +module.exports = { + getAll +} \ No newline at end of file diff --git a/src/domains/movie.js b/src/domains/movie.js new file mode 100644 index 00000000..deabc6aa --- /dev/null +++ b/src/domains/movie.js @@ -0,0 +1,8 @@ +const prisma = require('../utils/prisma.js') + +const getAllMovies = async () => await prisma.movie.findMany() + + +module.exports = { + getAllMovies +} \ No newline at end of file diff --git a/src/routers/movie.js b/src/routers/movie.js new file mode 100644 index 00000000..6d35167c --- /dev/null +++ b/src/routers/movie.js @@ -0,0 +1,8 @@ +const express = require('express') +const { getAll } = require('../controllers/movie.js') + +const router = express.Router() + +router.get('/', getAll) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index 93d47a16..a64fd856 100644 --- a/src/server.js +++ b/src/server.js @@ -17,5 +17,8 @@ app.use(express.urlencoded({ extended: true })); const customerRouter = require('./routers/customer'); app.use('/customers', customerRouter); +const movieRouter = require('./routers/movie') +app.use('/movies', movieRouter) + module.exports = app From f7eaf920b1f2db3e46dbb4e9b50cf57c8d75260f Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 12:49:49 +0100 Subject: [PATCH 02/13] post/movies --- src/controllers/movie.js | 14 ++++++++++++-- src/domains/movie.js | 10 +++++++++- src/routers/movie.js | 3 ++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 9406e6cc..00b53a36 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,4 +1,5 @@ -const { getAllMovies } = require('../domains/movie.js') +const { getAllMovies, createMovie } = require('../domains/movie.js') + const getAll = async (req, res) => { @@ -8,6 +9,15 @@ const getAll = async (req, res) => { }) } +const addMovie = async (req, res) => { + const newMovie = (await createMovie(req)).map(m => m) + + res.status(201).json({ + movie: newMovie + }) +} + module.exports = { - getAll + getAll, + addMovie } \ No newline at end of file diff --git a/src/domains/movie.js b/src/domains/movie.js index deabc6aa..b26022a4 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -2,7 +2,15 @@ const prisma = require('../utils/prisma.js') const getAllMovies = async () => await prisma.movie.findMany() +const createMovie = async (req) => await prisma.movie.create({ + data: { + title: req.body.title, + runtimeMins: req.body.runtimeMins + } +}) + module.exports = { - getAllMovies + getAllMovies, + createMovie } \ No newline at end of file diff --git a/src/routers/movie.js b/src/routers/movie.js index 6d35167c..9e863ccf 100644 --- a/src/routers/movie.js +++ b/src/routers/movie.js @@ -1,8 +1,9 @@ const express = require('express') -const { getAll } = require('../controllers/movie.js') +const { getAll, addMovie } = require('../controllers/movie.js') const router = express.Router() router.get('/', getAll) +router.post('/', addMovie) module.exports = router \ No newline at end of file From e39e55fb271975beb8b93afdcae20fc980b876d5 Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 13:15:23 +0100 Subject: [PATCH 03/13] get/movies, post/movies refactored to include screenings --- src/controllers/movie.js | 2 +- src/domains/movie.js | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 00b53a36..67dd054b 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -10,7 +10,7 @@ const getAll = async (req, res) => { } const addMovie = async (req, res) => { - const newMovie = (await createMovie(req)).map(m => m) + const newMovie = await createMovie(req) res.status(201).json({ movie: newMovie diff --git a/src/domains/movie.js b/src/domains/movie.js index b26022a4..3a0d12ae 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -1,11 +1,18 @@ const prisma = require('../utils/prisma.js') -const getAllMovies = async () => await prisma.movie.findMany() +const getAllMovies = async () => await prisma.movie.findMany({ + include: { + screenings: true + } +}) const createMovie = async (req) => await prisma.movie.create({ data: { title: req.body.title, runtimeMins: req.body.runtimeMins + }, + include: { + screenings: true } }) From fb6558212e6f33e8b762b146b88269e338937cec Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 13:24:12 +0100 Subject: [PATCH 04/13] get/movies/id --- src/controllers/movie.js | 11 ++++++++++- src/routers/movie.js | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 67dd054b..50dc15be 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -17,7 +17,16 @@ const addMovie = async (req, res) => { }) } +const findByID = async (req, res) => { + const id = Number(req.params.id) + const found = (await getAllMovies()).find((m) => m.id === id) + res.status(200).json({ + movie: found + }) +} + module.exports = { getAll, - addMovie + addMovie, + findByID } \ No newline at end of file diff --git a/src/routers/movie.js b/src/routers/movie.js index 9e863ccf..21e43b52 100644 --- a/src/routers/movie.js +++ b/src/routers/movie.js @@ -1,9 +1,10 @@ const express = require('express') -const { getAll, addMovie } = require('../controllers/movie.js') +const { getAll, addMovie, findByID } = require('../controllers/movie.js') const router = express.Router() router.get('/', getAll) router.post('/', addMovie) +router.get('/:id', findByID) module.exports = router \ No newline at end of file From 9ecc1ba1310554d9b5c2d3d116780f30fbe8b2a4 Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 13:31:46 +0100 Subject: [PATCH 05/13] put/movies/id --- src/controllers/movie.js | 12 ++++++++++-- src/domains/movie.js | 16 +++++++++++++++- src/routers/movie.js | 3 ++- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 50dc15be..0910c447 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,4 +1,4 @@ -const { getAllMovies, createMovie } = require('../domains/movie.js') +const { getAllMovies, createMovie, updateMovie } = require('../domains/movie.js') const getAll = async (req, res) => { @@ -25,8 +25,16 @@ const findByID = async (req, res) => { }) } +const updateMovieByID = async (req, res) => { + const updatedMovie = await updateMovie(req) + res.status(201).json({ + movie: updatedMovie + }) +} + module.exports = { getAll, addMovie, - findByID + findByID, + updateMovieByID } \ No newline at end of file diff --git a/src/domains/movie.js b/src/domains/movie.js index 3a0d12ae..9a829000 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -16,8 +16,22 @@ const createMovie = async (req) => await prisma.movie.create({ } }) +const updateMovie = async (req) => await prisma.movie.update({ + where: { + id: Number(req.params.id) + }, + data: { + title: req.body.title, + runtimeMins: req.body.runtimeMins + }, + include: { + screenings: true + } +}) + module.exports = { getAllMovies, - createMovie + createMovie, + updateMovie } \ No newline at end of file diff --git a/src/routers/movie.js b/src/routers/movie.js index 21e43b52..8b3eeda5 100644 --- a/src/routers/movie.js +++ b/src/routers/movie.js @@ -1,10 +1,11 @@ const express = require('express') -const { getAll, addMovie, findByID } = require('../controllers/movie.js') +const { getAll, addMovie, findByID, updateMovieByID } = require('../controllers/movie.js') const router = express.Router() router.get('/', getAll) router.post('/', addMovie) router.get('/:id', findByID) +router.put('/:id', updateMovieByID) module.exports = router \ No newline at end of file From c820c608765c5f73676b984760e25783a4497f2c Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 13:53:58 +0100 Subject: [PATCH 06/13] put/customers --- src/controllers/customer.js | 14 ++++++++++++-- src/domains/customer.js | 22 +++++++++++++++++++++- src/routers/customer.js | 4 +++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 775cfb42..89ea1581 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,5 +1,6 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") -const { createCustomerDb } = require('../domains/customer.js') +const { createCustomerDb, updateCustomer } = require('../domains/customer.js') +const { customer } = require("../utils/prisma.js") const createCustomer = async (req, res) => { const { @@ -43,6 +44,15 @@ const createCustomer = async (req, res) => { } } + +const updateCustomerDetails = async (req, res) => { + const updatedCustomer = await updateCustomer(req) + res.status(201).json({ + customer: updatedCustomer + }) +} + module.exports = { - createCustomer + createCustomer, + updateCustomerDetails } diff --git a/src/domains/customer.js b/src/domains/customer.js index c7f315fd..9ff04a46 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -21,6 +21,26 @@ const createCustomerDb = async (name, phone, email) => await prisma.customer.cre } }) + +const updateCustomer = async (req) => await prisma.customer.update({ + where: { + id: Number(req.params.id) + }, + data: { + name: req.body.name, + contact: { + update: { + phone: req.body.phone, + email: req.body.email + } + } + }, + include: { + contact: true + } +}) + module.exports = { - createCustomerDb + createCustomerDb, + updateCustomer } diff --git a/src/routers/customer.js b/src/routers/customer.js index f14a87fc..d4211a61 100644 --- a/src/routers/customer.js +++ b/src/routers/customer.js @@ -1,7 +1,8 @@ const express = require("express"); const { createCustomer -} = require('../controllers/customer'); +} = require('../controllers/customer.js'); +const { updateCustomerDetails } = require("../controllers/customer.js"); const router = express.Router(); @@ -9,5 +10,6 @@ const router = express.Router(); // The below /register route extends that, so the end result will be a URL // that looks like http://localhost:4040/customer/register router.post("/register", createCustomer); +router.put('/:id', updateCustomerDetails) module.exports = router; From 5d614ec8ca29ee707fe3454dbe808f12ef2b9c0e Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 15:19:48 +0100 Subject: [PATCH 07/13] post/screens --- src/controllers/screen.js | 12 ++++++++++++ src/domains/screen.js | 11 +++++++++++ src/routers/customer.js | 4 ++-- src/routers/screen.js | 7 +++++++ src/server.js | 3 +++ 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/controllers/screen.js create mode 100644 src/domains/screen.js create mode 100644 src/routers/screen.js diff --git a/src/controllers/screen.js b/src/controllers/screen.js new file mode 100644 index 00000000..41164e15 --- /dev/null +++ b/src/controllers/screen.js @@ -0,0 +1,12 @@ +const { createScreen } = require("../domains/screen") + +const addScreen = async (req, res) => { + const createdScreen = await createScreen(req) + res.status(201).json({ + screen: createdScreen + }) +} + +module.exports = { + addScreen +} \ No newline at end of file diff --git a/src/domains/screen.js b/src/domains/screen.js new file mode 100644 index 00000000..6f331e72 --- /dev/null +++ b/src/domains/screen.js @@ -0,0 +1,11 @@ +const prisma = require('../utils/prisma.js') + +const createScreen = async (req) => await prisma.screen.create({ + data: { + number: req.body.number + } +}) + +module.exports = { + createScreen +} \ No newline at end of file diff --git a/src/routers/customer.js b/src/routers/customer.js index d4211a61..5288ba3e 100644 --- a/src/routers/customer.js +++ b/src/routers/customer.js @@ -1,8 +1,8 @@ const express = require("express"); const { - createCustomer + createCustomer, updateCustomerDetails } = require('../controllers/customer.js'); -const { updateCustomerDetails } = require("../controllers/customer.js"); + const router = express.Router(); diff --git a/src/routers/screen.js b/src/routers/screen.js new file mode 100644 index 00000000..536eb488 --- /dev/null +++ b/src/routers/screen.js @@ -0,0 +1,7 @@ +const express = require("express") +const { addScreen } = require("../controllers/screen") +const router = express.Router() + +router.post('/', addScreen) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index a64fd856..cb6ccd4a 100644 --- a/src/server.js +++ b/src/server.js @@ -20,5 +20,8 @@ app.use('/customers', customerRouter); const movieRouter = require('./routers/movie') app.use('/movies', movieRouter) +const screenRouter = require('./routers/screen') +app.use('/screens', screenRouter) + module.exports = app From 8d2779a7fb5687fc2fc8e4182622f2ae94eb89bb Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 16:48:04 +0100 Subject: [PATCH 08/13] get/movieswith runtime query params --- src/controllers/movie.js | 13 +++++++++++-- src/domains/movie.js | 25 ++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 0910c447..11d8029f 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,9 +1,18 @@ -const { getAllMovies, createMovie, updateMovie } = require('../domains/movie.js') +const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt } = require('../domains/movie.js') const getAll = async (req, res) => { + let allMovies + if(!req.query.runtimeGt || !req.query.runtimeLt) { + allMovies = (await getAllMovies()).map(m => m) + } + if(req.query.runtimeGt) { + allMovies = (await getAllMoviesByRuntimeGt(req.query.runtimeGt)).map(m => m) + } + if (req.query.runtimeLt) { + allMovies = (await getAllMoviesByRuntimeLt(req.query.runtimeLt)).map(m => m) + } - const allMovies = (await getAllMovies()).map(m => m) res.status(200).json({ movies: allMovies }) diff --git a/src/domains/movie.js b/src/domains/movie.js index 9a829000..bf5c12d7 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -29,9 +29,32 @@ const updateMovie = async (req) => await prisma.movie.update({ } }) +const getAllMoviesByRuntimeGt = async (query) => await prisma.movie.findMany({ + where: { + runtimeMins: { + gt: Number(query) + } + }, + include: { + screenings: true + } +}) + +const getAllMoviesByRuntimeLt = async (query) => await prisma.movie.findMany({ + where: { + runtimeMins: { + lt: Number(query) + } + }, + include: { + screenings: true + } +}) module.exports = { getAllMovies, createMovie, - updateMovie + updateMovie, + getAllMoviesByRuntimeGt, + getAllMoviesByRuntimeLt } \ No newline at end of file From f35aa05a509ea1a7a273d2ae0e174a17d527471d Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Mon, 1 Jul 2024 18:23:28 +0100 Subject: [PATCH 09/13] error catchers created, createTicket function started --- src/controllers/customer.js | 17 ++++++++++++++++- src/controllers/movie.js | 33 +++++++++++++++++++++++++++++++++ src/controllers/screen.js | 11 ++++++++++- src/controllers/ticket.js | 0 src/domains/customer.js | 12 +++++++++++- src/domains/screen.js | 15 ++++++++++++++- src/domains/ticket.js | 11 +++++++++++ src/errorClasses/index.js | 11 +++++++++++ src/routers/ticket.js | 0 src/server.js | 18 ++++++++++++++++++ 10 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 src/controllers/ticket.js create mode 100644 src/domains/ticket.js create mode 100644 src/errorClasses/index.js create mode 100644 src/routers/ticket.js diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 89ea1581..5f3a7d99 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,5 +1,5 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") -const { createCustomerDb, updateCustomer } = require('../domains/customer.js') +const { createCustomerDb, updateCustomer, getCustomerByID } = require('../domains/customer.js') const { customer } = require("../utils/prisma.js") const createCustomer = async (req, res) => { @@ -46,7 +46,22 @@ const createCustomer = async (req, res) => { const updateCustomerDetails = async (req, res) => { + if ( + req.body.name === "" || + req.body.name === undefined || + req.body.phone === "" || + req.body.phone === undefined || + req.body.email === "" || + req.body.email === undefined + ) { + throw new MissingFields("Customer name field missing") + } + if (!getCustomerByID()) { + throw new DoesNotExist("Customer not found with that id") + } + const updatedCustomer = await updateCustomer(req) + res.status(201).json({ customer: updatedCustomer }) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 11d8029f..1700cf8c 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,6 +1,7 @@ const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt } = require('../domains/movie.js') + const getAll = async (req, res) => { let allMovies if(!req.query.runtimeGt || !req.query.runtimeLt) { @@ -19,6 +20,17 @@ const getAll = async (req, res) => { } const addMovie = async (req, res) => { + if ( + req.body.title === undefined || + req.body.title === "" || + req.body.runtimeMins === undefined || + req.body.runtimeMins === "" + ) { + throw new MissingFields("Movie title or runtimeMins field missing") + } + if (findMovieByTitle(req.body.title)) { + throw new AlreadyExists("Movie already exists, please choose another to add") + } const newMovie = await createMovie(req) res.status(201).json({ @@ -29,18 +41,39 @@ const addMovie = async (req, res) => { const findByID = async (req, res) => { const id = Number(req.params.id) const found = (await getAllMovies()).find((m) => m.id === id) + if (!found) { + throw new DoesNotExist("Could not find this movies") + } res.status(200).json({ movie: found }) } const updateMovieByID = async (req, res) => { + if ( + req.body.title === "" || + req.body.title === undefined || + req.body.runtimeMins === "" || + req.body.runtimeMins === undefined + ) { + throw new MissingFields("Movie title or runtimeMins field missing") + } + if (!findByID(req)) { + throw new DoesNotExist("Could not find this movies") + } + if (findMovieByTitle) { + throw new AlreadyExists("Movie already exists, please choose another to add") + } const updatedMovie = await updateMovie(req) res.status(201).json({ movie: updatedMovie }) } +const findMovieByTitle = async (title) => { + const found = (await getAllMovies()).find((m) => m.title === title) +} + module.exports = { getAll, addMovie, diff --git a/src/controllers/screen.js b/src/controllers/screen.js index 41164e15..990db755 100644 --- a/src/controllers/screen.js +++ b/src/controllers/screen.js @@ -1,6 +1,15 @@ -const { createScreen } = require("../domains/screen") +const { createScreen, findScreen } = require("../domains/screen") const addScreen = async (req, res) => { + if ( + req.body.number === "" || + req.body.number === undefined + ) { + throw new MissingFields("Number field missing from screenings") + } + if (findScreen()) { + throw new AlreadyExists("This screen already exists please select another screen") + } const createdScreen = await createScreen(req) res.status(201).json({ screen: createdScreen diff --git a/src/controllers/ticket.js b/src/controllers/ticket.js new file mode 100644 index 00000000..e69de29b diff --git a/src/domains/customer.js b/src/domains/customer.js index 9ff04a46..d589f1a2 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -40,7 +40,17 @@ const updateCustomer = async (req) => await prisma.customer.update({ } }) +const getCustomerByID = async (req) => await prisma.customer.findUnique({ + where: { + id: Number(req.params.id) + }, + include: { + contact: true + } +}) + module.exports = { createCustomerDb, - updateCustomer + updateCustomer, + getCustomerByID } diff --git a/src/domains/screen.js b/src/domains/screen.js index 6f331e72..81dba034 100644 --- a/src/domains/screen.js +++ b/src/domains/screen.js @@ -3,9 +3,22 @@ const prisma = require('../utils/prisma.js') const createScreen = async (req) => await prisma.screen.create({ data: { number: req.body.number + }, + include: { + screenings: true + } +}) + +const findScreen = async (req) => await prisma.screen.findUnique({ + where: { + number: req.body.number + }, + include: { + screenings: true } }) module.exports = { - createScreen + createScreen, + findScreen } \ No newline at end of file diff --git a/src/domains/ticket.js b/src/domains/ticket.js new file mode 100644 index 00000000..d8a4360d --- /dev/null +++ b/src/domains/ticket.js @@ -0,0 +1,11 @@ +const prisma = require('../utils/prisma.js') + +const createTicket = async (req) => await prisma.ticket.create({ + data: { + screeningId: req.body. + }, + include: { + screening: true, + customer: true + } +}) \ No newline at end of file diff --git a/src/errorClasses/index.js b/src/errorClasses/index.js new file mode 100644 index 00000000..6e986f02 --- /dev/null +++ b/src/errorClasses/index.js @@ -0,0 +1,11 @@ +class AlreadyExists extends Error { + +} + +class MissingFields extends Error { + +} + +class DoesNotExist extends Error { + +} \ No newline at end of file diff --git a/src/routers/ticket.js b/src/routers/ticket.js new file mode 100644 index 00000000..e69de29b diff --git a/src/server.js b/src/server.js index cb6ccd4a..77d90441 100644 --- a/src/server.js +++ b/src/server.js @@ -24,4 +24,22 @@ const screenRouter = require('./routers/screen') app.use('/screens', screenRouter) +app.use((error, req, res, next) => { + if(error instanceof MissingFields) { + return res.status(400).json({ + message: error.message + }) + } + if(error instanceof AlreadyExists) { + return res.status(409).json({ + message: error.message + }) + } + if(error instanceof DoesNotExist) { + return res.status(404).json({ + message: error.message + }) + } +}) + module.exports = app From 90192d6974a219efd6fb2c28081e9ca455ce6538 Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Tue, 2 Jul 2024 17:06:26 +0100 Subject: [PATCH 10/13] current work --- src/controllers/customer.js | 11 ++++------- src/controllers/movie.js | 27 +++++++++++++++++---------- src/controllers/screen.js | 5 ++++- src/controllers/ticket.js | 26 ++++++++++++++++++++++++++ src/domains/customer.js | 7 ++----- src/domains/movie.js | 9 ++++++++- src/domains/screen.js | 5 +---- src/domains/ticket.js | 9 +++++++-- src/errorClasses/index.js | 6 ++++++ src/routers/ticket.js | 7 +++++++ src/server.js | 3 +++ test/api/routes/movies.spec.js | 23 ++++++++++++----------- test/api/routes/screens.spec.js | 4 ++-- 13 files changed, 99 insertions(+), 43 deletions(-) diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 5f3a7d99..b67f6628 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,6 +1,7 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") const { createCustomerDb, updateCustomer, getCustomerByID } = require('../domains/customer.js') const { customer } = require("../utils/prisma.js") +const { MissingFields, DoesNotExist } = require('../errorClasses/index.js') const createCustomer = async (req, res) => { const { @@ -46,17 +47,13 @@ const createCustomer = async (req, res) => { const updateCustomerDetails = async (req, res) => { + const id = Number(req.params.id) if ( - req.body.name === "" || - req.body.name === undefined || - req.body.phone === "" || - req.body.phone === undefined || - req.body.email === "" || - req.body.email === undefined + req.body.name === "" ) { throw new MissingFields("Customer name field missing") } - if (!getCustomerByID()) { + if (!getCustomerByID(id)) { throw new DoesNotExist("Customer not found with that id") } diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 1700cf8c..8f72ff58 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,5 +1,5 @@ -const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt } = require('../domains/movie.js') - +const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt, getMovieByTitle } = require('../domains/movie.js') +const { MissingFields, AlreadyExists, DoesNotExist } = require('../errorClasses/index.js') const getAll = async (req, res) => { @@ -22,15 +22,15 @@ const getAll = async (req, res) => { const addMovie = async (req, res) => { if ( req.body.title === undefined || - req.body.title === "" || + req.body.title === "" && req.body.runtimeMins === undefined || req.body.runtimeMins === "" ) { throw new MissingFields("Movie title or runtimeMins field missing") } - if (findMovieByTitle(req.body.title)) { - throw new AlreadyExists("Movie already exists, please choose another to add") - } + // if (getMovieByTitle(req)) { + // throw new AlreadyExists("Movie already exists, please choose another to add") + // } const newMovie = await createMovie(req) res.status(201).json({ @@ -40,10 +40,11 @@ const addMovie = async (req, res) => { const findByID = async (req, res) => { const id = Number(req.params.id) - const found = (await getAllMovies()).find((m) => m.id === id) + const found = await findMovieByID(id) if (!found) { throw new DoesNotExist("Could not find this movies") } + res.status(200).json({ movie: found }) @@ -52,16 +53,16 @@ const findByID = async (req, res) => { const updateMovieByID = async (req, res) => { if ( req.body.title === "" || - req.body.title === undefined || + req.body.title === undefined && req.body.runtimeMins === "" || req.body.runtimeMins === undefined ) { throw new MissingFields("Movie title or runtimeMins field missing") } - if (!findByID(req)) { + if (!findMovieByID(req.params.id)) { throw new DoesNotExist("Could not find this movies") } - if (findMovieByTitle) { + if (findMovieByTitle(req.body.title)) { throw new AlreadyExists("Movie already exists, please choose another to add") } const updatedMovie = await updateMovie(req) @@ -70,8 +71,14 @@ const updateMovieByID = async (req, res) => { }) } +const findMovieByID = async (id) => { + const found = (await getAllMovies()).find((m) => m.id === id) + return found +} + const findMovieByTitle = async (title) => { const found = (await getAllMovies()).find((m) => m.title === title) + return found } module.exports = { diff --git a/src/controllers/screen.js b/src/controllers/screen.js index 990db755..75265335 100644 --- a/src/controllers/screen.js +++ b/src/controllers/screen.js @@ -1,16 +1,19 @@ const { createScreen, findScreen } = require("../domains/screen") +const { MissingFields, AlreadyExists } = require('../errorClasses/index.js') const addScreen = async (req, res) => { + const screen = req.body.number if ( req.body.number === "" || req.body.number === undefined ) { throw new MissingFields("Number field missing from screenings") } - if (findScreen()) { + if (findScreen(req)) { throw new AlreadyExists("This screen already exists please select another screen") } const createdScreen = await createScreen(req) + console.log('created screen await') res.status(201).json({ screen: createdScreen }) diff --git a/src/controllers/ticket.js b/src/controllers/ticket.js index e69de29b..1d735d32 100644 --- a/src/controllers/ticket.js +++ b/src/controllers/ticket.js @@ -0,0 +1,26 @@ +const { getCustomerByID } = require("../domains/customer") +const { findScreen } = require("../domains/screen") +const { createTicket } = require("../domains/ticket") + +const createTicketController = async (req, res) => { + const customerID = req.body.customerId + if ( + req.body.screeningId === "" || + req.body.screeningId === undefined || + req.body.customerId === "" || + req.body.customerId === undefined + ) { + throw new MissingFields("Missing fields from the ticket") + } + if (!findScreen() || !getCustomerByID(customerID)) { + throw new DoesNotExist("The screen or customer does not exist, please select another ID") + } + const createdTicket = await createTicket(req) + res.status(201).json({ + ticket: createdTicket + }) +} + +module.exports = { + createTicketController +} \ No newline at end of file diff --git a/src/domains/customer.js b/src/domains/customer.js index d589f1a2..1e578b56 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -40,12 +40,9 @@ const updateCustomer = async (req) => await prisma.customer.update({ } }) -const getCustomerByID = async (req) => await prisma.customer.findUnique({ +const getCustomerByID = async (id) => await prisma.customer.findUnique({ where: { - id: Number(req.params.id) - }, - include: { - contact: true + id: id } }) diff --git a/src/domains/movie.js b/src/domains/movie.js index bf5c12d7..54637dbd 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -51,10 +51,17 @@ const getAllMoviesByRuntimeLt = async (query) => await prisma.movie.findMany({ } }) +const getMovieByTitle = async (req) => await prisma.movie.findFirst({ + where: { + title: req.body.title + } +}) + module.exports = { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeGt, - getAllMoviesByRuntimeLt + getAllMoviesByRuntimeLt, + getMovieByTitle } \ No newline at end of file diff --git a/src/domains/screen.js b/src/domains/screen.js index 81dba034..ff783b3f 100644 --- a/src/domains/screen.js +++ b/src/domains/screen.js @@ -9,12 +9,9 @@ const createScreen = async (req) => await prisma.screen.create({ } }) -const findScreen = async (req) => await prisma.screen.findUnique({ +const findScreen = async (req) => await prisma.screen.findFirst({ where: { number: req.body.number - }, - include: { - screenings: true } }) diff --git a/src/domains/ticket.js b/src/domains/ticket.js index d8a4360d..3cbdcaed 100644 --- a/src/domains/ticket.js +++ b/src/domains/ticket.js @@ -2,10 +2,15 @@ const prisma = require('../utils/prisma.js') const createTicket = async (req) => await prisma.ticket.create({ data: { - screeningId: req.body. + screeningId: req.body.screeningId, + customerId: req.body.customerId }, include: { screening: true, customer: true } -}) \ No newline at end of file +}) + +module.exports = { + createTicket +} \ No newline at end of file diff --git a/src/errorClasses/index.js b/src/errorClasses/index.js index 6e986f02..b6630a54 100644 --- a/src/errorClasses/index.js +++ b/src/errorClasses/index.js @@ -8,4 +8,10 @@ class MissingFields extends Error { class DoesNotExist extends Error { +} + +module.exports = { + AlreadyExists, + MissingFields, + DoesNotExist } \ No newline at end of file diff --git a/src/routers/ticket.js b/src/routers/ticket.js index e69de29b..85345ab1 100644 --- a/src/routers/ticket.js +++ b/src/routers/ticket.js @@ -0,0 +1,7 @@ +const express = require('express') +const { createTicketController } = require('../controllers/ticket') +const router = express.Router() + +router.post('/', createTicketController) + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index 77d90441..53d6d564 100644 --- a/src/server.js +++ b/src/server.js @@ -23,7 +23,10 @@ app.use('/movies', movieRouter) const screenRouter = require('./routers/screen') app.use('/screens', screenRouter) +const ticketRouter = require('./routers/ticket') +app.use('/tickets', ticketRouter) +const { MissingFields, AlreadyExists, DoesNotExist } = require('./errorClasses/index.js') app.use((error, req, res, next) => { if(error instanceof MissingFields) { return res.status(400).json({ diff --git a/test/api/routes/movies.spec.js b/test/api/routes/movies.spec.js index 209c4bc3..76cda7bc 100644 --- a/test/api/routes/movies.spec.js +++ b/test/api/routes/movies.spec.js @@ -3,11 +3,12 @@ const app = require("../../../src/server.js") const { createMovie } = require("../../helpers/createMovie.js") const { createScreen } = require("../../helpers/createScreen.js") + describe("Movies Endpoint", () => { describe("GET /movies", () => { it("will retrieve a list of movies", async () => { const screen = await createScreen(1) - await createMovie('Dodgeball', 120, screen) + await createMovie('Superbad', 120, screen) await createMovie('Scream', 113, screen) const response = await supertest(app).get('/movies') @@ -17,7 +18,7 @@ describe("Movies Endpoint", () => { expect(response.body.movies.length).toEqual(2) const [movie1, movie2] = response.body.movies - expect(movie1.title).toEqual('Dodgeball') + expect(movie1.title).toEqual('Superbad') expect(movie1.runtimeMins).toEqual(120) expect(movie1.screenings).not.toEqual(undefined) expect(movie1.screenings.length).toEqual(1) @@ -39,7 +40,7 @@ describe("Movies Endpoint", () => { const response = await supertest(app) .post("/movies") .send(request) - + expect(response.status).toEqual(201) expect(response.body.movie).not.toEqual(undefined) expect(response.body.movie.title).toEqual('Top Gun') @@ -52,14 +53,14 @@ describe("Movies Endpoint", () => { describe("GET /movies/:id", () => { it("will get a movie by id", async () => { const screen = await createScreen(1) - const created = await createMovie('Dodgeball', 120, screen) + const created = await createMovie('Lucky', 89, screen) const response = await supertest(app).get(`/movies/${created.id}`) - + expect(response.status).toEqual(200) expect(response.body.movie).not.toEqual(undefined) - expect(response.body.movie.title).toEqual('Dodgeball') - expect(response.body.movie.runtimeMins).toEqual(120) + expect(response.body.movie.title).toEqual('Lucky') + expect(response.body.movie.runtimeMins).toEqual(89) expect(response.body.movie.screenings).not.toEqual(undefined) expect(response.body.movie.screenings.length).toEqual(1) }) @@ -68,20 +69,20 @@ describe("Movies Endpoint", () => { describe("PUT /movies/:id", () => { it("will update a movie by id", async () => { const screen = await createScreen(1) - const created = await createMovie('Dodgeball', 120, screen) + const created = await createMovie('Batman Returns', 118, screen) const request = { - title: 'Scream', + title: 'Scary Movie', runtimeMins: 113 } const response = await supertest(app) .put(`/movies/${created.id}`) .send(request) - + expect(response.status).toEqual(201) expect(response.body.movie).not.toEqual(undefined) - expect(response.body.movie.title).toEqual('Scream') + expect(response.body.movie.title).toEqual('Scary Movie') expect(response.body.movie.runtimeMins).toEqual(113) expect(response.body.movie.screenings).not.toEqual(undefined) expect(response.body.movie.screenings.length).toEqual(1) diff --git a/test/api/routes/screens.spec.js b/test/api/routes/screens.spec.js index e6bc8da5..037ebf70 100644 --- a/test/api/routes/screens.spec.js +++ b/test/api/routes/screens.spec.js @@ -5,7 +5,7 @@ describe("Screens Endpoint", () => { describe("POST /screens", () => { it("will create a new screen", async () => { const request = { - number: 10 + number: 11 } const response = await supertest(app) @@ -14,7 +14,7 @@ describe("Screens Endpoint", () => { expect(response.status).toEqual(201) expect(response.body.screen).not.toEqual(undefined) - expect(response.body.screen.number).toEqual(10) + expect(response.body.screen.number).toEqual(11) }) }) }) \ No newline at end of file From 0bc4e107b75717c6b8bd8f3ba946c7e2b6e9c1b0 Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Wed, 3 Jul 2024 15:38:22 +0100 Subject: [PATCH 11/13] move and screens controllers refactored for error handlers --- src/controllers/movie.js | 115 ++++++++++++++++++++++----------- src/controllers/screen.js | 34 ++++++---- src/domains/movie.js | 4 +- src/domains/screen.js | 4 +- src/errorClasses/index.js | 15 ++++- src/server.js | 19 +----- test/api/routes/movies.spec.js | 6 +- 7 files changed, 117 insertions(+), 80 deletions(-) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 8f72ff58..f802eb7f 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,6 +1,5 @@ const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt, getMovieByTitle } = require('../domains/movie.js') -const { MissingFields, AlreadyExists, DoesNotExist } = require('../errorClasses/index.js') - +const { PrismaClientKnownRequestError } = require('@prisma/client/runtime/library') const getAll = async (req, res) => { let allMovies @@ -20,55 +19,93 @@ const getAll = async (req, res) => { } const addMovie = async (req, res) => { - if ( - req.body.title === undefined || - req.body.title === "" && - req.body.runtimeMins === undefined || - req.body.runtimeMins === "" - ) { - throw new MissingFields("Movie title or runtimeMins field missing") - } - // if (getMovieByTitle(req)) { - // throw new AlreadyExists("Movie already exists, please choose another to add") - // } - const newMovie = await createMovie(req) + const { + title, + runtimeMins + } = req.body - res.status(201).json({ - movie: newMovie - }) + if (!title || !runtimeMins) { + return res.status(400).json({ + error: "Movie title or runtimeMins field missing" + }) + } + if (getMovieByTitle(title) === true) { + return res.status(409).json({ + error: "Movie already exists, please choose another to add" + }) + } + try { + const newMovie = await createMovie(req) + + res.status(201).json({ + movie: newMovie + }) + } catch(e) { + if(e.code === "P2002") { + return res.status(409).json({ + error: "Movie already exists, please choose another to add" + }) + } + res.status(500).json({ + error: e.message + }) + } } const findByID = async (req, res) => { const id = Number(req.params.id) const found = await findMovieByID(id) if (!found) { - throw new DoesNotExist("Could not find this movies") - } - - res.status(200).json({ - movie: found - }) + throw new DoesNotExist("Could not find this movie") + } else { + res.status(200).json({ + movie: found + }) + } } const updateMovieByID = async (req, res) => { - if ( - req.body.title === "" || - req.body.title === undefined && - req.body.runtimeMins === "" || - req.body.runtimeMins === undefined - ) { - throw new MissingFields("Movie title or runtimeMins field missing") - } + const { + title, + runtimeMins + } = req.body + if (!title || !runtimeMins) { + return res.status(400).json({ + error: "Movie title or runtimeMins field missing" + }) + } if (!findMovieByID(req.params.id)) { - throw new DoesNotExist("Could not find this movies") - } - if (findMovieByTitle(req.body.title)) { - throw new AlreadyExists("Movie already exists, please choose another to add") - } - const updatedMovie = await updateMovie(req) - res.status(201).json({ + return res.status(404).json({ + error: "Could not find this movies, try another ID" + }) + } + if (getMovieByTitle(title) === true) { + return res.status(409).json({ + error: "Movie already exists, please choose another to add" + }) + } + try { + const updatedMovie = await updateMovie(req) + res.status(201).json({ movie: updatedMovie - }) + }) + } catch(e) { + if (e instanceof PrismaClientKnownRequestError) { + if(e.code === "P2002") { + return res.status(409).json({ + error: "Movie already exists, please choose another to add" + }) + } else if (e.code === "P2001") { + return res.status(404).json({ + error: "Could not find this movies, try another ID" + }) + } + } + + res.status(500).json({ + error: e.message + }) + } } const findMovieByID = async (id) => { diff --git a/src/controllers/screen.js b/src/controllers/screen.js index 75265335..e8b39aa6 100644 --- a/src/controllers/screen.js +++ b/src/controllers/screen.js @@ -1,22 +1,30 @@ const { createScreen, findScreen } = require("../domains/screen") -const { MissingFields, AlreadyExists } = require('../errorClasses/index.js') const addScreen = async (req, res) => { - const screen = req.body.number - if ( - req.body.number === "" || - req.body.number === undefined - ) { - throw new MissingFields("Number field missing from screenings") + const { number } = req.body + if (!number) { + return res.status(400).json({ + error: "Number field missing from screenings" + }) } - if (findScreen(req)) { - throw new AlreadyExists("This screen already exists please select another screen") - } - const createdScreen = await createScreen(req) - console.log('created screen await') - res.status(201).json({ + if (findScreen(number) === true) { + return res.status(409).json({ + error: "This screen already exists please select another screen" + }) + } + try { + const createdScreen = await createScreen(req) + + res.status(201).json({ screen: createdScreen }) + } catch(e) { + if(e.code === "P2002") { + return res.status(409).json({ + error: "This screen already exists please select another screen" + }) + } + } } module.exports = { diff --git a/src/domains/movie.js b/src/domains/movie.js index 54637dbd..5783ac7c 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -51,9 +51,9 @@ const getAllMoviesByRuntimeLt = async (query) => await prisma.movie.findMany({ } }) -const getMovieByTitle = async (req) => await prisma.movie.findFirst({ +const getMovieByTitle = async (title) => await prisma.movie.findFirst({ where: { - title: req.body.title + title: title } }) diff --git a/src/domains/screen.js b/src/domains/screen.js index ff783b3f..f03dc5af 100644 --- a/src/domains/screen.js +++ b/src/domains/screen.js @@ -9,9 +9,9 @@ const createScreen = async (req) => await prisma.screen.create({ } }) -const findScreen = async (req) => await prisma.screen.findFirst({ +const findScreen = async (number) => await prisma.screen.findFirst({ where: { - number: req.body.number + number: Number(number) } }) diff --git a/src/errorClasses/index.js b/src/errorClasses/index.js index b6630a54..fd9c7b52 100644 --- a/src/errorClasses/index.js +++ b/src/errorClasses/index.js @@ -1,13 +1,22 @@ class AlreadyExists extends Error { - + constructor(message) { + super(message) + this.name = 'AlreadyExists' + } } class MissingFields extends Error { - + constructor(message) { + super(message) + this.name = 'MissingFields' + } } class DoesNotExist extends Error { - + constructor(message) { + super(message) + this.name = 'DoesNotExist' + } } module.exports = { diff --git a/src/server.js b/src/server.js index 53d6d564..715af555 100644 --- a/src/server.js +++ b/src/server.js @@ -26,23 +26,6 @@ app.use('/screens', screenRouter) const ticketRouter = require('./routers/ticket') app.use('/tickets', ticketRouter) -const { MissingFields, AlreadyExists, DoesNotExist } = require('./errorClasses/index.js') -app.use((error, req, res, next) => { - if(error instanceof MissingFields) { - return res.status(400).json({ - message: error.message - }) - } - if(error instanceof AlreadyExists) { - return res.status(409).json({ - message: error.message - }) - } - if(error instanceof DoesNotExist) { - return res.status(404).json({ - message: error.message - }) - } -}) + module.exports = app diff --git a/test/api/routes/movies.spec.js b/test/api/routes/movies.spec.js index 76cda7bc..cb5efa7c 100644 --- a/test/api/routes/movies.spec.js +++ b/test/api/routes/movies.spec.js @@ -33,7 +33,7 @@ describe("Movies Endpoint", () => { describe("POST /movies", () => { it("will create a movie", async () => { const request = { - title: "Top Gun", + title: "Full Metal Jacket", runtimeMins: 110 } @@ -43,7 +43,7 @@ describe("Movies Endpoint", () => { expect(response.status).toEqual(201) expect(response.body.movie).not.toEqual(undefined) - expect(response.body.movie.title).toEqual('Top Gun') + expect(response.body.movie.title).toEqual('Full Metal Jacket') expect(response.body.movie.runtimeMins).toEqual(110) expect(response.body.movie.screenings).not.toEqual(undefined) expect(response.body.movie.screenings.length).toEqual(0) @@ -69,7 +69,7 @@ describe("Movies Endpoint", () => { describe("PUT /movies/:id", () => { it("will update a movie by id", async () => { const screen = await createScreen(1) - const created = await createMovie('Batman Returns', 118, screen) + const created = await createMovie('King of Comedy', 118, screen) const request = { title: 'Scary Movie', From 7dffc3cad1bb1fca8432facc149b6df64c114f9b Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Wed, 3 Jul 2024 18:10:49 +0100 Subject: [PATCH 12/13] tests for movie errors started --- src/controllers/customer.js | 36 ++++++++++---- src/controllers/movie.js | 38 +++++++-------- src/domains/customer.js | 13 ++++-- src/domains/movie.js | 13 ++++++ test/api/extensions/movies-ext.spec.js | 65 ++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 test/api/extensions/movies-ext.spec.js diff --git a/src/controllers/customer.js b/src/controllers/customer.js index b67f6628..330bfdb3 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,7 +1,7 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") const { createCustomerDb, updateCustomer, getCustomerByID } = require('../domains/customer.js') const { customer } = require("../utils/prisma.js") -const { MissingFields, DoesNotExist } = require('../errorClasses/index.js') +const { error } = require("console") const createCustomer = async (req, res) => { const { @@ -48,20 +48,36 @@ const createCustomer = async (req, res) => { const updateCustomerDetails = async (req, res) => { const id = Number(req.params.id) - if ( - req.body.name === "" - ) { - throw new MissingFields("Customer name field missing") + const { name, contact: {phone, email} = {} } = req.body + + if (!name) { + return res.status(400).json({ + error: "Customer name field missing" + }) } if (!getCustomerByID(id)) { - throw new DoesNotExist("Customer not found with that id") + return res.status(404).json({ + error: "Customer not found with that ID, choose another" + }) } + try { + const updatedCustomer = await updateCustomer(id, name, phone, email) - const updatedCustomer = await updateCustomer(req) - - res.status(201).json({ + res.status(201).json({ customer: updatedCustomer - }) + }) + } catch(e) { + if (e instanceof PrismaClientKnownRequestError) { + if(e.code === "P2001") { + return res.status(404).json({ + error: "Customer not found with that ID, choose another" + }) + } + } + res.status(500).json({ + error: e.message + }) + } } module.exports = { diff --git a/src/controllers/movie.js b/src/controllers/movie.js index f802eb7f..7dd1d762 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,4 +1,4 @@ -const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt, getMovieByTitle } = require('../domains/movie.js') +const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt, getMovieByTitle, getMovieById } = require('../domains/movie.js') const { PrismaClientKnownRequestError } = require('@prisma/client/runtime/library') const getAll = async (req, res) => { @@ -41,22 +41,26 @@ const addMovie = async (req, res) => { movie: newMovie }) } catch(e) { - if(e.code === "P2002") { - return res.status(409).json({ - error: "Movie already exists, please choose another to add" + if(e instanceof PrismaClientKnownRequestError) { + if(e.code === "P2002") { + return res.status(409).json({ + error: "Movie already exists, please choose another to add" + }) + } + res.status(500).json({ + error: e.message }) - } - res.status(500).json({ - error: e.message - }) + } } } const findByID = async (req, res) => { const id = Number(req.params.id) - const found = await findMovieByID(id) + const found = await getMovieById(id) if (!found) { - throw new DoesNotExist("Could not find this movie") + return res.status(404).json({ + error: "Could not find this movies, try another ID" + }) } else { res.status(200).json({ movie: found @@ -69,12 +73,13 @@ const updateMovieByID = async (req, res) => { title, runtimeMins } = req.body + const id = Number(req.params.id) if (!title || !runtimeMins) { return res.status(400).json({ error: "Movie title or runtimeMins field missing" }) } - if (!findMovieByID(req.params.id)) { + if (!getMovieById(id)) { return res.status(404).json({ error: "Could not find this movies, try another ID" }) @@ -101,23 +106,12 @@ const updateMovieByID = async (req, res) => { }) } } - res.status(500).json({ error: e.message }) } } -const findMovieByID = async (id) => { - const found = (await getAllMovies()).find((m) => m.id === id) - return found -} - -const findMovieByTitle = async (title) => { - const found = (await getAllMovies()).find((m) => m.title === title) - return found -} - module.exports = { getAll, addMovie, diff --git a/src/domains/customer.js b/src/domains/customer.js index 1e578b56..d6b66b96 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -22,16 +22,16 @@ const createCustomerDb = async (name, phone, email) => await prisma.customer.cre }) -const updateCustomer = async (req) => await prisma.customer.update({ +const updateCustomer = async (id, name, phone, email) => await prisma.customer.update({ where: { - id: Number(req.params.id) + id: id }, data: { - name: req.body.name, + name: name, contact: { update: { - phone: req.body.phone, - email: req.body.email + phone: phone, + email: email } } }, @@ -43,6 +43,9 @@ const updateCustomer = async (req) => await prisma.customer.update({ const getCustomerByID = async (id) => await prisma.customer.findUnique({ where: { id: id + }, + include: { + contact: true } }) diff --git a/src/domains/movie.js b/src/domains/movie.js index 5783ac7c..86c18cc8 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -51,9 +51,21 @@ const getAllMoviesByRuntimeLt = async (query) => await prisma.movie.findMany({ } }) +const getMovieById = async (id) => await prisma.movie.findUnique({ + where: { + id: id + }, + include: { + screenings: true + } +}) + const getMovieByTitle = async (title) => await prisma.movie.findFirst({ where: { title: title + }, + include: { + screenings: true } }) @@ -63,5 +75,6 @@ module.exports = { updateMovie, getAllMoviesByRuntimeGt, getAllMoviesByRuntimeLt, + getMovieById, getMovieByTitle } \ No newline at end of file diff --git a/test/api/extensions/movies-ext.spec.js b/test/api/extensions/movies-ext.spec.js new file mode 100644 index 00000000..bce97032 --- /dev/null +++ b/test/api/extensions/movies-ext.spec.js @@ -0,0 +1,65 @@ +const supertest = require('supertest') +const app = require('../../../src/server.js') +const { createMovie } = require('../../helpers/createMovie.js') +const { describe } = require('node:test') +const { title } = require('process') + +describe('Movie Endpoit', () => { + describe('PUT /movies/', () => { + it('will return 400 if there are missing fields in the request body', async () => { + const movie = await createMovie('The Man Who Laughs', 110) + + const request = {} + + const response = await supertest(app) + .put(`/movies/${movie.id}`) + .send(request) + + expect(response.status).toEqual(400) + expect(response.body).toHaveProperty('error') + }) + it('will return 404 if the movie is not found', async () => { + const request = { + title: 'Gangs of New York' + } + + const response = await supertest(app) + .put(`movies/10000`) + .send(request) + + expect(response.status).toEqual(404) + expect(response.body).toHaveProperty('error') + }) + it('will return 409 if a movie already exists with the same title', async () => { + const movie = await createMovie('To Kill A Mockingbird', 129) + + const request = { + title: 'To Kill A Mockingbird', + runtimeMins: 129 + } + const response = await supertest(app) + .put(`/movies/${movie.id}`) + .send(request) + + expect(response.status).toEqual(409) + expect(response.body).toHaveProperty('error') + }) + }) + describe('GET /movies/id', () => { + it('will return 404 if the movie is not found', async () => { + const request = { + title: 'Gangs of New York' + } + + const response = await supertest(app) + .put(`movies/10000`) + .send(request) + + expect(response.status).toEqual(404) + expect(response.body).toHaveProperty('error') + }) + }) + describe('POST /movies/', () => { + + }) +}) \ No newline at end of file From 332878697164753e45cbce1ea25b30d7095f43f4 Mon Sep 17 00:00:00 2001 From: Tim Zoltie Date: Thu, 4 Jul 2024 13:27:17 +0100 Subject: [PATCH 13/13] all tests for error status code created --- src/controllers/customer.js | 6 +-- src/controllers/movie.js | 54 ++++++++++++++++---------- src/controllers/screen.js | 14 ++++--- src/controllers/ticket.js | 47 +++++++++++++++------- src/domains/customer.js | 2 +- src/domains/movie.js | 20 +++++----- src/domains/screen.js | 11 +++++- src/domains/ticket.js | 16 -------- test/api/extensions/movies-ext.spec.js | 40 +++++++++++++++---- test/api/extensions/screen-ext.spec.js | 36 +++++++++++++++++ test/api/extensions/ticket-ext.spec.js | 48 +++++++++++++++++++++++ test/helpers/createTicket.js | 18 +++++++++ 12 files changed, 233 insertions(+), 79 deletions(-) delete mode 100644 src/domains/ticket.js create mode 100644 test/api/extensions/screen-ext.spec.js create mode 100644 test/api/extensions/ticket-ext.spec.js create mode 100644 test/helpers/createTicket.js diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 330bfdb3..2db53cdb 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,7 +1,5 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") const { createCustomerDb, updateCustomer, getCustomerByID } = require('../domains/customer.js') -const { customer } = require("../utils/prisma.js") -const { error } = require("console") const createCustomer = async (req, res) => { const { @@ -49,13 +47,13 @@ const createCustomer = async (req, res) => { const updateCustomerDetails = async (req, res) => { const id = Number(req.params.id) const { name, contact: {phone, email} = {} } = req.body - + const foundCustomerId = await getCustomerByID(id) if (!name) { return res.status(400).json({ error: "Customer name field missing" }) } - if (!getCustomerByID(id)) { + if (!foundCustomerId) { return res.status(404).json({ error: "Customer not found with that ID, choose another" }) diff --git a/src/controllers/movie.js b/src/controllers/movie.js index 7dd1d762..06f1d575 100644 --- a/src/controllers/movie.js +++ b/src/controllers/movie.js @@ -1,17 +1,26 @@ -const { getAllMovies, createMovie, updateMovie, getAllMoviesByRuntimeLt, getAllMoviesByRuntimeGt, getMovieByTitle, getMovieById } = require('../domains/movie.js') +const { + getAllMovies, + createMovie, + updateMovie, + getAllMoviesByRuntimeLt, + getAllMoviesByRuntimeGt, + getMovieByTitle, + getMovieById +} = require('../domains/movie.js') + const { PrismaClientKnownRequestError } = require('@prisma/client/runtime/library') const getAll = async (req, res) => { + const { runtimeLt,runtimeGt } = req.query let allMovies - if(!req.query.runtimeGt || !req.query.runtimeLt) { - allMovies = (await getAllMovies()).map(m => m) - } - if(req.query.runtimeGt) { - allMovies = (await getAllMoviesByRuntimeGt(req.query.runtimeGt)).map(m => m) + + if(runtimeGt) { + allMovies = await getAllMoviesByRuntimeGt(Number(runtimeGt)) } - if (req.query.runtimeLt) { - allMovies = (await getAllMoviesByRuntimeLt(req.query.runtimeLt)).map(m => m) + if (runtimeLt) { + allMovies = await getAllMoviesByRuntimeLt(Number(runtimeLt)) } + allMovies = await getAllMovies() res.status(200).json({ movies: allMovies @@ -24,18 +33,20 @@ const addMovie = async (req, res) => { runtimeMins } = req.body + const titleFound = await getMovieByTitle(title) + if (!title || !runtimeMins) { return res.status(400).json({ error: "Movie title or runtimeMins field missing" }) } - if (getMovieByTitle(title) === true) { + if (titleFound) { return res.status(409).json({ - error: "Movie already exists, please choose another to add" + error: "Movie with that title already exists" }) } try { - const newMovie = await createMovie(req) + const newMovie = await createMovie(title, runtimeMins) res.status(201).json({ movie: newMovie @@ -44,7 +55,7 @@ const addMovie = async (req, res) => { if(e instanceof PrismaClientKnownRequestError) { if(e.code === "P2002") { return res.status(409).json({ - error: "Movie already exists, please choose another to add" + error: "Movie with that title already exists" }) } res.status(500).json({ @@ -59,7 +70,7 @@ const findByID = async (req, res) => { const found = await getMovieById(id) if (!found) { return res.status(404).json({ - error: "Could not find this movies, try another ID" + error: "Could not find movie with that ID" }) } else { res.status(200).json({ @@ -74,23 +85,26 @@ const updateMovieByID = async (req, res) => { runtimeMins } = req.body const id = Number(req.params.id) + const foundId = await getMovieById(id) + const foundTitle = await getMovieByTitle(title) if (!title || !runtimeMins) { return res.status(400).json({ error: "Movie title or runtimeMins field missing" }) } - if (!getMovieById(id)) { + if (!foundId) { return res.status(404).json({ - error: "Could not find this movies, try another ID" + error: "Could not find movie with that ID" }) } - if (getMovieByTitle(title) === true) { + if (foundTitle) { return res.status(409).json({ - error: "Movie already exists, please choose another to add" + error: "Movie with that title already exists" }) } try { - const updatedMovie = await updateMovie(req) + const updatedMovie = await updateMovie(id, title, + runtimeMins) res.status(201).json({ movie: updatedMovie }) @@ -98,11 +112,11 @@ const updateMovieByID = async (req, res) => { if (e instanceof PrismaClientKnownRequestError) { if(e.code === "P2002") { return res.status(409).json({ - error: "Movie already exists, please choose another to add" + error: "Movie with that title already exists" }) } else if (e.code === "P2001") { return res.status(404).json({ - error: "Could not find this movies, try another ID" + error: "Could not find movie with that ID" }) } } diff --git a/src/controllers/screen.js b/src/controllers/screen.js index e8b39aa6..40cad2f9 100644 --- a/src/controllers/screen.js +++ b/src/controllers/screen.js @@ -1,13 +1,15 @@ +const { PrismaClientKnownRequestError } = require("@prisma/client/runtime/library") const { createScreen, findScreen } = require("../domains/screen") const addScreen = async (req, res) => { const { number } = req.body + const screenFound = await findScreen(number) if (!number) { return res.status(400).json({ error: "Number field missing from screenings" }) } - if (findScreen(number) === true) { + if (screenFound) { return res.status(409).json({ error: "This screen already exists please select another screen" }) @@ -19,10 +21,12 @@ const addScreen = async (req, res) => { screen: createdScreen }) } catch(e) { - if(e.code === "P2002") { - return res.status(409).json({ - error: "This screen already exists please select another screen" - }) + if(e instanceof PrismaClientKnownRequestError) { + if(e.code === "P2002") { + return res.status(409).json({ + error: "This screen already exists please select another screen" + }) + } } } } diff --git a/src/controllers/ticket.js b/src/controllers/ticket.js index 1d735d32..d6e02681 100644 --- a/src/controllers/ticket.js +++ b/src/controllers/ticket.js @@ -1,24 +1,43 @@ +const { error } = require("console") const { getCustomerByID } = require("../domains/customer") -const { findScreen } = require("../domains/screen") -const { createTicket } = require("../domains/ticket") +const { findScreeningById } = require("../domains/screen") +const { createTicket } = require("../../test/helpers/createTicket.js") +const { PrismaClientKnownRequestError } = require("@prisma/client/runtime/library") const createTicketController = async (req, res) => { - const customerID = req.body.customerId - if ( - req.body.screeningId === "" || - req.body.screeningId === undefined || - req.body.customerId === "" || - req.body.customerId === undefined - ) { - throw new MissingFields("Missing fields from the ticket") + + const {screeningId, customerId} = req.body + const foundScreenId = await findScreeningById(screeningId) + const foundCustomerId = await getCustomerByID(customerId) + + if (!screeningId || !customerId) { + return res.status(400).json({ + error: "Missing fields from the ticket" + }) } - if (!findScreen() || !getCustomerByID(customerID)) { - throw new DoesNotExist("The screen or customer does not exist, please select another ID") + if (!foundScreenId || !foundCustomerId) { + return res.status(404).json({ + error: "The screen or customer does not exist, please select another ID" + }) } - const createdTicket = await createTicket(req) - res.status(201).json({ + try { + const createdTicket = await createTicket(screeningId, customerId) + res.status(201).json({ ticket: createdTicket }) + } catch (e) { + if(e instanceof PrismaClientKnownRequestError) { + if(e.code === "P2001") { + return res.status(404).json({ + error: "The screen or customer does not exist, please select another ID" + }) + } + } + res.status(500).json({ + error: e.message + }) + } + } module.exports = { diff --git a/src/domains/customer.js b/src/domains/customer.js index d6b66b96..40d073da 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -42,7 +42,7 @@ const updateCustomer = async (id, name, phone, email) => await prisma.customer.u const getCustomerByID = async (id) => await prisma.customer.findUnique({ where: { - id: id + id: Number(id) }, include: { contact: true diff --git a/src/domains/movie.js b/src/domains/movie.js index 86c18cc8..92bc11ef 100644 --- a/src/domains/movie.js +++ b/src/domains/movie.js @@ -6,23 +6,25 @@ const getAllMovies = async () => await prisma.movie.findMany({ } }) -const createMovie = async (req) => await prisma.movie.create({ +const createMovie = async (title, + runtimeMins) => await prisma.movie.create({ data: { - title: req.body.title, - runtimeMins: req.body.runtimeMins + title: title, + runtimeMins: runtimeMins }, include: { screenings: true } }) -const updateMovie = async (req) => await prisma.movie.update({ +const updateMovie = async (id, title, + runtimeMins) => await prisma.movie.update({ where: { - id: Number(req.params.id) + id: id }, data: { - title: req.body.title, - runtimeMins: req.body.runtimeMins + title: title, + runtimeMins: runtimeMins }, include: { screenings: true @@ -32,7 +34,7 @@ const updateMovie = async (req) => await prisma.movie.update({ const getAllMoviesByRuntimeGt = async (query) => await prisma.movie.findMany({ where: { runtimeMins: { - gt: Number(query) + gt: query } }, include: { @@ -43,7 +45,7 @@ const getAllMoviesByRuntimeGt = async (query) => await prisma.movie.findMany({ const getAllMoviesByRuntimeLt = async (query) => await prisma.movie.findMany({ where: { runtimeMins: { - lt: Number(query) + lt: query } }, include: { diff --git a/src/domains/screen.js b/src/domains/screen.js index f03dc5af..53af721c 100644 --- a/src/domains/screen.js +++ b/src/domains/screen.js @@ -11,11 +11,18 @@ const createScreen = async (req) => await prisma.screen.create({ const findScreen = async (number) => await prisma.screen.findFirst({ where: { - number: Number(number) + number: number + } +}) + +const findScreeningById = async (screeningId) => await prisma.screen.findUnique({ + where: { + id: screeningId } }) module.exports = { createScreen, - findScreen + findScreen, + findScreeningById } \ No newline at end of file diff --git a/src/domains/ticket.js b/src/domains/ticket.js deleted file mode 100644 index 3cbdcaed..00000000 --- a/src/domains/ticket.js +++ /dev/null @@ -1,16 +0,0 @@ -const prisma = require('../utils/prisma.js') - -const createTicket = async (req) => await prisma.ticket.create({ - data: { - screeningId: req.body.screeningId, - customerId: req.body.customerId - }, - include: { - screening: true, - customer: true - } -}) - -module.exports = { - createTicket -} \ No newline at end of file diff --git a/test/api/extensions/movies-ext.spec.js b/test/api/extensions/movies-ext.spec.js index bce97032..7d471959 100644 --- a/test/api/extensions/movies-ext.spec.js +++ b/test/api/extensions/movies-ext.spec.js @@ -20,11 +20,12 @@ describe('Movie Endpoit', () => { }) it('will return 404 if the movie is not found', async () => { const request = { - title: 'Gangs of New York' + title: 'Raging Bull', + runtimeMins: 129 } const response = await supertest(app) - .put(`movies/10000`) + .put(`/movies/10000`) .send(request) expect(response.status).toEqual(404) @@ -47,19 +48,42 @@ describe('Movie Endpoit', () => { }) describe('GET /movies/id', () => { it('will return 404 if the movie is not found', async () => { - const request = { - title: 'Gangs of New York' - } + await createMovie('Gangs of New York', 167) + await createMovie('Raging Bull', 129) const response = await supertest(app) - .put(`movies/10000`) - .send(request) + .get(`/movies/10000`) expect(response.status).toEqual(404) expect(response.body).toHaveProperty('error') }) }) describe('POST /movies/', () => { - + it('will return 400 if the movies fields is missing a body', async () => { + + const request = {} + + const response = await supertest(app) + .post(`/movies/`) + .send(request) + + expect(response.status).toEqual(400) + expect(response.body).toHaveProperty('error') + }) + it('will return 409 if the movie title already exists in the db', async() => { + const movie = await (createMovie('Psycho', 109)) + + const request = { + title: 'Psycho', + runtimeMins: 109 + } + + const response = await supertest(app) + .post(`/movies/`) + .send(request) + + expect(response.status).toEqual(409) + expect(response.body).toHaveProperty('error') + }) }) }) \ No newline at end of file diff --git a/test/api/extensions/screen-ext.spec.js b/test/api/extensions/screen-ext.spec.js new file mode 100644 index 00000000..3d481c7f --- /dev/null +++ b/test/api/extensions/screen-ext.spec.js @@ -0,0 +1,36 @@ +const supertest = require('supertest') +const app = require('../../../src/server.js') +const { createScreen } = require('../../helpers/createScreen.js') + +const { describe } = require('node:test') + +describe('Screen Endpoint', () => { + describe('POST /screens/', () => { + it('will return 400 if there is a missing field in the request body', async () => { + const screen = await createScreen(1) + + const request = {} + + const response = await supertest(app) + .post(`/screens/`) + .send(request) + + expect(response.status).toEqual(400) + expect(response.body).toHaveProperty('error') + }) + it('will return 409 if a screen already exists with this number', async () => { + const screen = await createScreen(1) + + const request = { + number: 1 + } + + const response = await supertest(app) + .post(`/screens/`) + .send(request) + + expect(response.status).toEqual(409) + expect(response.body).toHaveProperty('error') + }) + }) +}) \ No newline at end of file diff --git a/test/api/extensions/ticket-ext.spec.js b/test/api/extensions/ticket-ext.spec.js new file mode 100644 index 00000000..b6803aa9 --- /dev/null +++ b/test/api/extensions/ticket-ext.spec.js @@ -0,0 +1,48 @@ +const supertest = require('supertest') +const app = require('../../../src/server.js') +const { createTicket } = require('../../helpers/createTicket.js') + +const { describe } = require('node:test') + +describe('Ticket Endpoint', () => { + describe('POST /ticket/', () => { + it('will create a ticket for the customer', () => { + async () => { + + const request = { + screeningId: 1, + customerId: 1 + } + + const response = await supertest(app) + .post('/screens/') + .send(request) + + expect(response.status).toEqual(201) + expect(response.body.customer).not.toEqual(undefined) + expect(response.body.screening).not.toEqual(undefined) + expect(response.body.movie.title).toEqual('The Matrix') + expect(response.body.customer.name).toEqual('Tom') + } + }) + it('will return 400 if the screenId or customerId fields are missing', async () => { + const request = {} + + const response = await supertest(app) + .post('/screens/') + .send(request) + + expect(response.status).toEqual(400) + expect(response.body).toHaveProperty('error') + }) + it('will return 400 if the screeningId or customerId is not found', async () => { + const request = {} + const response = await supertest(app) + .post('/screens/') + .send(request) + + expect(response.status).toEqual(400) + expect(response.body).toHaveProperty('error') + }) + }) +}) \ No newline at end of file diff --git a/test/helpers/createTicket.js b/test/helpers/createTicket.js new file mode 100644 index 00000000..b2d930bf --- /dev/null +++ b/test/helpers/createTicket.js @@ -0,0 +1,18 @@ +const prisma = require("../../src/utils/prisma") + +const createTicket = async (screeningId, customerId) => await prisma.ticket.create({ + where: { + screeningId: screeningId, + customerId: customerId + }, + include: { + screening: true, + customer: true, + movie, + screen + } +}) + +module.exports = { + createTicket +} \ No newline at end of file