Skip to content
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

#159762182 Integrate Payment #30

Merged
merged 24 commits into from
Sep 10, 2018

Conversation

yomigeek
Copy link
Contributor

@yomigeek yomigeek commented Sep 3, 2018

What does this PR do?

Integrate Payement System to allow users upgrade to a premium account on the platform

Description of Task to be completed?

  • consume Flutterwave Rave API
  • create a dummy front-end page to initiate the payment
  • create a middleware that checks if the payment reference is provided
  • prevent user account upgrade if payment reference is invalid during a check with the Flutterwave Rave API
  • upgrades user account if payment reference is valid during a check with the Flutterwave Rave API

How should this be manually tested?

  • clone the repo: Run git clone https://github.com/andela/elven-ah.git in the folder where you want the repo to be saved.
  • navigate into the newly created folder and install the dependencies: cd elven-ah && npm install
  • copy .env.example to .env: cp .env.example .env
  • provision a PostgreSQL database and add the credentials to the .env file.
  • start the server using npm start
  • initiate the payment using a front-end client to get the payment reference via the query parameter
  • upgrade the user account by making a GET request to /api/pay with ref as a query parameter

Any background context you want to provide?

What are the relevant pivotal tracker stories?

#159762182

Screenshots (if appropriate)\

N/A

Questions:

N/A

[Finishes #159762182]

yomigeek and others added 7 commits August 31, 2018 10:28
- add a sketchy UI for checking of the process
- add a payment model
- add a payment controller
- install the flutterwave rave package
- modify payment controller file
- modify payment model
- create comment reply as first level comment when invalid parentId is supplied

[Delivers #160216041]
- add test for comment reply feature that creates comment reply with invalid parent id as first level comment
- refactor comment tests to remove unnecessary fields in request body

[Finishes #160216041]
- refactor CommentController to use aync/await
- extract repeated slug validation code to middleware
- modify test to read updated responses

[Finishes #160216041]
- add more tests to cover more edge cases

[Finishes #160216041]
- add more unit tests
- create a check payment refeerence middleware
- modify payment controller file

[Delivers #159762182]
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Payments');
}
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline required at end of file but not found eol-last

}
});
},
down: (queryInterface, Sequelize) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'Sequelize' is defined but never used no-unused-vars
Unexpected block statement surrounding arrow body; move the returned value immediately after the => arrow-body-style

@@ -0,0 +1,44 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected block statement surrounding arrow body; move the returned value immediately after the => arrow-body-style

@@ -0,0 +1,44 @@
'use strict';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected newline after "use strict" directive lines-around-directive
'use strict' is unnecessary inside of modules strict

},
{
where: { userId },
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected a newline before ')' function-paren-newline

});
return PaymentController.PaymentResponse(res);
}
Payment.update({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected a newline after '(' function-paren-newline

@coveralls
Copy link

coveralls commented Sep 3, 2018

Pull Request Test Coverage Report for Build 378

  • 129 of 139 (92.81%) changed or added relevant lines in 12 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.8%) to 90.579%

Changes Missing Coverage Covered Lines Changed/Added Lines %
server/v1/controllers/PaymentController.js 44 46 95.65%
server/v1/controllers/CommentController.js 40 48 83.33%
Totals Coverage Status
Change from base Build 344: 0.8%
Covered Lines: 714
Relevant Lines: 776

💛 - Coveralls

- fix hound issues
- modify test

[Delivers #159762182]
- improve test coverage removing redundant codes

[Delivers #159762182]
…ntId-error

#160216041 fix app crash on comment reply creation with invalid parentId
Copy link
Contributor

@Oluwafayokemi Oluwafayokemi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job! @yomigeek. Well done

Copy link
Contributor

@Veraclins Veraclins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yomigeek nice job here. Just check out my comments and implement the feedback where necessary.

.then((response) => {
const { id: userId, email } = req.user;
const transactionValues = response.body.data;
const subscriptionType = transactionValues.amount === SUBSCRIPTION_RATE ? 'month' : 'annual';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yomigeek nice job here and quite expressive. I feel the SUBSCRIPTION_RATE constant should be MONTHLY_SUBSCRIPTION_RATE to add context and make the comparable unambiguous.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this notification, I would implement this change..

});
}

static ProcessUpgrade(paymentInfo, res) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why there is a ProcessUpgrade method and no method to create a payment? I see that you are actually creating the payment if none is found and updating otherwise. Don't you think ProcessUpgrade may not really be the best method name? I believe processPayment could be a better name. That could include both creating and upgrading the payment and still be descriptive of the whole action. Also, your method name is not in camelCase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad as regards the camelCasing issue, I will implement the change. As regards the method name, I used that because the whole process is all about upgrading a user from a free account to a premium account.

* @param {object} next the next middleware function

*/
const checkReference = (req, res, next) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why this is implemented as a middleware instead of as a method in the controller? Given that it is used in just a single place I feel that it is better as a method in the PaymentController. This way everything about the payment is contained in a single place. (Single Responsibility Principle).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I did that to avoid longer codes to in the validate controller, more or less like every aspect having its own purpose within the whole process.

- add new models based on recent modification to accomodate article subscription
- modify the user and article model to accomodate subscription and updates
- modify the payment controller file

[Delivers #159762182]
if (transactionValues.status === 'successful' && transactionValues['customer.email'] === email) {
return PaymentController.accountUpgradeProcessor(
{ userId, reference, subscriptionType }, res
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected newline before ')' function-paren-newline

const transactionValues = response.body.data;
const subscriptionType = transactionValues.amount === MONTHLY_SUBSCRIPTION_RATE ? 'month' : 'annual';
if (transactionValues.status === 'successful' && transactionValues['customer.email'] === email) {
return PaymentController.accountUpgradeProcessor(

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

- add more units
- modify payment controller

[Delivers #159762182]
Copy link
Contributor

@Veraclins Veraclins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yomigeek you have done a nice job here. I particularly love the way you arranged the methods in the order of their invocation. This makes it very easy to understand the flow of operation. There are, however, a few areas I feel you may want to look into.

  1. One of the recommendations for writing clean codes is to use verbs (or actions) for method names. This you did well with the checkPaymentType method, however, I feel you can reword the other method names. For instance, accountUpgrade could be upgradeAccount, accountUpgradeProcessor could be processAccountUpgrade, etc.
  2. Since all the failed payment responses return 400 status code, don't you think that defining them everywhere is rather an unnecessary repetition? I believe you can use the number (like you did for success responses) in the method itself.
  3. On line 111, I see that you are checking that an articleId is supplied but you are not checking that the supplied id is a number. This could cause database errors which would break the app.
  4. The userSubscriptionDetailUpdate method was declared to take two arguments but you called it on line 75 without any argument. How does that work?
  5. Finally, you may want to check the comments (docs) for successPaymentResponse and failedPaymentResponse. From their description in the comments, they seem to be doing exactly what userSubscriptionDetailUpdate does.
    Once again, nice job bro.

- add more unit tests
- modify payment controller file

[Deliver #159762182]
@yomigeek
Copy link
Contributor Author

yomigeek commented Sep 6, 2018

@Veraclins Thanks for the reviews you gave earlier. Reviews and changes have been implemented as deemed necessary...

chore(readme): add api docs link and update url

- add link to the API docs and update the url on the readme file to reflect the versioning

[Finishes #160127137]
Copy link
Contributor

@madeofhuman madeofhuman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You did a really great work here, Yomi, especially given the changing scope of the task. Well done! Just address the conflicts arising from my PR merge and we're golden.

- add a sketchy UI for checking of the process
- add a payment model
- add a payment controller
- install the flutterwave rave package
- modify payment controller file
- modify payment model
- add more unit tests
- create a check payment refeerence middleware
- modify payment controller file

[Delivers #159762182]
- fix hound issues
- modify test

[Delivers #159762182]
- improve test coverage removing redundant codes

[Delivers #159762182]
- add new models based on recent modification to accomodate article subscription
- modify the user and article model to accomodate subscription and updates
- modify the payment controller file

[Delivers #159762182]
- add more units
- modify payment controller

[Delivers #159762182]
- add more unit tests
- modify payment controller file

[Deliver #159762182]
- make changes to files and folder structures to acoomodate api versioning

[Delivers #159762182]
- fix merge issues on branch

[Delivers #159762182]
Copy link
Contributor

@tonymontaro tonymontaro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work!

@tonymontaro tonymontaro merged commit c177165 into staging Sep 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants