From 4464058005ca1d2998a87d0273add64db88e38cf Mon Sep 17 00:00:00 2001 From: Bill Randall Date: Wed, 8 Jan 2025 17:26:10 -0500 Subject: [PATCH] Turn checkout service into an Angular service --- src/app/branded/branded-checkout.component.js | 5 +- src/app/branded/branded-checkout.spec.js | 7 +- src/app/checkout/checkout.component.js | 5 +- src/app/checkout/checkout.spec.js | 4 +- .../checkoutHelpers/checkout.service.js | 28 ++++-- .../checkoutHelpers/checkout.service.spec.js | 87 +++++++++++-------- 6 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/app/branded/branded-checkout.component.js b/src/app/branded/branded-checkout.component.js index c7d06d355..f35a832f0 100644 --- a/src/app/branded/branded-checkout.component.js +++ b/src/app/branded/branded-checkout.component.js @@ -13,7 +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 checkoutService from 'common/services/checkoutHelpers/checkout.service' import brandedAnalyticsFactory from './analytics/branded-analytics.factory' import 'common/lib/fakeLocalStorage' @@ -24,7 +24,7 @@ const componentName = 'brandedCheckout' class BrandedCheckoutController { /* @ngInject */ - constructor ($element, $window, analyticsFactory, brandedAnalyticsFactory, tsysService, sessionService, envService, orderService, $translate) { + constructor ($element, $window, analyticsFactory, brandedAnalyticsFactory, tsysService, sessionService, envService, orderService, checkoutService, $translate) { this.$element = $element[0] // extract the DOM element from the jqLite wrapper this.$window = $window this.analyticsFactory = analyticsFactory @@ -156,6 +156,7 @@ export default angular thankYouSummary.name, sessionService.name, orderService.name, + checkoutService.name, brandedAnalyticsFactory.name, uibModal, 'environment', diff --git a/src/app/branded/branded-checkout.spec.js b/src/app/branded/branded-checkout.spec.js index 5502e4370..b4f4d2b76 100644 --- a/src/app/branded/branded-checkout.spec.js +++ b/src/app/branded/branded-checkout.spec.js @@ -51,12 +51,13 @@ describe('branded checkout', () => { onOrderFailed: jest.fn(), }, ) - $ctrl.checkoutService = { - initializeRecaptcha: jest.fn() - } })) describe('$onInit', () => { + beforeEach(() => { + jest.spyOn($ctrl.checkoutService, 'initializeRecaptcha').mockImplementation(() => {}) + }) + it('should set API Url if custom one is set', () => { $ctrl.apiUrl = 'https://custom-api.cru.org' $ctrl.$onInit() diff --git a/src/app/checkout/checkout.component.js b/src/app/checkout/checkout.component.js index 64c96abe5..03b21ec76 100644 --- a/src/app/checkout/checkout.component.js +++ b/src/app/checkout/checkout.component.js @@ -14,7 +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 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' @@ -28,7 +28,7 @@ const componentName = 'checkout' class CheckoutController { /* @ngInject */ - constructor ($window, $location, $rootScope, $log, cartService, envService, orderService, designationsService, sessionEnforcerService, analyticsFactory) { + constructor ($window, $location, $rootScope, $log, cartService, envService, orderService, designationsService, sessionEnforcerService, checkoutService, analyticsFactory) { this.$log = $log this.$window = $window this.$location = $location @@ -150,6 +150,7 @@ export default angular orderService.name, designationsService.name, sessionEnforcerService.name, + checkoutService.name, showErrors.name, analyticsFactory.name ]) diff --git a/src/app/checkout/checkout.spec.js b/src/app/checkout/checkout.spec.js index 716ce8be5..fcb7d38ed 100644 --- a/src/app/checkout/checkout.spec.js +++ b/src/app/checkout/checkout.spec.js @@ -19,9 +19,6 @@ describe('checkout', function () { search: '' }, scrollTo: jest.fn() } }) - self.controller.checkoutService = { - initializeRecaptcha: jest.fn() - } })) it('to be defined', function () { @@ -38,6 +35,7 @@ describe('checkout', function () { jest.spyOn(self.controller, 'sessionEnforcerService').mockImplementation(() => {}) jest.spyOn(self.controller.$rootScope, '$on').mockImplementation(() => {}) jest.spyOn(self.controller, 'signedOut').mockImplementation(() => {}) + jest.spyOn(self.controller.checkoutService, 'initializeRecaptcha').mockImplementation(() => {}) self.controller.$onInit() }) diff --git a/src/common/services/checkoutHelpers/checkout.service.js b/src/common/services/checkoutHelpers/checkout.service.js index 0efbe89d2..3e2729a67 100644 --- a/src/common/services/checkoutHelpers/checkout.service.js +++ b/src/common/services/checkoutHelpers/checkout.service.js @@ -1,8 +1,24 @@ -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) +import angular from 'angular' + +const serviceName = 'checkoutService' + +class CheckoutService { + /* @ngInject */ + constructor ($window, envService) { + this.$window = $window + this.envService = envService + } + + 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) + } } } + +export default angular + .module(serviceName, []) + .service(serviceName, CheckoutService) diff --git a/src/common/services/checkoutHelpers/checkout.service.spec.js b/src/common/services/checkoutHelpers/checkout.service.spec.js index 883d2770c..afa230a8e 100644 --- a/src/common/services/checkoutHelpers/checkout.service.spec.js +++ b/src/common/services/checkoutHelpers/checkout.service.spec.js @@ -1,42 +1,55 @@ -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') - }) +import angular from 'angular' +import 'angular-mocks' - afterEach(() => { - const foundScript = document.getElementById('give-checkout-recaptcha') - if (foundScript) { - document.head.removeChild(foundScript) - } - }) +import module from './checkout.service' - 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() - }) +describe('checkout service', () => { + beforeEach(angular.mock.module(module.name)) + + beforeEach(angular.mock.module(($provide) => { + $provide.value('envService', { + read: () => '123' + }) + })) + + const self = {} + let script + + beforeEach(inject((checkoutService, envService, $window) => { + self.checkoutService = checkoutService + self.envService = envService + self.$window = $window + self.$window.document = document - 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) + script = self.$window.document.createElement('script') + })) + + describe('initializeRecaptcha()', () => { + beforeEach(() => { + script.src = 'https://www.google.com/recaptcha/enterprise.js?render=123' + script.id = 'test-script' + }) + + afterEach(() => { + const foundScript = self.$window.document.getElementById('give-checkout-recaptcha') + if (foundScript) { + document.head.removeChild(foundScript) + } + }) + + it('should add a script even if one already exists', () => { + self.$window.document.head.appendChild(script) + self.checkoutService.initializeRecaptcha.call(self) + 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' + self.$window.document.head.appendChild(script) + expect(document.getElementById('give-checkout-recaptcha')).not.toBeNull() + self.checkoutService.initializeRecaptcha.call(self) + expect(document.querySelectorAll('#give-checkout-recaptcha')).toHaveLength(1) + }) }) }) -