-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Setup API endpoint for loan application
Add files loansController.js and loansModel.js Add file ValidateLoans.js for user input validation Add file loans.js for loans data structure Add Auth.js for user authentication Add files loanHelper.js, utils.js Add loansTest.js for test cases
- Loading branch information
1 parent
29f7e03
commit a9019b5
Showing
15 changed files
with
572 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import loansModel from '../model/loansModel' | ||
import ResponseHelper from '../helpers/responseHelper' | ||
|
||
/** | ||
* @fileOverview - class manages all users logic | ||
* @class - LoansController | ||
* @requires - ../model/loansModel | ||
* @requires - ../helpers/token | ||
* @requires - ../helpers/errorStrings | ||
* @exports - loansController.js | ||
**/ | ||
|
||
class LoansController { | ||
|
||
/** | ||
* Create a loan application | ||
* @param {object} req | ||
* @param {object} res | ||
*/ | ||
|
||
static createLoan (req, res) { | ||
|
||
const userEmail = req.token.user.email; | ||
|
||
const currentLoan = loansModel.checkCurrentLoan(userEmail) | ||
|
||
if(currentLoan.isFound === true ) { | ||
|
||
ResponseHelper.errorResponse(res, `You have an unpaid loan of ${currentLoan.loan.amount} which is under review or yet to be fully repaid`); | ||
|
||
} else { | ||
const newLoan = loansModel.createLoan(req, userEmail); | ||
|
||
return res.status(201).send({ | ||
status: 201, | ||
data: { | ||
loanId: newLoan.id, | ||
user: newLoan.user, | ||
createdOn: newLoan.createdOn, | ||
status: newLoan.status, | ||
repaid: newLoan.repaid, | ||
tenor: newLoan.tenor, | ||
amount: newLoan.amount, | ||
paymentInstallment: newLoan.paymentInstallment, | ||
balance: newLoan.balance, | ||
interest: newLoan.interest | ||
} | ||
}); | ||
} | ||
|
||
} | ||
|
||
|
||
} | ||
|
||
export default LoansController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* @fileOverview - This module holds dummy data for loans | ||
* @exports - loans object | ||
*/ | ||
const loans = [ | ||
{ | ||
id: 1, | ||
user: 'shonubijerry@gmail.com', | ||
createdOn: '01/05/2019 2:16:17 PM', | ||
status: 'approved', | ||
repaid: true, | ||
tenor: 5, | ||
amount: 40000, | ||
paymentInstallment: '8400.00', | ||
balance: '0.00', | ||
interest: '2000.00' | ||
}, | ||
{ | ||
id: 2, | ||
user: 'adeade@gmail.com', | ||
createdOn: '01/04/2019 2:16:17 PM', | ||
status: 'approved', | ||
repaid: false, | ||
tenor: 7, | ||
amount: 80000, | ||
paymentInstallment: '12000.00', | ||
balance: '84000.00', | ||
interest: '4000.00' | ||
}, | ||
{ | ||
id: 3, | ||
user: 'shonubijerry@gmail.com', | ||
createdOn: '01/05/2019 2:17:34 PM', | ||
status: 'approved', | ||
repaid: true, | ||
tenor: 5, | ||
amount: 8960000, | ||
paymentInstallment: '1881600.00', | ||
balance: '0.00', | ||
interest: '448000.00' | ||
}, | ||
{ | ||
id: 4, | ||
user: 'adeade@gmail.com', | ||
createdOn: '01/05/2019 3:40:18 PM', | ||
status: 'approved', | ||
repaid: true, | ||
tenor: 7, | ||
amount: 60000, | ||
paymentInstallment: '9000.00', | ||
balance: '0.00', | ||
interest: '3000.00' | ||
} | ||
]; | ||
|
||
export default loans; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* @fileOverview - This class helps generate loan parameters | ||
* @class LoanHelper | ||
* @exports loanHelper | ||
**/ | ||
|
||
class LoanHelper { | ||
|
||
/** | ||
* calculate interest | ||
* @param {float} amount | ||
* @returns {float} | ||
*/ | ||
|
||
static getInterest(amount) { | ||
return amount * 0.05; | ||
} | ||
|
||
/** | ||
* calculate balance | ||
* @param {float} amount | ||
* @returns {float} | ||
*/ | ||
|
||
static getBalance(amount) { | ||
return amount + this.getInterest(amount); | ||
} | ||
|
||
/** | ||
* calculate paymentInstallment | ||
* @param {integer} tenor | ||
* @returns {float} | ||
*/ | ||
|
||
static getInstallment(amount, tenor) { | ||
return this.getBalance(amount) / tenor; | ||
} | ||
|
||
} | ||
|
||
|
||
export default LoanHelper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* @fileOverview - This class helps generate repeated codes | ||
* @class Utils | ||
* @exports Utils | ||
**/ | ||
|
||
class Utils { | ||
|
||
/** | ||
* get present date and time | ||
* @returns {string} | ||
*/ | ||
|
||
static getNow() { | ||
const d = new Date(); | ||
return `${d.toLocaleDateString()} ${d.toLocaleTimeString()}`; | ||
} | ||
|
||
} | ||
|
||
export default Utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import jwt from 'jsonwebtoken'; | ||
import errorStrings from '../helpers/errorStrings'; | ||
import ResponseHelper from '../helpers/responseHelper'; | ||
|
||
const secretKey = process.env.SECRET_KEY; | ||
|
||
/** | ||
* @class Authenticate User | ||
* @requires jsonwebtoken | ||
* @requires '../helpers/errorStrings' | ||
*/ | ||
class Auth { | ||
|
||
/** | ||
* Authenticate users | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @param {callback} next | ||
* @return {Object} | ||
*/ | ||
|
||
static authenticateUser(request, response, next) { | ||
try { | ||
const userToken = request.headers['x-access'] || request.headers.token; | ||
const verifiedToken = jwt.verify(userToken, secretKey); | ||
request.token = verifiedToken; | ||
return next(); | ||
} catch (error) { | ||
ResponseHelper.errorUnauthorized(response, errorStrings.notAuthenticated); | ||
} | ||
|
||
} | ||
|
||
|
||
} | ||
|
||
export default Auth; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import errorStrings from '../helpers/errorStrings'; | ||
import Validator from '../helpers/Validator'; | ||
import rules from '../helpers/rules'; | ||
|
||
|
||
/** | ||
* @fileOverview Class to validate loans form submission | ||
* @class ValidateLoans | ||
* @requires ../helpers/errorStrings | ||
* @requires ../helpers/Validator | ||
* @requires ../helpers/rules | ||
* @exports ValidateLoans | ||
*/ | ||
|
||
class ValidateLoans { | ||
/** | ||
* validate signup input | ||
* @param {Object} request | ||
* @param {Object} response | ||
* @callback {Function} next | ||
*/ | ||
|
||
static validateApplication(request, response, next) { | ||
|
||
const errors = ValidateLoans.checkApplicationErrors(request.body); | ||
|
||
Validator.checkValidationErrors(response, errors, next); | ||
} | ||
|
||
/** | ||
* collect all possible errors | ||
* @param {Object} request | ||
* @return {String} errors | ||
*/ | ||
|
||
static checkApplicationErrors ({amount, tenor}) { | ||
const errors = {}; | ||
|
||
if (!amount || !rules.empty.test(amount) || !rules.validAmount.test(amount)) | ||
errors.validAmount = errorStrings.validAmount; | ||
|
||
if (!tenor || !rules.empty.test(tenor) || !rules.validTenor.test(tenor)) | ||
errors.validTenor = errorStrings.validTenor; | ||
|
||
return errors; | ||
} | ||
|
||
|
||
} | ||
|
||
export default ValidateLoans; |
Oops, something went wrong.