diff --git a/package-lock.json b/package-lock.json index 3f55ed31..5822783d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9743,9 +9743,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "dev": true, "funding": [ { @@ -18289,9 +18289,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz", - "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", "dev": true, "license": "MIT", "engines": { diff --git a/src/layouts/payment-method/payment-method.spec.js b/src/layouts/payment-method/payment-method.spec.js index edee79f9..a70be241 100644 --- a/src/layouts/payment-method/payment-method.spec.js +++ b/src/layouts/payment-method/payment-method.spec.js @@ -20,7 +20,7 @@ jest.mock('@/helpers/order-helper.js', () => ({ saveSession: jest.fn() })); -function setupMocks({ customMountOptions = {}, queryString }, mainInitialState = {}, customMixin = null) { +function setupMocks({ customMountOptions = {}, queryString }, mainInitialState = {}, customMixin = null, mockCmsContent = '') { const mountOptions = getMountOptions({ ...customMountOptions, route: { query: { issPage: issPageValues.PAYMENT_METHOD, ...queryString }, params: {} }, @@ -51,7 +51,9 @@ function setupMocks({ customMountOptions = {}, queryString }, mainInitialState = }; const cmsMixin = { methods: { - getCmsContent: jest.fn() + getCmsContent: jest.fn((widget, field) => { + return mockCmsContent; + }) } } @@ -320,4 +322,28 @@ describe('payment-method.vue', () => { expect(submitWorkOrder).toHaveBeenCalledTimes(1); }); }); + + describe('State Specific Text Rendering', () => { + test('State specific textBlock component exists when CMS content for it exists', () => { + // Arrange + const mockCmsContent = 'This is a test CMS content for state specific text.'; + const wrapper = setupMocks({}, {}, null, mockCmsContent); + + // Act + const stateSpecificTextBlock = wrapper.find('.state-specific-text'); + + // Assert + expect(stateSpecificTextBlock.exists()).toBe(true); + }); + test('State specific textBlock component does not exist when CMS content for it does not exist', () => { + // Arrange + const wrapper = setupMocks({}, {}, null, ''); + + // Act + const stateSpecificTextBlock = wrapper.find('.state-specific-text'); + + // Assert + expect(stateSpecificTextBlock.exists()).toBe(false); + }); + }); }); diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index d289df4f..5c87754a 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -19,6 +19,10 @@ +

+
+ + +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/src/layouts/schedule-page/schedule-page.spec.js b/src/layouts/schedule-page/schedule-page.spec.js index 411f7e4f..22e96af9 100644 --- a/src/layouts/schedule-page/schedule-page.spec.js +++ b/src/layouts/schedule-page/schedule-page.spec.js @@ -13,6 +13,7 @@ jest.mock('@/helpers/cms-content-helper', () => ({ })); const RECAL_ACK_MODAL_REF_NAME = 'recalAckModal'; +const BENEFIT_RECAL_MODAL_REF_NAME = 'benefitRecalModal'; const mockMixin = { methods: { @@ -74,6 +75,15 @@ const recalAckModalStub = { } }; +const benefitRecalModalStub = { + template: '
', + methods: { + openModal: jest.fn(), + footerButtonClick: jest.fn() + } +}; + + function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) { const mountOptions = getMountOptions({ router: { @@ -85,7 +95,8 @@ function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) { siteFooter: footerStub, loadingModal: loadingModalStub, serviceLocation: serviceLocationStub, - recalAckModal: recalAckModalStub + recalAckModal: recalAckModalStub, + benefitRecalModal: benefitRecalModalStub }; methodToRun(); @@ -106,6 +117,16 @@ function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) { writable: false, configurable: true }); + + // Manually create the ref for benefitRecalModal since shallowMount doesn't populate it + Object.defineProperty(wrapper.vm.$refs, BENEFIT_RECAL_MODAL_REF_NAME, { + value: { + openModal: jest.fn(), + footerButtonClick: jest.fn() + }, + writable: false, + configurable: true + }); // Manually create the ref for serviceLocation since shallowMount doesn't populate it Object.defineProperty(wrapper.vm.$refs, 'serviceLocation', { @@ -155,9 +176,8 @@ beforeEach(() => { payment: { isInsurance: true }, - lineItems: { - glassParts: [], - supportingItems: [] + issConfig: { + clientName: 'TestClient' } } } @@ -340,7 +360,7 @@ describe('schedule page methods...', () => { test('recalAckModal should open when part requires recal, but recal not added to order', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); - wrapper.vm.mainStore.lineItems.glassParts = [ + wrapper.vm.mainStore.order.lineItems.glassParts = [ { partNumber: 'TEST123', requiresRecalibration: true @@ -356,7 +376,7 @@ describe('schedule page methods...', () => { test('navigation forward is blocked when recalAckModal is displayed, but checkbox has not been acknowledged', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); - wrapper.vm.mainStore.lineItems.glassParts = [ + wrapper.vm.mainStore.order.lineItems.glassParts = [ { partNumber: 'TEST123', requiresRecalibration: true @@ -374,7 +394,7 @@ describe('schedule page methods...', () => { test('navigation forward is allowed when checkbox has been acknowledged on recalAckModal', async () => { // Arrange const { wrapper } = getShallowMountedComponent(); - wrapper.vm.mainStore.lineItems.glassParts = [ + wrapper.vm.mainStore.order.lineItems.glassParts = [ { partNumber: 'TEST123', requiresRecalibration: true @@ -390,4 +410,88 @@ describe('schedule page methods...', () => { // Assert expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); }); -}); + test('backButtonAction opens benefitRecalModal when hasBenefitRecalModal returns true and benefitRecalModalAcknowledged is false', () => { + // Arrange + const { wrapper } = getShallowMountedComponent(); + wrapper.vm.getCmsContent = jest.fn().mockReturnValue('Benefit Recalibration Modal Header'); + wrapper.vm.benefitRecalModalAcknowledged = false; + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.$refs[BENEFIT_RECAL_MODAL_REF_NAME].openModal).toHaveBeenCalled(); + }); + test('backButtonAction pushes non-recalibration_version event when opening benefitRecalModal and hasRecalibrationPart is false', () => { + // Arrange + const { wrapper } = getShallowMountedComponent(); + wrapper.vm.getCmsContent = jest.fn().mockReturnValue('Benefit Recalibration Modal Header'); + wrapper.vm.benefitRecalModalAcknowledged = false; + wrapper.vm.mainStore.order.lineItems.glassParts = [ + { + partNumber: 'TEST123', + requiresRecalibration: false + } + ]; + wrapper.vm.pushEventToGA = jest.fn(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.pushEventToGA).toHaveBeenCalledWith( + 'safelite_benefit_modal_displayed', + wrapper.vm.mainStore.accountNameForEvents, + 'non-recalibration_version', + true + ); + }); + test('backButtonAction pushes recalibration_version event when opening benefitRecalModal and hasRecalibrationPart is true', () => { + // Arrange + const { wrapper } = getShallowMountedComponent(); + wrapper.vm.getCmsContent = jest.fn().mockReturnValue('Benefit Recalibration Modal Header'); + wrapper.vm.benefitRecalModalAcknowledged = false; + wrapper.vm.mainStore.order.lineItems.glassParts = [ + { + partNumber: 'TEST123', + requiresRecalibration: true + } + ]; + wrapper.vm.pushEventToGA = jest.fn(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.pushEventToGA).toHaveBeenCalledWith( + 'safelite_benefit_modal_displayed', + wrapper.vm.mainStore.accountNameForEvents, + 'recalibration_version', + true + ); + }); + test('backButtonAction navigates back when hasBenefitRecalModal is true and benefitRecalModalAcknowledged is true', () => { + // Arrange + const { wrapper } = getShallowMountedComponent(); + wrapper.vm.getCmsContent = jest.fn().mockReturnValue('Benefit Recalibration Modal Header'); + wrapper.vm.benefitRecalModalAcknowledged = true; + wrapper.vm.navigateBack = jest.fn(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.navigateBack).toHaveBeenCalled(); + }); + test('backButtonAction navigates back when hasBenefitRecalModal is false', () => { + // Arrange + const { wrapper } = getShallowMountedComponent(); + wrapper.vm.navigateBack = jest.fn(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.navigateBack).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index 6c3af64c..43b17ba0 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -55,7 +55,7 @@ cmsWidgetName="SiteFooterWidget" :isForwardButtonHidden="!hasNeededServiceLocationData" :isForwardButtonNavigationDisabled="!isFormValid" - @backClicked="navigateBack(this, navigateBackScenario)" + @backClicked="backButtonAction" @forwardClicked="forwardButtonAction" />
@@ -69,6 +69,11 @@ cmsWidgetName="RecalAckModalWidget" :ackError="ackError" @recalAcknowledged="updateIsRecalAcknowledged"/> +