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

Updates hideCvv flag for edit payment methods and new payment methods. #1109

Open
wants to merge 40 commits into
base: master
Choose a base branch
from

Conversation

wjames111
Copy link

OKR: Implement real-time CVV validation on all transactions for Give App

@wjames111 wjames111 self-assigned this Oct 28, 2024
@wjames111 wjames111 added the On Staging Will be merged to the staging branch by Github Actions label Oct 28, 2024
@wjames111
Copy link
Author

@wrandall22 I'm having some difficulty with this one. I need to validate that the CVV is correct when paying with a saved card. I added a save payment method that is essentially just ripped from creditCardForm.component.js. I haven’t been able to get it working though which isn't surprising seeing as I'm not entirely sure what all is going on in that code block. Do you have any pointers for me/is this the right way of going about it?

@wrandall22
Copy link
Contributor

So, there are a few things.

  1. You should probably make the changes in existingPaymentMethods instead of in paymentMethodDisplay since the first is only used in checkout and the latter is used in several places we don't want to capture cvv.
  2. The validation is happening, but is not preventing the user from moving forward, which means we need to hook into the continue button on checkout step 2 and ensure that the validation passes there before moving forward.
  3. The Angular way of re-using the cvv template/controller code is to create a directive and put it in both places. We have several directives in the codebase already which you can reference (even creditCardNumber has one). This would be a way to not copy/paste code and maintain it in two places.

@wjames111
Copy link
Author

@wrandall22 thank you this is really helpful. One question, do we only need the validators on the CVV? I would assume we need to ensure the CVV is also correct for the given credit card before allowing them to move forward. That was what I was trying to accomplish with the savePayment method, although it didn't appear to be working.

@wrandall22
Copy link
Contributor

The CVV is the only thing being entered, so is the only thing being validated in this situation. That validation can live in the directive.

@wjames111
Copy link
Author

Ahh okay that makes things a bit easier.

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

Great work on this PR!

Just a note: before merging with staging, can you run yarn lint:write? This will ensure the lint issues are fixed or bring attention to code that needs to be changed. This way, your changes on staging will be deployed to the staging site.

@dr-bizz dr-bizz removed the On Staging Will be merged to the staging branch by Github Actions label Nov 8, 2024
@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

Removing the on staging label for now. Once everything is working on this branch, feel free to add it back

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

It seems like it wasn't just you, there were some other changes from other PRs that caused staging to fail being deployed.

@wjames111
Copy link
Author

@dr-bizz thanks that make me feel better. Sorry about that, I didn't realize it was causing issues. It's not quite ready for staging either.

@wrandall22
Copy link
Contributor

You can turn it into a draft PR until it's ready if you want.

@dr-bizz
Copy link
Contributor

dr-bizz commented Nov 8, 2024

It's all good. This is where amplify previews would come in handy

@wjames111 wjames111 marked this pull request as draft November 8, 2024 16:05
@wjames111
Copy link
Author

@wrandall22 is this more what you had in mind? Do you know where else the directive needs to be used apart from existingPaymentMethods?

@wrandall22
Copy link
Contributor

Hey Will, thanks for working on this. I was more thinking of putting this part of the HTML in the directive:

<div class="form-group" ng-class="{'has-error': ($ctrl.creditCardPaymentForm.securityCode | showErrors), 'is-required': !$ctrl.paymentMethod}">
          <label translate>{{'SEC_CODE'}}</label>
          <input type="text"
                 name="securityCode"
                 autocomplete="cc-csc"
                 class="form-control form-control-subtle"
                 ng-model="$ctrl.creditCardPayment.securityCode"
                 ng-required="!$ctrl.paymentMethod || $ctrl.creditCardPayment.cardNumber"
                 ng-attr-placeholder="{{$ctrl.paymentMethod && !$ctrl.creditCardPayment.cardNumber ? '***' : ''}}">
          <div role="alert" ng-messages="$ctrl.creditCardPaymentForm.securityCode.$error" ng-if="($ctrl.creditCardPaymentForm.securityCode | showErrors)">
            <div class="help-block" ng-message="required" translate>{{'CARD_SEC_CODE_ERROR'}}</div>
            <div class="help-block" ng-message="minLength" translate>{{'MIN_LENGTH_CARD_SEC_CODE'}}</div>
            <div class="help-block" ng-message="maxLength" translate>{{'MAX_LENGTH_CARD_SEC_CODE'}}</div>
            <div class="help-block" ng-message="cardTypeLength" ng-init="isAmex = $ctrl.cardInfo.type($ctrl.creditCardPayment.cardNumber) === 'American Express'">
              <translate ng-if="!isAmex">{{'LOCATION_OF_CODE_OTHER'}}</translate>
              <translate ng-if="isAmex">{{'LOCATION_OF_CODE_AMEX'}}</translate>
            </div>
          </div>
        </div>

Then using it in both creditCardForm and existingPaymentMethods

@wjames111
Copy link
Author

@wrandall22 is this a little more what you had in mind? I was initially trying to validate within the directive itself, but it ended up being easier to just use the directive for the template and use the validators that were already in place.

@wrandall22
Copy link
Contributor

Yep, this is the direction I was thinking.

@wjames111
Copy link
Author

@wrandall22 okay great! I'll fix it up.

@wjames111 wjames111 added the On Staging Will be merged to the staging branch by Github Actions label Nov 19, 2024
@wjames111 wjames111 marked this pull request as ready for review November 19, 2024 20:42
@wjames111 wjames111 removed the On Staging Will be merged to the staging branch by Github Actions label Nov 20, 2024
Copy link
Contributor

@wrandall22 wrandall22 left a comment

Choose a reason for hiding this comment

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

I got part way through the review, this is a good start. I'm going to play around a little bit with the directive locally as well.

@wjames111
Copy link
Author

Thanks @wrandall22! I'll get started on these changes.

if (this.selectedPaymentMethod?.['card-type'] && this.creditCardPaymentForm?.securityCode) {
const selectedUri = this.selectedPaymentMethod.self.uri
const storage = JSON.parse(this.sessionStorage.getItem('storedCvvs'))
const getSelectedCvv = storage ? storage[Object.keys(storage).filter((item) => item === selectedUri)] : false
Copy link
Contributor

Choose a reason for hiding this comment

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

If you use '' instead of false you don't need the conditional below.

Copy link
Author

Choose a reason for hiding this comment

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

Oh nice I like that!


it('should add securityCode viewValue from sessionStorage', () => {
self.controller.creditCardPaymentForm.securityCode.$viewValue = '123'
self.controller.selectedPaymentMethod = { 'card-type': 'Visa', self: { type: 'cru.creditcards.named-credit-card', uri: '/paymentmethods/crugive/giydsnjqgi=' }, selectAction: 'some uri' }
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is a bit too long, let's break it up to multiple lines.

Copy link
Contributor

@dr-bizz dr-bizz left a comment

Choose a reason for hiding this comment

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

Thank you for thinking the error on the checkout. I have review the code again and made some comments, but they are only small things.

I did test the security code on the checkout and found it didn't matter what value I added, it always allowed me to continue. Should that be the case, or are you just taking the input on step 2, and then checking it when the user submits the checkout?

@@ -116,7 +116,10 @@ class Step2Controller {
}
}

getContinueDisabled () {
isContinueDisabled () {
if (this.selectedPaymentMethod?.['card-type'] && typeof this.isCvvValid !== 'undefined' && !this.isCvvValid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

so if isCvvValid is undefined we enable the continue button?

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it that if there are no CC to ensure they are valid, we don't disable the button, so the user isn't blocked.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see on line 129 we ensure a payment method is selected.

Copy link
Author

Choose a reason for hiding this comment

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

I may be able to take that out now but initially I added typeof this.isCvvValid !== 'undefined' so that it's not disabled before enableContinue gets called.

})

describe('existing credit card used', () => {
it('should return true when cvv is invalid', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could write it as should disable continue when cvv is invalid to make the test name quicker to understand, without the dev having to look at the test itself to understand what is is testing to return true.

Copy link
Contributor

Choose a reason for hiding this comment

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

The same could be saids for the ones below as well.

Copy link
Author

Choose a reason for hiding this comment

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

Nice, I'll update these test names.

expect(self.controller.isContinueDisabled()).toBe(false)
})

it('should return false when cvv is invalid', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Woudl you have a Cvv when you enter your bank details?

Copy link
Author

Choose a reason for hiding this comment

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

There's a cvv for new credit cards but not for new bank accounts. The this.selectedPaymentMethod?.['card-type’] in the isContinueDisabled conditional should ensure continue isn’t disabled for bank accounts. Line 346 should have the tests for this.

@wjames111
Copy link
Author

@dr-bizz Thanks for looking it over again! and yes, we're just taking the input on step 2, and then checking it when the user submits the checkout. The only issue with this is it never get's saved to session storage which Bill pointed out. I have a commit that should fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
On Staging Will be merged to the staging branch by Github Actions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants