Skip to content

Commit

Permalink
Merge 5a64bd4 into 512893b
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilome committed Oct 16, 2018
2 parents 512893b + 5a64bd4 commit cf52bdd
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 114 deletions.
85 changes: 17 additions & 68 deletions server/controllers/orderController.js
Expand Up @@ -4,7 +4,7 @@ import orderFormatter from '../middleware/formatter';
class OrderController {
static async getAllOrders(req, res) {
try {
const dbQuery = 'SELECT orders.id, menu.food_name, users.name, orders.date, orders.status FROM orders JOIN menu ON orders.item = menu.id JOIN users ON orders.author = users.id';
const dbQuery = 'SELECT orders.id, orders.items, users.name, orders.date, orders.status FROM orders JOIN users ON orders.author = users.id';
const allOrders = (await pool.query(dbQuery)).rows;
const formattedOrders = orderFormatter(allOrders);

Expand All @@ -22,24 +22,16 @@ class OrderController {
const { id } = req.params;

if (Number.isNaN(Number(id))) {
return res.status(400).json({
status: 'error',
message: 'invalid order id format',
});
return res.status(400).json({ status: 'error', message: 'invalid order id format' });
}

try {
const allOrders = (await pool.query('SELECT orders.id, menu.food_name, users.name, orders.date, orders.status FROM orders JOIN menu ON orders.item = menu.id JOIN users ON orders.author = users.id')).rows;
const allOrders = (await pool.query('SELECT orders.id, orders.items, users.name, orders.date, orders.status FROM orders JOIN users ON orders.author = users.id')).rows;

const formattedOrders = orderFormatter(allOrders);
const targetOrder = formattedOrders.find(order => order.id === Number(id));

if (!targetOrder) {
return res.status(404).json({
status: 'error',
message: 'no such order exists',
});
}
if (!targetOrder) return res.status(404).json({ status: 'error', message: 'no such order exists' });

return res.status(200).json({
status: 'success',
Expand All @@ -52,38 +44,13 @@ class OrderController {
}

static async newOrder(req, res) {
const { foodId } = req.body;
if (!foodId) {
return res.status(400).json({
status: 'error',
message: 'incomplete data',
});
}

if (Number.isNaN(Number(foodId))) {
return res.status(400).json({
status: 'error',
message: 'invalid data provided',
});
}
try {
const foodExists = (await pool.query('SELECT * FROM menu WHERE id=$1', [foodId])).rowCount;

if (!foodExists) {
return res.status(400).json({
status: 'error',
message: 'no such food exists',
});
}
} catch (error) {
res.status(500).json(error);
}
const { foodItems } = req;

const dbInsertQuery = 'INSERT INTO orders(item, author) VALUES($1, $2)';
const dbSelectQuery = 'SELECT orders.id, menu.food_name, users.name, orders.date, orders.status FROM orders JOIN menu ON orders.item = menu.id JOIN users ON orders.author = users.id';
const dbInsertQuery = 'INSERT INTO orders(items, author) VALUES($1, $2)';
const dbSelectQuery = 'SELECT orders.id, orders.items, users.name, orders.date, orders.status FROM orders JOIN users ON orders.author = users.id';

try {
await pool.query(dbInsertQuery, [foodId, req.userId]);
await pool.query(dbInsertQuery, [JSON.stringify(foodItems), req.userId]);
const allOrders = (await pool.query(dbSelectQuery));
const newOrder = allOrders.rows[allOrders.rowCount - 1];

Expand All @@ -93,7 +60,7 @@ class OrderController {
order: {
id: newOrder.id,
author: newOrder.name,
title: newOrder.food_name,
items: JSON.parse(newOrder.items),
date: newOrder.date,
status: newOrder.status,
},
Expand All @@ -105,28 +72,14 @@ class OrderController {

static async updateOrder(req, res) {
const { id } = req.params;

if (!Number(id)) {
return res.status(400).json({
status: 'error',
message: 'invalid order id provided',
});
}
if (!Number(id)) return res.status(400).json({ status: 'error', message: 'invalid order id provided' });

try {
const dbQuery = 'UPDATE orders SET status=$1 WHERE id=$2';
await pool.query(dbQuery, [req.status, Number(id)]);

const orderExists = (await pool.query('SELECT * FROM orders WHERE id=$1', [Number(id)])).rowCount;
if (!orderExists) return res.status(404).json({ status: 'error', message: 'no order with that id exists' });

if (!orderExists) {
return res.status(404).json({
status: 'error',
message: 'no order with that id exists',
});
}

const updatedOrders = (await pool.query('SELECT orders.id, menu.food_name, users.name, orders.date, orders.status FROM orders JOIN menu ON orders.item = menu.id JOIN users ON orders.author = users.id')).rows;
await pool.query('UPDATE orders SET status=$1 WHERE id=$2', [req.status, Number(id)]);
const updatedOrders = (await pool.query('SELECT orders.id, orders.items, users.name, orders.date, orders.status FROM orders JOIN users ON orders.author = users.id')).rows;

const formattedOrders = orderFormatter(updatedOrders);
const targetOrder = formattedOrders.find(order => order.id === Number(id));
Expand All @@ -142,13 +95,7 @@ class OrderController {

static async getAllUserOrders(req, res) {
const { id } = req.params;

if (Number.isNaN(Number(id))) {
return res.status(400).json({
status: 'error',
message: 'invalid user id',
});
}
if (Number.isNaN(Number(id))) return res.status(400).json({ status: 'error', message: 'invalid user id' });

if (Number(id) !== req.userId) {
return res.status(403).json({
Expand All @@ -159,10 +106,12 @@ class OrderController {

try {
const userOrders = (await pool.query('SELECT * FROM orders WHERE author=$1', [id])).rows;
const formattedUserOrders = userOrders
.map(order => ({ items: JSON.parse(order.items), date: order.date, status: order.status }));
return res.status(200).json({
status: 'success',
message: 'orders fetched successfully',
orders: userOrders,
orders: formattedUserOrders,
});
} catch (error) {
return res.status(500).json({ error });
Expand Down
32 changes: 0 additions & 32 deletions server/db/orders.js

This file was deleted.

2 changes: 1 addition & 1 deletion server/db/schema.sql
Expand Up @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS menu (

CREATE TABLE IF NOT EXISTS orders (
id serial PRIMARY KEY,
item INTEGER REFERENCES menu(id),
items TEXT NOT NULL,
author INTEGER REFERENCES users(id),
date DATE NOT NULL DEFAULT CURRENT_DATE,
status VARCHAR(50) NOT NULL DEFAULT 'new'
Expand Down
2 changes: 1 addition & 1 deletion server/middleware/formatter.js
Expand Up @@ -3,7 +3,7 @@ const formatOrders = (orders) => {
const formatted = {
id: foundOrder.id,
author: foundOrder.name,
title: foundOrder.food_name,
items: JSON.parse(foundOrder.items),
date: foundOrder.date,
status: foundOrder.status,
};
Expand Down
28 changes: 28 additions & 0 deletions server/middleware/sanitizer.js
Expand Up @@ -104,6 +104,34 @@ class Sanitize {
req.price = price;
return next();
}

static async newOrder(req, res, next) {
const { foodIds } = req.body;

if (!foodIds
|| !Validator.isArray(foodIds)
|| !foodIds.length
|| !Validator.isArrayOfNumbers(foodIds)
) {
return res.status(400).json({
status: 'error',
message: 'foodIds should be an array of numbers',
});
}
const { allFoodExists, allFoodItems } = await Validator.isArrayOfValidFoodIds(foodIds);
if (!allFoodExists) {
return res.status(404).json({
status: 'error',
message: 'one of the requested food items does not exist',
});
}
// Create Array of requested food names.
const foodItems = foodIds
.map(foodId => allFoodItems.find(foodItem => foodItem.id === Number(foodId)).food_name);

req.foodItems = foodItems;
return next();
}
}

export default Sanitize;
2 changes: 1 addition & 1 deletion server/routes/ordersRouter.js
Expand Up @@ -6,7 +6,7 @@ import Sanitize from '../middleware/sanitizer';
const router = new Router();

router.get('/users/:id/orders', AuthHandler.authorize, OrderController.getAllUserOrders);
router.post('/orders', AuthHandler.authorize, OrderController.newOrder);
router.post('/orders', AuthHandler.authorize, Sanitize.newOrder, OrderController.newOrder);
router.get('/orders', AuthHandler.authorize, AuthHandler.authorizeAdmin, OrderController.getAllOrders);

router.get(
Expand Down
23 changes: 23 additions & 0 deletions server/validators/validator.js
@@ -1,3 +1,5 @@
import pool from '../db/config';

class Validator {
static isEmail(email) {
const re = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/ig;
Expand All @@ -15,6 +17,27 @@ class Validator {
static isValidName(name) {
return name.trim().length >= 2;
}

static isArray(value) {
return Array.isArray(value);
}

static isArrayOfNumbers(array) {
return array.every(element => !Number.isNaN(Number(element)));
}

static async isArrayOfValidFoodIds(foodIds) {
try {
const allFoodItems = (await pool.query('SELECT * FROM menu')).rows;
const validFoodIds = allFoodItems.map(food => food.id);
return {
allFoodExists: foodIds.every(foodId => validFoodIds.includes(Number(foodId))),
allFoodItems,
};
} catch (error) {
throw new Error(error);
}
}
}

/* Refs.
Expand Down
23 changes: 23 additions & 0 deletions tests/routes/menu.spec.js
Expand Up @@ -73,6 +73,27 @@ describe('POST /menu', () => {
done();
});
});

it('should add another new food item to the menu successfully', (done) => {
chai.request(app)
.post('/api/v1/menu')
.set('x-auth', generateValidToken(users.admin))
.send({
foodName: 'Turkey Wings',
foodImage: 'https://i.imgur.com/Bfn1CxC.jpg',
price: '1200',
})
.end((err, res) => {
if (err) done(err);

res.status.should.eql(201);
res.body.should.be.an('object').which.has.all.keys(['status', 'message', 'food']);
res.body.food.should.have.all.keys(['id', 'food_name', 'food_image', 'price']);
res.body.food.food_name.should.eql('Turkey Wings');
res.body.food.price.should.eql(1200);
done();
});
});
});

describe('GET /menu', () => {
Expand All @@ -88,6 +109,7 @@ describe('GET /menu', () => {
res.status.should.eql(200);
res.body.message.should.eql('menu fetched successfully');
res.body.menu.should.be.an('array');
res.body.menu.length.should.eql(2);
done();
});
});
Expand All @@ -102,6 +124,7 @@ describe('GET /menu', () => {
res.status.should.eql(200);
res.body.message.should.eql('menu fetched successfully');
res.body.menu.should.be.an('array');
res.body.menu.length.should.eql(2);
done();
});
});
Expand Down

0 comments on commit cf52bdd

Please sign in to comment.