Skip to content

Commit

Permalink
Fix merge conflicts.
Browse files Browse the repository at this point in the history
  • Loading branch information
wjames111 committed Dec 17, 2024
2 parents e2a7f3f + 57360ce commit dc1be1d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ class ExistingPaymentMethodsController {
if (this.creditCardPaymentForm && this.creditCardPaymentForm.securityCode) {
unregister()
this.addCvvValidators()
this.switchPayment()
}
})
}

addCvvValidators () {
this.$scope.$watch('$ctrl.creditCardPaymentForm.securityCode.$viewValue', (number) => {
this.creditCardPaymentForm.securityCode.$validators.minLength = cruPayments.creditCard.cvv.validate.minLength
this.creditCardPaymentForm.securityCode.$validators.maxLength = cruPayments.creditCard.cvv.validate.maxLength

this.enableContinue({ $event: cruPayments.creditCard.cvv.validate.minLength(number) && cruPayments.creditCard.cvv.validate.maxLength(number) })
this.selectedPaymentMethod.cvv = number
if (this.selectedPaymentMethod?.['card-type'] && this.creditCardPaymentForm.securityCode) {
this.creditCardPaymentForm.securityCode.$validators.minLength = cruPayments.creditCard.cvv.validate.minLength
this.creditCardPaymentForm.securityCode.$validators.maxLength = cruPayments.creditCard.cvv.validate.maxLength
this.enableContinue({ $event: cruPayments.creditCard.cvv.validate.minLength(number) && cruPayments.creditCard.cvv.validate.maxLength(number) })
this.selectedPaymentMethod.cvv = number
}
})
}

Expand Down Expand Up @@ -103,7 +105,7 @@ class ExistingPaymentMethodsController {
// Select the first payment method
this.selectedPaymentMethod = paymentMethods[0]
}

this.shouldRecoverCvv = true
this.switchPayment()
}

Expand Down Expand Up @@ -155,14 +157,12 @@ class ExistingPaymentMethodsController {
switchPayment () {
this.onPaymentChange({ selectedPaymentMethod: this.selectedPaymentMethod })
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)] || '' : ''
// Set CVV to new credit card CVV
this.creditCardPaymentForm.securityCode.$setViewValue(getSelectedCvv)
// Set cvv from session storage
const storage = this.shouldRecoverCvv ? JSON.parse(this.sessionStorage.getItem('cvv')) : ''
this.creditCardPaymentForm.securityCode.$setViewValue(storage)
this.creditCardPaymentForm.securityCode.$render()
this.shouldRecoverCvv = false
}

if (this.selectedPaymentMethod?.['bank-name']) {
// This is an EFT payment method so we need to remove any fee coverage
this.orderService.storeCoverFeeDecision(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ describe('checkout', () => {
}
},
selectedPaymentMethod: {
cvv: ''
cvv: '',
'card-type': 'Visa'
}
})
self.$window = $window
Expand Down Expand Up @@ -350,82 +351,53 @@ describe('checkout', () => {
})

it('should reset securityCode viewValue', () => {
self.controller.creditCardPaymentForm.securityCode.$viewValue = '123'
self.controller.selectedPaymentMethod = { 'card-type': 'Visa', self: { type: 'cru.creditcards.named-credit-card', uri: 'selected uri' }, selectAction: 'some uri' }
self.controller.switchPayment()

expect(self.controller.creditCardPaymentForm.securityCode.$setViewValue).toHaveBeenCalledWith('')
expect(self.controller.creditCardPaymentForm.securityCode.$render).toHaveBeenCalled()
})

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'
}
self.$window.sessionStorage.setItem(
'storedCvvs',
'{"/paymentmethods/crugive/giydsnjqgi=":"456","/paymentmethods/crugive/giydsnjqgy=":"321"}'
'cvv',
'456'
)
self.controller.shouldRecoverCvv = true
self.controller.switchPayment()

expect(self.controller.creditCardPaymentForm.securityCode.$setViewValue).toHaveBeenCalledWith('456')
expect(self.controller.creditCardPaymentForm.securityCode.$render).toHaveBeenCalled()
})

it('should not 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'
}
self.$window.sessionStorage.setItem(
'storedCvvs',
'{"/paymentmethods/crugive/giydsnjqgs=":"456","/paymentmethods/crugive/giydsnjqgy=":"321"}'
)
self.controller.switchPayment()

expect(self.controller.creditCardPaymentForm.securityCode.$setViewValue).toHaveBeenCalledWith('')
expect(self.controller.creditCardPaymentForm.securityCode.$setViewValue).toHaveBeenCalledWith(456)
expect(self.controller.creditCardPaymentForm.securityCode.$render).toHaveBeenCalled()
})
})

describe('addCvvValidators', () => {
it('should add validator functions to creditCardPaymentForm.securityCode', () => {
jest.spyOn(self.controller, 'addCvvValidators').mockImplementation(() => {
self.controller.creditCardPaymentForm.securityCode.$validators = {
minLength: cruPayments.creditCard.cvv.validate.minLength,
maxLength: cruPayments.creditCard.cvv.validate.maxLength
}
})
delete self.controller.creditCardPaymentForm
self.controller.waitForFormInitialization()
self.controller.$scope.$digest()

expect(self.controller.addCvvValidators).not.toHaveBeenCalled()
it('should add a watch on the security code value', () => {
self.controller.creditCardPaymentForm = {
$valid: true,
$dirty: false,
securityCode: {
$viewValue: '123',
$validators: {}
}
}
self.controller.addCvvValidators()
expect(self.controller.$scope.$$watchers.length).toEqual(1)
expect(self.controller.$scope.$$watchers[0].exp).toEqual('$ctrl.creditCardPaymentForm.securityCode.$viewValue')
})

it('should add validator functions to creditCardPaymentForm.securityCode', () => {
jest.spyOn(self.controller, 'addCvvValidators')
self.controller.selectedPaymentMethod.self = {
type: 'cru.creditcards.named-credit-card',
uri: 'selected uri'
}
self.controller.waitForFormInitialization()
self.controller.$scope.$digest()

expect(self.controller.addCvvValidators).toHaveBeenCalled()
expect(Object.keys(self.controller.creditCardPaymentForm.securityCode.$validators).length).toEqual(2)
expect(typeof self.controller.creditCardPaymentForm.securityCode.$validators.minLength).toBe('function')
expect(typeof self.controller.creditCardPaymentForm.securityCode.$validators.maxLength).toBe('function')

})

it('should call enableContinue when cvv is valid', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
<div class="panel panel-default tab-toggle mb0">
<div class="panel panel-default tab-toggle mb0 existing-payment-method">
<div class="panel-title panel-heading">
<span translate>Your Payment Methods</span>
<i class="fas fa-lock u-floatRight mt--"></i>
</div>

<div class="panel-body">
<div class="radio radio-method" ng-repeat="paymentMethod in $ctrl.paymentMethods" ng-init="expired = !$ctrl.validPaymentMethod(paymentMethod)">
<label>
<input type="radio" name="paymentMethod" ng-model="$ctrl.selectedPaymentMethod" ng-value="paymentMethod" ng-disabled="expired" required ng-change="$ctrl.switchPayment()">
<payment-method-display payment-method="paymentMethod" expired="expired"></payment-method-display>
<button class="btn btn-xs btn-link" ng-click="$ctrl.openPaymentMethodFormModal(paymentMethod)" ng-if="paymentMethod['card-type']" translate>edit</button>
</label>
</div>
<div ng-if="$ctrl.selectedPaymentMethod['card-type']" class="row">
<div class="col-sm-4">
<form novalidate name="$ctrl.creditCardPaymentForm">
<credit-card-cvv ></credit-card-cvv>
</form>
<form novalidate name="$ctrl.creditCardPaymentForm">
<div class="radio radio-method saved-payment-methods" ng-repeat="paymentMethod in $ctrl.paymentMethods" ng-init="expired = !$ctrl.validPaymentMethod(paymentMethod)">
<div class="row">
<label>
<input type="radio" name="paymentMethod" ng-model="$ctrl.selectedPaymentMethod" ng-value="paymentMethod" ng-disabled="expired" required ng-change="$ctrl.switchPayment()">
<payment-method-display payment-method="paymentMethod" expired="expired"></payment-method-display>
<button class="btn btn-xs btn-link" ng-click="$ctrl.openPaymentMethodFormModal(paymentMethod)" ng-if="paymentMethod['card-type']" translate>edit</button>
</label>
<span ng-if="$ctrl.selectedPaymentMethod['card-type'] && $ctrl.selectedPaymentMethod === paymentMethod">
<credit-card-cvv ></credit-card-cvv>
</span>
</div>
</div>
</div>
</form>

<div class="panel panel-default tab-toggle mb0 mt"
ng-if="(($ctrl.cartData && $ctrl.cartData.items) || $ctrl.brandedCheckoutItem) && $ctrl.selectedPaymentMethod && $ctrl.selectedPaymentMethod['card-type']">
<div class="panel-title panel-heading" translate>{{'OPTIONAL'}}</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/checkout/step-2/step-2.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Step2Controller {
this.onStateChange({ state: 'submitted' })
this.paymentFormState = 'success'
} else if ($event.state === 'submitted') {
// this.orderService.storeCardSecurityCode(this.selectedPaymentMethod.cvv, this.selectedPaymentMethod.self.uri)
this.orderService.storeCardSecurityCode(this.selectedPaymentMethod.cvv, this.selectedPaymentMethod.self.uri)
} else if ($event.state === 'unsubmitted') {
this.onStateChange({ state: 'unsubmitted' })
} else if ($event.state === 'error') {
Expand Down
1 change: 1 addition & 0 deletions src/app/checkout/step-2/step-2.component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ describe('checkout', () => {

it('should update paymentFormState if transitioning to a different state', () => {
self.controller.paymentFormState = 'unsubmitted'
self.controller.selectedPaymentMethod = { cvv: '123', self: { uri: 'uri'} }
self.controller.onPaymentFormStateChange({ state: 'submitted' })

expect(self.controller.paymentFormState).toEqual('submitted')
Expand Down
3 changes: 1 addition & 2 deletions src/app/checkout/step-2/step-2.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
hide-payment-type-options="$ctrl.hidePaymentTypeOptions"
cart-data="$ctrl.cartData"
branded-checkout-item="$ctrl.brandedCheckoutItem"
enable-continue="$ctrl.enableContinue($event)"
>
enable-continue="$ctrl.enableContinue($event)">
</checkout-existing-payment-methods>
</div>
</div>
Expand Down
32 changes: 18 additions & 14 deletions src/common/directives/creditCardCvv.directive.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import angular from 'angular'

import './creditCardCvv.directive.scss'
const directiveName = 'creditCardCvv'

const template =
`<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'">
`<div class="credit-card-cvv-container form-group" ng-class="{'has-error': ($ctrl.creditCardPaymentForm.securityCode | showErrors), 'is-required': !$ctrl.paymentMethod}">
<span class="credit-card-cvv-label" translate>{{'SEC_CODE'}}</span>
<div>
<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="credit-card-cvv-help-block help-block" ng-message="required" translate>{{'CARD_SEC_CODE_ERROR'}}</div>
<div class="credit-card-cvv-help-block help-block" ng-message="minLength" translate>{{'MIN_LENGTH_CARD_SEC_CODE'}}</div>
<div class="credit-card-cvv-help-block help-block" ng-message="maxLength" translate>{{'MAX_LENGTH_CARD_SEC_CODE'}}</div>
<div class="credit-card-cvv-help-block 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>
</div>`
Expand Down
48 changes: 48 additions & 0 deletions src/common/directives/creditCardCvv.directive.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@

.radio.radio-method {
.credit-card-cvv-container {
display: flex;
margin: 8px 20px 8px 38px;
.col-sm-4 {
padding-left: 10px;
padding-right: 0;
}
.form-control {
line-height: 1.6;
height: auto;
}
.credit-card-cvv-label {
margin-top: 9px;
margin-right: 9px;
font-size: 15px;
line-height: 1.2em;
font-weight: bold;
white-space: nowrap;
&::after {
content: ':';
}
}
.credit-card-cvv-help-block {
margin-bottom: 0;
}
}
}

.give-modal-content, .branded-checkout {
.credit-card-cvv-label {
text-transform: uppercase;
font-weight: 500;
letter-spacing: 1px;
font-size: 14px;
display: block;
margin-bottom: 4px;
&::after {
content: '*';
display: inline-block;
font-size: 115%;
line-height: 0;
font-family: "fontawesome", "Font Awesome 5 Pro";
margin-left: 6px;
}
}
}

0 comments on commit dc1be1d

Please sign in to comment.