Skip to content

Commit

Permalink
Merge 996c778 into f09a99e
Browse files Browse the repository at this point in the history
  • Loading branch information
alainmateso committed Oct 24, 2019
2 parents f09a99e + 996c778 commit 625c83c
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 39 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"test": "npm run rollback && npm run migrate && npm run seed && npm run test-suite",
"test-suite": "NODE_ENV=test nyc --reporter=html --reporter=text mocha src/tests/index.spec.js --require @babel/register --timeout 20000 --exit",
"coveralls": "nyc report --reporter=text-lcov| coveralls",
"build": "babel ./src --out-dir dist --source-maps --watch"
"localbuild": "babel ./src --out-dir dist --source-maps --watch"
},
"nyc": {
"exclude": [
Expand Down
79 changes: 65 additions & 14 deletions src/controllers/requestController.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,77 @@
import models from '../database/models';
import strings from '../utils/stringsUtil';
import text from '../utils/strings';
import responseHelper from '../utils/responseHelper';
import responseUtil from '../utils/responseUtil';
import userServices from '../services/userServices';
import Utilities from '../utils/index';
import findRequests from '../helpers/findRequests';

const {
APPROVED, REJECTED, SUCCESSFULLY_RETRIEVED_REQUESTS
} = strings.requests;
const { NO_REQUESTS, ASSIGNED_REQUESTS } = text.user.requests;

export default class requestController {

static async viewRequests({ user }, res) {
static async viewManagerRequests(req, res) {
const { id: lineManager } = req.user.payload;

const users = await models.users.findAll({
where: { lineManager },
attributes: ['id', 'username', 'email'],
include: [
{
model: models.requests,
where: { statusId: [1, 2, 3] },
attributes: ['id', 'createdAt'],
include: [
{ model: models.tripTypes, as: 'type', attributes: ['id', 'name'] },
{ model: models.requestStatus, as: 'status', attributes: ['id', 'name'] },
{ model: models.locations, as: 'origin', attributes: ['id', 'name', 'country'] },
{ model: models.destinations, attributes: ['id', 'arrivalDate', 'departureDate', 'reasons'], include: [{ model: models.locations, as: 'location', attributes: ['name'] }] }
]
},
]
});
return responseUtil(res, 200, (!users.length)
? NO_REQUESTS
: ASSIGNED_REQUESTS, users);
}

static async viewMyRequests({ user }, res) {
const query = Utilities.requestQueries.userRequests(user.payload);
const { requests } = await userServices.findOne(query, Utilities.queryScopes.responseScope);

if (!requests.length) {
return Utilities.responseHelper(
res,
Utilities.stringsHelper.user.requests.NO_REQUESTS,
requests,
404
);
return responseUtil(res, 200, (!requests.length)
? NO_REQUESTS
: SUCCESSFULLY_RETRIEVED_REQUESTS, requests);
}

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

const requestToApprove = findRequests(req);

if (requestToApprove) {
await models.requests.update({ statusId: 3 }, { where: { id } });

return responseHelper(res, APPROVED, null, 200);
}
return responseHelper(res, strings.requests.NOT_FOUND, null, 404);
}

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

const requestToReject = findRequests(req);

if (requestToReject) {
await models.requests.update({ statusId: 2 }, { where: { id } });

return responseHelper(res, REJECTED, null, 200);
}
return responseHelper(res, strings.user.requests.NOT_FOUND, null, 404);

return Utilities.responseHelper(
res,
Utilities.stringsHelper.user.requests.SUCCESSFULLY_RETRIEVED_REQUESTS,
requests,
200
);
}
}
3 changes: 2 additions & 1 deletion src/database/migrations/20190930143254-User.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ module.exports = {
},
lineManager:{
type: Sequelize.INTEGER,
allowNull: true
allowNull: false,
defaultValue: 8
},
email: {
type: Sequelize.STRING,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 6
}, { transaction: t })
}, { transaction: t }),
])),

down: queryInterface => queryInterface.sequelize.transaction(t => Promise.all([
Expand Down
4 changes: 4 additions & 0 deletions src/database/models/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ module.exports = (sequelize, DataTypes) => {
targetKey: 'requestId',
sourceKey: 'id'
});
requests.belongsTo(models.users, {
targetKey: 'id',
sourceKey: 'userId'
});
};

return requests;
Expand Down
6 changes: 4 additions & 2 deletions src/database/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ module.exports = (sequelize, Datatypes) => {
currency: Datatypes.STRING,
company: Datatypes.STRING,
department: Datatypes.STRING,
lineManager: Datatypes.INTEGER,
isVerified: {
type: Datatypes.BOOLEAN,
defaultValue: false,
},
role: Datatypes.INTEGER
lineManager:{
type: Datatypes.INTEGER,
defaultValue: 8
}
}, {
scopes: {
responseScope: {
Expand Down
16 changes: 16 additions & 0 deletions src/database/seeders/20191002153158-usersTableSeeder.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
email: 'johndoe@test.com',
password: '$2b$10$vQp2ahUwAnRS.HHxNLK0pOQ/E41TRnxtlDJL.5vVRHsvL7DC9svNm',
isVerified: false,
lineManager: 8,
role: 6,
createdAt: new Date(),
updatedAt: new Date()
Expand Down Expand Up @@ -37,6 +38,7 @@ module.exports = {
email: 'ghost@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 6,
createdAt: new Date(),
updatedAt: new Date()
Expand All @@ -46,6 +48,7 @@ module.exports = {
email: 'user@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 5,
createdAt: new Date(),
updatedAt: new Date()
Expand All @@ -56,6 +59,7 @@ module.exports = {
email: 'alain@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 1,
createdAt: new Date(),
updatedAt: new Date()
Expand All @@ -65,6 +69,7 @@ module.exports = {
email: 'mateso@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 6,
createdAt: new Date(),
updatedAt: new Date()
Expand All @@ -74,10 +79,21 @@ module.exports = {
email: 'supplier@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 5,
createdAt: new Date(),
updatedAt: new Date()
},
{
username: 'demoManager',
email: 'manager@caretbn.com',
password: '$2b$10$VyldWKIyiuVSqZYjmz4u8OepsFJFKzQipOQzhrhQKthgn8a9OI2Au',
isVerified: true,
lineManager: 8,
role: 4,
createdAt: new Date(),
updatedAt: new Date()
},
])
]),

Expand Down
20 changes: 20 additions & 0 deletions src/helpers/findRequests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import models from '../database/models';

const findSpecificRequest = async req => {
const { id: userManager } = req.user.payload;
const { id } = req.params;

const foundRequest = await models.requests.findOne({
where: { id },
attributes: ['id'],
include: [
{
model: models.users,
attributes: ['id', 'username', 'email'],
where: { lineManager: userManager }
}]
});
return foundRequest;
};

export default findSpecificRequest;
10 changes: 9 additions & 1 deletion src/middlewares/checkRole.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ const checkSupplierRole = (req, res, next) => {
return next();
};

export default { checkSupplierRole };
const checkManagerRole = (req, res, next) => {
const { role } = req.user.payload;
if (role !== 4) {
return responseError(res, 403, strings.requests.MANAGERS_ONLY);
}
return next();
};

export default { checkSupplierRole, checkManagerRole };
2 changes: 1 addition & 1 deletion src/middlewares/inputValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import responseError from '../utils/responseError';
import strings from '../utils/stringsUtil';

const validation = (req, res, schema, next) => {
const { error } = schema.validate(req.body, { abortEarly: false });
const { error } = schema.validate(req.body, req.params, { abortEarly: false });
if (error) {
const errorMessages = [];
error.details.forEach(detail => {
Expand Down
12 changes: 11 additions & 1 deletion src/routes/api/requests.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Router } from 'express';
import requestController from '../../controllers/requestController';
import validateToken from '../../middlewares/auth/validateToken';
import checkId from '../../middlewares/checkId';
import checkRole from '../../middlewares/checkRole';

const router = new Router();
const {
viewMyRequests, approveRequest, rejectRequest, viewManagerRequests
} = requestController;

router.get('/', validateToken, (req, res) => requestController.viewRequests(req, res));
const { checkManagerRole } = checkRole;

router.get('/', validateToken, viewMyRequests);
router.get('/manager', validateToken, checkManagerRole, viewManagerRequests);
router.patch('/manager/approve/:id', validateToken, checkManagerRole, checkId, approveRequest);
router.patch('/manager/reject/:id', validateToken, checkManagerRole, checkId, rejectRequest);

export default router;
3 changes: 2 additions & 1 deletion src/tests/mockData/mockData.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const mockData = {
admin:{email: 'alain@caretbn.com', password: 'Pa55w0rd' },
fakeGender: { gender: 'xxxx' },
missingFields: { email: '', password: '' },
supplier:{email: 'supplier@caretbn.com', password: 'Pa55w0rd'}
supplier:{email: 'supplier@caretbn.com', password: 'Pa55w0rd'},
manager:{email: 'manager@caretbn.com', password: 'Pa55w0rd'},
};
export default mockData;
Loading

0 comments on commit 625c83c

Please sign in to comment.