Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .env.example

This file was deleted.

7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,20 @@ The full database schema and seed file for this exercise has already been implem

- Change your movie list GET route to only respond with movies that have a future screening time
- Add the ability for customers to leave reviews on movies
- This will require a new entity in your diagram, schema file and seed file. Remember the `npx prisma generate`, `npx prisma migrate dev --create-only --skip-seed --name reviews` and `npx prisma migrate reset` commands from an earlier exercise!
- This will require a new entity in your diagram, schema file and seed file. Remember the `npx prisma generate`, `npx prisma migrate dev --create-only --skip-seed --name reviews` and `npx prisma migrate reset` commands from an earlier exercise!
- You will need to create your own tests for these endpoints. Use the existing test provided in `test/api/extensions` as a guide.
- If you create the new `Review` entity, then you will also need to re-run `npm run test:migration` so that your test database runs the migration to create this table. Do this AFTER you have created the new migration file.
- If you create the new `Review` entity, then you will also need to re-run `npm run test:migration` so that your test database runs the migration to create this table. Do this AFTER you have created the new migration file.

## Testing your work

- First, make sure you have created / setup the test database instance and env var, as described in the "Setting Up" section.
- Next, run the command `npm run test:migration` - this will run the schema migrations against the test database. **You only need to do this the one time.**

Now, whenever you want to run tests locally:

- Run the test suite with `npm test` for core requirements.
- Run the extension test suite with `npm run test-extensions`.
- When working on extensions, create your own tests by using the one provided in `test/api/extensions` as a guide.
- When working on extensions, create your own tests by using the one provided in `test/api/extensions` as a guide.

So far, you may have been using `curl` to manually test your API endpoints. You can continue to use this approach if you choose, or you can download a tool to make things a little easier. There are two main options:

Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
setupFilesAfterEnv: ['./test/setupTests.js']
}
}
46 changes: 23 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 29 additions & 16 deletions src/controllers/customer.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
const { PrismaClientKnownRequestError } = require("@prisma/client")
const { createCustomerDb } = require('../domains/customer.js')
const { PrismaClientKnownRequestError } = require("@prisma/client");
const { createCustomerDb, update } = require("../domains/customer.js");

const createCustomer = async (req, res) => {
const {
name,
phone,
email
} = req.body
const { name, phone, email } = req.body;

if (!name || !phone || !email) {
return res.status(400).json({
error: "Missing fields in request body"
})
error: "Missing fields in request body",
});
}

// Try-catch is a very common way to handle errors in JavaScript.
Expand All @@ -22,9 +18,9 @@ const createCustomer = async (req, res) => {
// instead of the Prisma error being thrown (and the app potentially crashing) we exit the
// `try` block (bypassing the `res.status` code) and enter the `catch` block.
try {
const createdCustomer = await createCustomerDb(name, phone, email)
const createdCustomer = await createCustomerDb(name, phone, email);

res.status(201).json({ customer: createdCustomer })
res.status(201).json({ customer: createdCustomer });
} catch (e) {
// In this catch block, we are able to specify how different Prisma errors are handled.
// Prisma throws errors with its own codes. P2002 is the error code for
Expand All @@ -35,14 +31,31 @@ const createCustomer = async (req, res) => {
// HTTP error codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses
if (e instanceof PrismaClientKnownRequestError) {
if (e.code === "P2002") {
return res.status(409).json({ error: "A customer with the provided email already exists" })
return res
.status(409)
.json({ error: "A customer with the provided email already exists" });
}
}

res.status(500).json({ error: e.message })
res.status(500).json({ error: e.message });
}
}
};

const fetchUpdate = async (req, res) => {
const id = Number(req.params.id);
const { name, contact } = req.body;

if (!name && (!contact.phone || !contact.email)) {
return res.status(400).json({
error: "Missing fields in request body",
});
}
const updates = req.body;
const updated = await update(id, updates);
res.status(201).json({ customer: updated });
};

module.exports = {
createCustomer
}
createCustomer,
fetchUpdate,
};
42 changes: 42 additions & 0 deletions src/controllers/movie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { all, getById, create, update, remove } = require("../domains/movie");

const fetchAll = async (req, res) => {
const movies = await all();
res.status(200).json({ movies: movies });
};

const fetchCreate = async (req, res) => {
const { title, runtimeMins } = req.body;
const newMovie = await create(title, Number(runtimeMins));
res.status(201).json({ movie: newMovie });
};

const fetchGet = async (req, res) => {
const { id } = req.params;
const found = await getById(Number(id));
if (!found) return res.status(404).json(`No movie found with id: ${id}`);

res.status(200).json({ movie: found });
};

const fetchUpdate = async (req, res) => {
let { id } = req.params;
let { title, runtimeMins } = req.body;
id = Number(id)
runtimeMins = Number(runtimeMins)

const found = await getById(id);
if (!found) return res.status(404).json(`No movie found with id: ${id}`);

const updated = await update(id, { title, runtimeMins });
res.status(201).json({ movie: updated });
};

const fetchRemove = async (req, res) => {};
module.exports = {
all: fetchAll,
create: fetchCreate,
get: fetchGet,
update: fetchUpdate,
remove: fetchRemove,
};
11 changes: 11 additions & 0 deletions src/controllers/screen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { create } = require("../domains/screen.js");

const fetchCreate = async (req, res) => {
const { number } = req.body;
const result = await create(number);
res.status(201).json({ screen: result });
};

module.exports = {
fetchCreate,
};
64 changes: 45 additions & 19 deletions src/domains/customer.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,52 @@
const prisma = require('../utils/prisma')
const prisma = require("../utils/prisma");

/**
* This will create a Customer AND create a new Contact, then automatically relate them with each other
* @tutorial https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#create-a-related-record
*/
const createCustomerDb = async (name, phone, email) => await prisma.customer.create({
data: {
name,
contact: {
create: {
phone,
email
}
}
},
// We add an `include` outside of the `data` object to make sure the new contact is returned in the result
// This is like doing RETURNING in SQL
include: {
contact: true
}
})
const createCustomerDb = async (name, phone, email) =>
await prisma.customer.create({
data: {
name,
contact: {
create: {
phone,
email,
},
},
},
// We add an `include` outside of the `data` object to make sure the new contact is returned in the result
// This is like doing RETURNING in SQL
include: {
contact: true,
},
});

const update = async (id, updates) => {
const result = await prisma.customer.update({
where: {
id,
},
data: {
name: updates.name,
contact: updates.contact && {
delete: {
customerId: id,
},
create: {
phone: updates.contact.phone,
email: updates.contact.email,
},
},
},
include: {
contact: true,
},
});
return result
};

module.exports = {
createCustomerDb
}
createCustomerDb,
update,
};
Loading