-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add search travel request #33
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,4 @@ | |
"editor.formatOnSave": false, | ||
"eslint.autoFixOnSave": true, | ||
"prettier.eslintIntegration": true, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,23 @@ | ||
import { | ||
onewayTripService, | ||
showManagerPendingAppr, | ||
showUsertravelsStatus | ||
showManagerPendingAppr, | ||
showUsertravelsStatus, | ||
searchTravel | ||
} from '../services/travelServices'; | ||
import { successResponseWithData, errorResponse } from '../utils/response'; | ||
|
||
import message from '../utils/messageUtils'; | ||
import statusCode from '../utils/statusCode'; | ||
import { paginate } from '../utils/pagination'; | ||
|
||
export default { | ||
createOneWayTrip: async (req, res) => { | ||
try { | ||
const { | ||
origin, destination, departure_date, accommodation_id, travel_purpose | ||
origin, | ||
destination, | ||
departure_date, | ||
accommodation_id, | ||
travel_purpose | ||
} = req.body; | ||
const userId = req.userData.id; | ||
|
||
|
@@ -23,12 +28,17 @@ export default { | |
destination, | ||
departure_date, | ||
travel_purpose, | ||
accommodation_id, | ||
accommodation_id | ||
}; | ||
|
||
const data = await onewayTripService(travelObj); | ||
|
||
successResponseWithData(res, statusCode.created, message.oneWayTripCreated, data); | ||
successResponseWithData( | ||
res, | ||
statusCode.created, | ||
message.oneWayTripCreated, | ||
data | ||
); | ||
} catch (err) { | ||
errorResponse(res, statusCode.serverError, err); | ||
} | ||
|
@@ -46,29 +56,60 @@ export default { | |
try { | ||
const requestsPending = await showManagerPendingAppr(manager); | ||
|
||
const filteredRequests = requestsPending.filter(request => request['user.department.line_manager'] !== null); | ||
const filteredRequests = requestsPending.filter( | ||
request => request['user.department.line_manager'] !== null | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unexpected newline before ')' function-paren-newline |
||
|
||
const requestNumbers = filteredRequests.length; | ||
|
||
// eslint-disable-next-line max-len | ||
successResponseWithData(res, statusCode.success, message.managerApproval(requestNumbers), filteredRequests); | ||
successResponseWithData( | ||
res, | ||
statusCode.success, | ||
message.managerApproval(requestNumbers), | ||
filteredRequests | ||
); | ||
} catch (err) { | ||
errorResponse(res, statusCode.serverError, err); | ||
} | ||
}, | ||
|
||
getUserTravelStatus: async(req, res) => { | ||
const { role, id } = req.userData; | ||
getUserTravelStatus: async (req, res) => { | ||
const { role, id } = req.userData; | ||
|
||
if (role === 'admin') { | ||
return errorResponse(res, statusCode.unauthorized, message.unauthorized); | ||
} else { | ||
if (role === 'admin') { | ||
return errorResponse(res, statusCode.unauthorized, message.unauthorized); | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary 'else' after 'return' no-else-return |
||
try { | ||
const data = await showUsertravelsStatus(id); | ||
return successResponseWithData(res, statusCode.success, message.userApproval, data); | ||
return successResponseWithData( | ||
res, | ||
statusCode.success, | ||
message.userApproval, | ||
data | ||
); | ||
} catch (error) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trailing spaces not allowed no-trailing-spaces |
||
errorResponse(res, statusCode.serverError, error); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
/* search travels | ||
* @param {Object} req - server request | ||
* @param {Object} res - server response | ||
* @param {Object} next - server response | ||
* @returns {Object} - custom response | ||
*/ | ||
export const searchTravels = async (req, res) => { | ||
try { | ||
const { body, query } = req; | ||
const { page, perPage } = query; | ||
const { rows, count } = await searchTravel(body, query); | ||
const meta = paginate(page, perPage, count, rows); | ||
return res.status(200).json({ success: { requests: rows, meta } }); | ||
} catch (error) { | ||
return res.status(404).json({ error: error }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected property shorthand object-shorthand There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @t4christ Excellent There is a defined error handler in the utils folder, instead of res.status(404)..... and also a success response too... instead of res.status(200).... |
||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
import { Router } from 'express'; | ||
|
||
import travelControllers from '../controllers/travelControllers'; | ||
import travelValidator from '../validation/travelValidation'; | ||
import travelControllers, {searchTravels} from '../controllers/travelControllers'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A space is required after '{' object-curly-spacing |
||
import { getToken, verifyToken } from '../middlewares/tokenMiddleware'; | ||
import travelValidator,{validateTravelSearch, validateTravelResult} from '../validation/travelValidation'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A space is required after ',' comma-spacing |
||
|
||
|
||
const route = Router(); | ||
const { createOneWayTrip, pendingManagerApproval, getUserTravelStatus } = travelControllers; | ||
|
@@ -13,6 +14,7 @@ route.post('/onewaytrip', getToken, verifyToken, validateTravelRequest, validate | |
|
||
// handles manager pending req approvals route | ||
route.get('/requests/pending/:manager', getToken, verifyToken, pendingManagerApproval); | ||
route.get('/search/travels',validateTravelSearch, validateTravelResult,searchTravels); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A space is required after ',' comma-spacing |
||
|
||
route.get('/user/status', getToken, verifyToken, getUserTravelStatus); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,6 +132,26 @@ describe('Testing one way ticket feature', () => { | |
done(); | ||
}); | ||
}); | ||
|
||
|
||
it('should return search result based on origin and destination', (done) => { | ||
const searchTravelRequest = { | ||
'origin': 'NewYork, USA', | ||
'destination': 'Paris, France' | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected indentation of 4 spaces but found 6 indent |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trailing spaces not allowed no-trailing-spaces |
||
chai.request(app) | ||
.get(`${prefix}/search/travels`) | ||
.set('Authorization', `Bearer ${token}`) | ||
.send(searchTravelRequest) | ||
.end((err, res) => { | ||
expect(res.status).to.equal(200); | ||
expect(searchTravelRequest).to.have.property('origin'); | ||
expect(searchTravelRequest).to.have.property('destination'); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('should return an error message if travel_purpose', (done) => { | ||
const mutatedtravelRequest = Object.assign({}, travelRequest); | ||
mutatedtravelRequest.travel_purpose = ''; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
|
||
/** | ||
* @function computeLimitAndOffset | ||
* @param {number} page page number to get | ||
* @param {number} perPage number of items per page/request | ||
* @param {number} defaultLimit default items per page = 20 | ||
* @returns {object} returns object containing limit and offset | ||
*/ | ||
export const computeLimitAndOffset = (page, perPage, defaultLimit = 20) => { | ||
const offset = (page ? Number(page) - 1 : 0) * (perPage ? Number(perPage) : defaultLimit); | ||
const limit = perPage ? Number(perPage) : defaultLimit; | ||
return { offset, limit }; | ||
}; | ||
|
||
/** | ||
* @function paginate | ||
* @param {number} page page number to get | ||
* @param {number} perPage number of items per page/request | ||
* @param {number} count total number of items | ||
* @param {array} rows items | ||
* @param {number} defaultLimit default items per page = 20 | ||
* @returns {object} return the metaData for pagination | ||
*/ | ||
export const paginate = (page, perPage, count, rows, defaultLimit = 20) => { | ||
const metaData = { | ||
page: Number(page) || 1, | ||
pageCount: Math.ceil(count / (perPage ? Number(perPage) : defaultLimit)), | ||
pageSize: rows.length, | ||
count | ||
}; | ||
return metaData; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,64 @@ | ||
import { check, validationResult } from 'express-validator'; | ||
|
||
|
||
import { errorResponse } from '../utils/response'; | ||
import statusCode from '../utils/statusCode'; | ||
import message from '../utils/messageUtils'; | ||
|
||
export default { | ||
validateTravelRequest: [ | ||
check('origin').not().isEmpty() | ||
check('origin') | ||
.not() | ||
.isEmpty() | ||
.withMessage(message.emptyOrigin) | ||
.isAlpha() | ||
.withMessage(message.lettersAlone), | ||
check('destination').not().isEmpty() | ||
check('destination') | ||
.not() | ||
.isEmpty() | ||
.withMessage(message.emptyDestination) | ||
.isAlpha() | ||
.withMessage(message.lettersAlone), | ||
check('departure_date').not().isEmpty().withMessage(message.emptyDepartureDate), | ||
check('travel_purpose').not().isEmpty().withMessage(message.emptyTravelPurpose), | ||
check('departure_date') | ||
.not() | ||
.isEmpty() | ||
.withMessage(message.emptyDepartureDate), | ||
check('travel_purpose') | ||
.not() | ||
.isEmpty() | ||
.withMessage(message.emptyTravelPurpose) | ||
], | ||
validateResult: (req, res, next) => { | ||
const errors = validationResult(req); | ||
if (!errors.isEmpty()) { | ||
const error = []; | ||
errors.array().forEach((err) => { | ||
errors.array().forEach(err => { | ||
error.push(err.msg); | ||
}); | ||
return errorResponse(res, statusCode.badRequest, error); | ||
} | ||
return next(); | ||
}, | ||
} | ||
}; | ||
|
||
export const validateTravelSearch = [ | ||
check('origin') | ||
.not() | ||
.isInt() | ||
.withMessage(message.lettersAlone), | ||
check('destination') | ||
.not() | ||
.isInt() | ||
.withMessage(message.lettersAlone) | ||
]; | ||
|
||
export const validateTravelResult = (req, res, next) => { | ||
const errors = validationResult(req); | ||
if (!errors.isEmpty()) { | ||
const error = []; | ||
errors.array().forEach(err => { | ||
error.push(err.msg); | ||
}); | ||
return errorResponse(res, statusCode.badRequest, error); | ||
} | ||
return next(); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unexpected newline after '(' function-paren-newline