Skip to content

Commit

Permalink
Merge cf3bba1 into 9e3e2b6
Browse files Browse the repository at this point in the history
  • Loading branch information
NonsoAmadi10 committed Sep 3, 2019
2 parents 9e3e2b6 + cf3bba1 commit faf9055
Show file tree
Hide file tree
Showing 8 changed files with 8,780 additions and 14 deletions.
8,649 changes: 8,649 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"coverage": "nyc report --reporter=text-lcov | coveralls",
"test": "NODE_ENV=test yarn undo:migration && NODE_ENV=test yarn migrate && NODE_ENV=test yarn undo:seed && NODE_ENV=test yarn seed && NODE_ENV=test nyc --reporter=html --reporter=text mocha --exit --require @babel/register --require @babel/polyfill src/test/index.js",
"test": "NODE_ENV=test&&yarn undo:migration &&yarn migrate && yarn undo:seed && yarn seed && nyc --reporter=html --reporter=text mocha --exit --require @babel/register --require @babel/polyfill src/test/index.js",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"dev-start": "set NODE_ENV=development && nodemon --exec babel-node src/index.js",
"build": "babel src --out-dir build",
Expand All @@ -21,7 +21,6 @@
"@sendgrid/mail": "^6.4.0",
"bcrypt": "^3.0.6",
"body-parser": "^1.18.3",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"cors": "^2.8.4",
"dotenv": "^6.0.0",
Expand All @@ -44,15 +43,13 @@
"request": "^2.87.0",
"sequelize": "^5.14.0",
"sequelize-cli": "^5.5.0",
"sinon": "^7.4.1",
"swagger-ui-express": "^4.0.7",
"underscore": "^1.9.1"
},
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/node": "^7.5.5",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.5.5",
"@babel/register": "^7.5.5",
"babel-eslint": "^10.0.2",
Expand Down
55 changes: 54 additions & 1 deletion src/controllers/RequestController.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class RequestController {
try {
const { id } = req.decoded;
const { body } = req;
const { dataValues } = await Request.create({ ...body, userId: id });
const { dataValues } = await Request.create({ ...body, userId: id, });
if (dataValues.id) {
HelperMethods.requestSuccessful(res, {
success: true,
Expand Down Expand Up @@ -67,6 +67,59 @@ class RequestController {
}
}

/**
* Edit a request
* Route: PATCH: /request/edit
* @param {object} req - HTTP Request object
* @param {object} res - HTTP Response object
* @return {res} res - HTTP Response object
* @memberof RequestController
*/
static async editRequest(req, res) {
try {
const { id } = req.decoded;
const {
body
} = req;

const requestExist = await Request.findOne({
where: {
id: body.requestId,
userId: id,
}
});

if (requestExist) {
if (requestExist.dataValues.status === 'open') {
if (requestExist.dataValues.returnDate) {
const convertFlightDate = body.flightDate
? new Date(body.flightDate).toISOString() : requestExist.flightDate;
const convertReturnDate = body.returnDate
? new Date(body.returnDate).toISOString() : requestExist.returnDate;
if (convertFlightDate > convertReturnDate) {
return HelperMethods.clientError(
res, 'The flight date cannot be after the return date', 400
);
}
}

const updatedRequest = await requestExist.update({ ...body, });
return HelperMethods.requestSuccessful(res, {
success: true,
message: 'Trip udpdated successfully',
updatedData: updatedRequest.dataValues,
}, 200);
}
return HelperMethods.clientError(res, 'Forbidden', 403);
}
return HelperMethods.clientError(
res, 'The request you are trying to edit does not exist', 404
);
} catch (error) {
if (error.errors) return HelperMethods.sequelizeValidationError(res, error);
}
}

/**
* Get pending requests
* Route: GET: /request
Expand Down
2 changes: 1 addition & 1 deletion src/migrations/03-create-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module.exports = {
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
},
}),

down: queryInterface => queryInterface.dropTable('Requests')
Expand Down
2 changes: 1 addition & 1 deletion src/models/Request.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default (sequelize, DataTypes) => {
type: DataTypes.ENUM,
values: ['BUSINESS', 'VACATION', 'EXPEDITION'],
defaultValue: 'BUSINESS'
},
}
});

Request.associate = models => {
Expand Down
7 changes: 6 additions & 1 deletion src/routes/requestRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ const requestRoutes = app => {
);

app.patch(
'/api/v1/request',
'/api/v1/request/approve',
Authorization.checkToken,
Authorization.confirmRole,
RequestController.approveRequest
);
app.patch(
'/api/v1/request/edit',
Authorization.checkToken,
RequestController.editRequest
);

app.patch(
'/api/v1/request/reject',
Expand Down
2 changes: 1 addition & 1 deletion src/seeders/03-demo-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = {
accommodationId: '9c41e609-7a30-4211-9d10-146a9c54ee74',
userId: '96dc6b6d-7a77-4322-8756-e22f181d952c',
reason: 'BUSINESS',
status: 'open',
status: 'approved',
createdAt: new Date(),
updatedAt: new Date()
},
Expand Down
72 changes: 67 additions & 5 deletions src/test/integrationTests/requestController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('Integration tests for the request controller', () => {
status: 'open'
};
let token;
let requestId;

before('login with an existing user details from the seeded data', async () => {
const response = await chai.request(app).post('/api/v1/auth/login')
Expand All @@ -25,6 +26,16 @@ describe('Integration tests for the request controller', () => {
password: 'password',
});
token = response.body.data.userDetails.token;
const bookTrip = await chai.request(app).post('/api/v1/request/book_trip')
.set('x-access-token', token)
.send({
origin: 'Lagos',
destination: 'Kaduna',
flightDate: '2019-06-21',
returnDate: '2019-08-21',
accommodationId: '2125be7b-f1f1-4f0a-af86-49c657870b5c'
});
requestId = bookTrip.body.data.tripCreated.id;
});
describe('Authentication tests', () => {
it('should return an error if the authentication token is missing', async () => {
Expand Down Expand Up @@ -96,6 +107,57 @@ describe('Integration tests for the request controller', () => {
expect(response.body).to.have.property('success');
expect(response.body.success).to.equal(false);
});

it('should allow a registered user to update a trip request', async () => {
const response = await chai.request(app).patch('/api/v1/request/edit')
.set('x-access-token', token).send({
requestId,
origin: 'eko',
destination: 'miami',
flightDate: '2019-02-01',
returnDate: '2019-06-04',
reason: 'VACATION'
});
expect(response.status).to.equal(200);
expect(response.body.data).to.have.property('message');
expect(response.body.data.message).to.equal('Trip udpdated successfully');
expect(response.body.data).to.have.property('updatedData');
expect(response.body.data.updatedData.origin).to.equal('eko');
expect(response.body.data.updatedData.destination).to.equal('miami');
expect(response.body.data.updatedData.reason).to.equal('VACATION');
expect(response.body.data).to.have.property('success');
expect(response.body.data.success).to.equal(true);
});

it('should not allow an update on incorrect date parameters', async () => {
const response = await chai.request(app).patch('/api/v1/request/edit')
.set('x-access-token', token).send({
requestId,
origin: 'eko',
destination: 'miami',
flightDate: '2019-02-01',
returnDate: '2017-06-04',
reason: 'VACATION'
});
expect(response.status).to.equal(400);
expect(response.body.message).to
.equal('The flight date cannot be after the return date');
});

it('should not allow an update on invalid request ID', async () => {
const response = await chai.request(app).patch('/api/v1/request/edit')
.set('x-access-token', token).send({
requestId: '1b26c8d1-768d-4bcb-8407-f6d85b1f1dee',
origin: 'eko',
destination: 'miami',
flightDate: '2019-02-01',
returnDate: '2017-06-04',
reason: 'VACATION'
});
expect(response.status).to.equal(404);
expect(response.body.message).to
.equal('The request you are trying to edit does not exist');
});
});

let managerToken;
Expand Down Expand Up @@ -162,7 +224,7 @@ describe('Integration tests for the request controller', () => {
it('should let a Manager approve a pending request created by'
+ ' his direct report', async () => {
const requestResponse = await chai.request(app)
.patch('/api/v1/request')
.patch('/api/v1/request/approve')
.set('x-access-token', managerToken)
.send({
id: '1b26c8d1-768d-4bcb-8407-f6d85b1f1dee',
Expand All @@ -174,7 +236,7 @@ describe('Integration tests for the request controller', () => {
it('should return error when non-Managers attempt '
+ 'to approve pending requests', async () => {
const requestResponse = await chai.request(app)
.patch('/api/v1/request')
.patch('/api/v1/request/approve')
.set('x-access-token', nonLineManagerToken)
.send({
id: '1b26c8d1-768d-4bcb-8407-f6d85b1f1dee',
Expand All @@ -186,7 +248,7 @@ describe('Integration tests for the request controller', () => {

it('should return error when route is accessed without a token', async () => {
const requestResponse = await chai.request(app)
.patch('/api/v1/request')
.patch('/api/v1/request/approve')
.set('x-access-token', 'invalid token')
.send({
id: '1b26c8d1-768d-4bcb-8407-f6d85b1f1dee',
Expand All @@ -199,8 +261,8 @@ describe('Integration tests for the request controller', () => {
it('should return error when a Manager who is not the line Manager'
+ 'attempts to approve pending requests', async () => {
const requestResponse = await chai.request(app)
.patch('/api/v1/request')
.set('x-access-token', managerToken)
.patch('/api/v1/request/approve')
.set('x-access-token', token)
.send({
id: '1b26c8d1-768d-4bcb-8407-f6d85b1f1dee',
});
Expand Down

0 comments on commit faf9055

Please sign in to comment.