Skip to content

Commit

Permalink
Separate out the creation of the Recaptcha script so we can put it on…
Browse files Browse the repository at this point in the history
… pages that the action is not being run on
  • Loading branch information
wrandall22 committed Dec 6, 2024
1 parent ae87a95 commit 517e012
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 67 deletions.
4 changes: 4 additions & 0 deletions src/app/branded/branded-checkout.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import thankYouSummary from 'app/thankYou/summary/thankYouSummary.component'

import sessionService from 'common/services/session/session.service'
import orderService from 'common/services/api/order.service'
import * as checkoutService from 'common/services/checkoutHelpers/checkout.service'
import brandedAnalyticsFactory from './analytics/branded-analytics.factory'

import 'common/lib/fakeLocalStorage'
Expand All @@ -33,6 +34,7 @@ class BrandedCheckoutController {
this.envService = envService
this.orderService = orderService
this.$translate = $translate
this.checkoutService = checkoutService

this.orderService.clearCoverFees()
}
Expand All @@ -57,6 +59,8 @@ class BrandedCheckoutController {
console.error(err)
})
this.$translate.use(this.language || 'en')

this.checkoutService.initializeRecaptcha.call(this)
}

formatDonorDetails () {
Expand Down
10 changes: 9 additions & 1 deletion src/app/branded/branded-checkout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ describe('branded checkout', () => {
onOrderCompleted: jest.fn(),
onOrderFailed: jest.fn(),
},
);
)
$ctrl.checkoutService = {
initializeRecaptcha: jest.fn()
}
}))

describe('$onInit', () => {
Expand All @@ -74,6 +77,11 @@ describe('branded checkout', () => {
expect($ctrl.formatDonorDetails).toHaveBeenCalled()
expect($ctrl.$window.sessionStorage.removeItem).toHaveBeenCalledWith('initialLoadComplete')
})

it('should initialize recaptcha', () => {
$ctrl.$onInit()
expect($ctrl.checkoutService.initializeRecaptcha).toHaveBeenCalled()
})
})

describe('formatDonorDetails', () => {
Expand Down
4 changes: 4 additions & 0 deletions src/app/checkout/checkout.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import showErrors from 'common/filters/showErrors.filter'
import cartService from 'common/services/api/cart.service'
import orderService from 'common/services/api/order.service'
import designationsService from 'common/services/api/designations.service'
import * as checkoutService from 'common/services/checkoutHelpers/checkout.service'

import sessionEnforcerService, { EnforcerCallbacks } from 'common/services/session/sessionEnforcer.service'
import { Roles, SignOutEvent } from 'common/services/session/session.service'
Expand All @@ -40,6 +41,7 @@ class CheckoutController {
this.loadingCartData = true
this.analyticsFactory = analyticsFactory
this.selfReference = this
this.checkoutService = checkoutService
}

$onInit () {
Expand All @@ -56,6 +58,8 @@ class CheckoutController {
this.initStepParam(true)
this.listenForLocationChange()
this.analyticsFactory.pageLoaded(true)

this.checkoutService.initializeRecaptcha.call(this)
}

$onDestroy () {
Expand Down
6 changes: 5 additions & 1 deletion src/app/checkout/checkout.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ describe('checkout', function () {
search: ''
}, scrollTo: jest.fn() }
})
self.controller.checkoutService = {
initializeRecaptcha: jest.fn()
}
}))

it('to be defined', function () {
Expand Down Expand Up @@ -53,6 +56,7 @@ describe('checkout', function () {
self.controller.$rootScope.$on.mock.calls[0][1]()

expect(self.controller.signedOut).toHaveBeenCalled()
expect(self.controller.checkoutService.initializeRecaptcha).toHaveBeenCalled()
})

describe('sessionEnforcerService success', () => {
Expand Down Expand Up @@ -118,7 +122,7 @@ describe('checkout', function () {
it('should watch the url and update the state', () => {
jest.spyOn(self.controller, 'initStepParam').mockImplementation(() => {})
jest.spyOn(self.controller.cartService, 'get').mockReturnValue(Observable.of('cartData'))
jest.spyOn(self.controller.analyticsFactory, 'checkoutStepEvent').mockImplementation(() => {})
jest.spyOn(self.controller.analyticsFactory, 'checkoutStepEvent').mockImplementation(() => {})
self.controller.listenForLocationChange()
self.controller.$location.search('step', 'review')
self.controller.$rootScope.$digest()
Expand Down
55 changes: 0 additions & 55 deletions src/common/components/Recaptcha/RecaptchaWrapper.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,9 @@ describe('RecaptchaWrapper component', () => {
execute: mockExecuteRecaptcha
}

const script = document.createElement('script')

beforeEach(() => {
$translate.instant.mockImplementation((input) => input)
global.window.grecaptcha = mockRecaptcha
script.src = 'https://www.google.com/recaptcha/api.js?render=123'
script.id = 'test-script'
})

afterEach(() => {
const foundScript = document.getElementById('give-checkout-recaptcha')
if (foundScript) {
document.head.removeChild(foundScript)
}
})

it('should render', () => {
Expand All @@ -62,49 +51,5 @@ describe('RecaptchaWrapper component', () => {
expect(recaptchaEnabledButton.className).toEqual('btn')
expect((recaptchaEnabledButton as HTMLButtonElement).disabled).toEqual(false)
expect(recaptchaEnabledButton.innerHTML).toEqual('Label')
expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull()
})

it('should add a script even if one already exists', () => {
document.head.appendChild(script)
render(
<RecaptchaWrapper
action='checkout'
onSuccess={jest.fn()}
componentInstance={{}}
buttonId='id'
buttonType={ButtonType.Submit}
buttonClasses='btn'
buttonDisabled={false}
buttonLabel='Label'
envService={envService}
$translate={$translate}
$log={$log}
/>
)
expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull()
expect(document.getElementById('test-script')).not.toBeNull()
})

it('should only add this script once', () => {
script.id = 'give-checkout-recaptcha'
document.head.appendChild(script)
expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull()
render(
<RecaptchaWrapper
action='checkout'
onSuccess={jest.fn()}
componentInstance={{}}
buttonId='id'
buttonType={ButtonType.Submit}
buttonClasses='btn'
buttonDisabled={false}
buttonLabel='Label'
envService={envService}
$translate={$translate}
$log={$log}
/>
)
expect(document.querySelectorAll('#give-checkout-recaptcha')).toHaveLength(1)
})
})
11 changes: 1 addition & 10 deletions src/common/components/Recaptcha/RecaptchaWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import angular from 'angular'
import { react2angular } from 'react2angular'
import React, { useMemo } from 'react'
import React from 'react'
import { ButtonType, Recaptcha } from './Recaptcha'

const componentName = 'recaptchaWrapper'
Expand Down Expand Up @@ -40,15 +40,6 @@ export const RecaptchaWrapper = ({
}: RecaptchaWrapperProps): JSX.Element => {
const recaptchaKey = envService.read('recaptchaKey')

useMemo(() => {
const script = document.createElement('script')
script.src = `https://www.google.com/recaptcha/enterprise.js?render=${recaptchaKey}`
script.id = 'give-checkout-recaptcha'
if (!document.getElementById(script.id)) {
document.head.appendChild(script)
}
}, [])

return (
<Recaptcha action={action}
onSuccess={onSuccess}
Expand Down
8 changes: 8 additions & 0 deletions src/common/services/checkoutHelpers/checkout.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function initializeRecaptcha () {
const script = this.$window.document.createElement('script')
script.src = `https://www.google.com/recaptcha/enterprise.js?render=${this.envService.read('recaptchaKey')}`
script.id = 'give-checkout-recaptcha'
if (!this.$window.document.getElementById(script.id)) {
this.$window.document.head.appendChild(script)
}
}
42 changes: 42 additions & 0 deletions src/common/services/checkoutHelpers/checkout.service.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as checkoutService from './checkout.service'

describe('initializeRecaptcha()', () => {
const $ctrl = {
$window: {
document: document
},
envService: {
read: jest.fn()
}
}
const script = document.createElement('script')

beforeEach(() => {
script.src = 'https://www.google.com/recaptcha/enterprise.js?render=123'
script.id = 'test-script'
$ctrl.envService.read.mockReturnValue('123')
})

afterEach(() => {
const foundScript = document.getElementById('give-checkout-recaptcha')
if (foundScript) {
document.head.removeChild(foundScript)
}
})

it('should add a script even if one already exists', () => {
document.head.appendChild(script)
checkoutService.initializeRecaptcha.call($ctrl)
expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull()
expect(document.getElementById('test-script')).not.toBeNull()
})

it('should only add this script once', () => {
script.id = 'give-checkout-recaptcha'
document.head.appendChild(script)
expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull()
checkoutService.initializeRecaptcha.call($ctrl)
expect(document.querySelectorAll('#give-checkout-recaptcha')).toHaveLength(1)
})
})

0 comments on commit 517e012

Please sign in to comment.