From 5559033c41a231daf3a23d4aa29a2a4b78c050f7 Mon Sep 17 00:00:00 2001 From: Matt Caimi Date: Thu, 1 Feb 2024 13:40:30 -0500 Subject: [PATCH 01/10] SSR-1064 payment method pia options --- src/constants/payment-method-constants.js | 7 + src/iss-components/nav-bar/nav-bar.spec.js | 59 +++++++ src/iss-components/nav-bar/nav-bar.vue | 163 ++++++++++++++++++ .../payment-method-list-button.spec.js | 104 +++++++++++ .../payment-method-list-button.vue | 123 +++++++++++++ .../payment-method-question.spec.js | 130 ++++++++++++++ .../payment-method-question.vue | 82 +++++++++ src/layouts/payment-method/payment-method.vue | 118 +++++++++++-- src/store/index.js | 13 +- 9 files changed, 785 insertions(+), 14 deletions(-) create mode 100644 src/constants/payment-method-constants.js create mode 100644 src/iss-components/nav-bar/nav-bar.spec.js create mode 100644 src/iss-components/nav-bar/nav-bar.vue create mode 100644 src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js create mode 100644 src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue create mode 100644 src/layouts/payment-method/payment-method-question/payment-method-question.spec.js create mode 100644 src/layouts/payment-method/payment-method-question/payment-method-question.vue diff --git a/src/constants/payment-method-constants.js b/src/constants/payment-method-constants.js new file mode 100644 index 00000000..0799f2b2 --- /dev/null +++ b/src/constants/payment-method-constants.js @@ -0,0 +1,7 @@ +export const paymentMethods = { + NONE: null, + LATER: "Later", + CREDIT_CARD: "CreditCard", + PAYPAL: "Paypal", + AFTERPAY: "Afterpay", +}; diff --git a/src/iss-components/nav-bar/nav-bar.spec.js b/src/iss-components/nav-bar/nav-bar.spec.js new file mode 100644 index 00000000..68b9f6c8 --- /dev/null +++ b/src/iss-components/nav-bar/nav-bar.spec.js @@ -0,0 +1,59 @@ +import { mount } from "@vue/test-utils"; +import navbar from "./nav-bar"; + +describe("nav-bar.vue", () => { + test("Should emit ForwardClicked on button click", async () => { + // Act + const wrapper = mount(navbar, { + mixins: [mockMixin], + }); + wrapper.vm.buttonClick(); + // Assert + expect(wrapper.emitted()["ForwardClicked"][0]).toHaveBeenCalled; + }); + + test("Should emit BackClicked on link click", async () => { + // Act + const wrapper = mount(navbar, { + mixins: [mockMixin], + }); + wrapper.vm.linkClick(); + // Assert + expect(wrapper.emitted()["BackClicked"][0]).toHaveBeenCalled; + }); + + test("Should change button text when update button text is called", async () => { + // Act + const wrapper = mount(navbar, { + mixins: [mockMixin], + }); + wrapper.vm.updateButtonText("newText"); + + // Assert + expect(wrapper.componentVM.customButtontext).toBe("newText"); + }); + + test("should run removeLoader fn on buttonMain and return false for onkeydown fn", async () => { + // Arrange + const wrapper = mount(navbar, { + mixins: [mockMixin], + }); + + // Act + wrapper.vm.$refs.buttonMain.removeLoader = jest.fn(); + wrapper.vm.removeLoader(); + const spy = jest.spyOn(document, "onkeydown"); + document.onkeydown(); + + // Assert + expect(wrapper.vm.$refs.buttonMain.removeLoader).toHaveBeenCalled(); + expect(spy).toReturnWith(true); + }); +}); + +const mockMixin = { + methods: { + getCmsContent: jest.fn(), + getFooterInfoBoxHeight: jest.fn(() => 80), + }, +}; diff --git a/src/iss-components/nav-bar/nav-bar.vue b/src/iss-components/nav-bar/nav-bar.vue new file mode 100644 index 00000000..631e5c0e --- /dev/null +++ b/src/iss-components/nav-bar/nav-bar.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js new file mode 100644 index 00000000..8cf6c55b --- /dev/null +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js @@ -0,0 +1,104 @@ +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; + +import paymentMethodListButton from "@/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button"; + +const testConstants = { + images: { + A: "imageA", + B: "imageB", + NONE: null, + }, + names: { + A: "nameA", + B: "nameB", + }, + content: { + withInline: "Button text with {custom:inlineImage} inline.", + noInline: "Button text with no inline", + }, +}; + +let cmsContent; + +describe("Payment Method Question", () => { + beforeEach(() => { + cmsContent = {}; + }); + + describe("Side image", () => { + it("Renders side image if image is present and not inline", () => { + // Arrange + const props = generateDefaultProps(); + const { wrapper } = setupMocks({ + propsData: props, + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(true); + }); + + it("Does not render side image if no image is present", () => { + // Arrange + let props = generateDefaultProps(); + + props.buttonImage = testConstants.images.NONE; + + const { wrapper } = setupMocks({ + propsData: props, + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(false); + }); + + it("Does not render side image if inline", () => { + // Arrange + let props = generateDefaultProps(); + + props.buttonLabel = testConstants.content.withInline; + props.altText = testConstants.content.withInline; + + const { wrapper } = setupMocks({ + propsData: props, + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(false); + }); + }); +}); + +function generateDefaultProps() { + return { + buttonLabel: testConstants.noInline, + altText: testConstants.noInline, + groupName: "payment-method", + value: testConstants.names.A, + buttonImage: testConstants.images.A, + }; +} + +function setupMocks(customMountOptions) { + const mountOptions = getMountOptions(customMountOptions); + + const mockMixin = { + methods: { + getCmsContent: jest.fn((widgetName, cmsFieldName) => { + return cmsContent?.[widgetName]?.[cmsFieldName] ?? ""; + }), + }, + }; + + mountOptions.global.mixins = [mockMixin]; + + const wrapper = shallowMount(paymentMethodListButton, mountOptions); + wrapper.vm.setCmsContent = jest.fn(); + return { wrapper }; +} diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue new file mode 100644 index 00000000..2763f1af --- /dev/null +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/layouts/payment-method/payment-method-question/payment-method-question.spec.js b/src/layouts/payment-method/payment-method-question/payment-method-question.spec.js new file mode 100644 index 00000000..d3a486d5 --- /dev/null +++ b/src/layouts/payment-method/payment-method-question/payment-method-question.spec.js @@ -0,0 +1,130 @@ +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; + +import paymentMethodQuestion from "@/layouts/payment-method/payment-method-question/payment-method-question"; + +const testConstants = { + cms: { + question: { + text: "Choose a payment option", + }, + answers: { + optionA: { + name: "NameA", + text: "TextA", + subText: "SubTextA", + imageId: "idA", + image: "imageA", + subWidget: "subWidgetA", + }, + optionB: { + name: "NameB", + text: "TextB", + subText: "SubTextB", + imageId: "idB", + image: "imageB", + subWidget: "subWidgetB", + }, + }, + }, +}; + +let cmsContent; + +describe("Payment Method Question", () => { + beforeEach(() => { + cmsContent = { + PaymentMethodWidget: { + QuestionText: testConstants.cms.question, + Answers: [ + { + Name: testConstants.cms.answers.optionA.name, + Text: testConstants.cms.answers.optionA.text, + SubText: testConstants.cms.answers.optionA.subText, + ImageId: testConstants.cms.answers.optionA.imageId, + AnswerImageUrl: testConstants.cms.answers.optionA.image, + SubWidgetName: testConstants.cms.answers.optionA.subWidget, + }, + { + Name: testConstants.cms.answers.optionB.name, + Text: testConstants.cms.answers.optionB.text, + SubText: testConstants.cms.answers.optionB.subText, + ImageId: testConstants.cms.answers.optionB.imageId, + AnswerImageUrl: testConstants.cms.answers.optionB.image, + SubWidgetName: testConstants.cms.answers.optionB.subWidget, + }, + ], + }, + }; + }); + + it("Should map cms content correctly", () => { + // Arrange + const props = generateDefaultProps(); + + const { wrapper } = setupMocks({ + propsData: props, + }); + + // Act + const mappedContent = wrapper.vm.paymentMethodAnswerData; + + // Assert + expect(mappedContent).toEqual([ + { + buttonLabel: testConstants.cms.answers.optionA.text, + altText: testConstants.cms.answers.optionA.text, + groupName: "payment-method", + value: testConstants.cms.answers.optionA.name, + buttonImage: testConstants.cms.answers.optionA.image, + }, + { + buttonLabel: testConstants.cms.answers.optionB.text, + altText: testConstants.cms.answers.optionB.text, + groupName: "payment-method", + value: testConstants.cms.answers.optionB.name, + buttonImage: testConstants.cms.answers.optionB.image, + }, + ]); + }); + + it("Handles null cms content gracefully", () => { + // Arrange + cmsContent = {}; + const props = generateDefaultProps(); + + const { wrapper } = setupMocks({ + propsData: props, + }); + + // Act + const mappedContent = wrapper.vm.paymentMethodAnswerData; + + // Assert + expect(mappedContent).toEqual([]); + }); +}); + +function generateDefaultProps() { + return { + modelValue: "modelValue", + }; +} + +function setupMocks(customMountOptions) { + const mountOptions = getMountOptions(customMountOptions); + + const mockMixin = { + methods: { + getCmsContent: jest.fn((widgetName, cmsFieldName) => { + return cmsContent?.[widgetName]?.[cmsFieldName] ?? ""; + }), + }, + }; + + mountOptions.global.mixins = [mockMixin]; + + const wrapper = shallowMount(paymentMethodQuestion, mountOptions); + wrapper.vm.setCmsContent = jest.fn(); + return { wrapper }; +} diff --git a/src/layouts/payment-method/payment-method-question/payment-method-question.vue b/src/layouts/payment-method/payment-method-question/payment-method-question.vue new file mode 100644 index 00000000..bbd0617b --- /dev/null +++ b/src/layouts/payment-method/payment-method-question/payment-method-question.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index a7ca3dba..190e82c5 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -4,6 +4,7 @@ v-slot="{ meta }" @submit="onSubmit" @invalidSubmit="onInvalidSubmit"> +
Cart Placeholder

Pia Alert Placeholder
-
Payment Method Question
+
Pia Disabled Placeholder
- @@ -39,14 +43,17 @@ diff --git a/src/store/index.js b/src/store/index.js index a4e9f04d..fe6538cd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -13,6 +13,7 @@ import damageLocationsSelected from '@/constants/damage-locations-selected'; import coverageStatuses from '@/constants/coverage-statuses'; import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from '@/constants/schedule-constants'; import { convertDateStringToDate, getDateDifferenceInDays, militaryToTwelveHourTime } from '@/helpers/date-helper'; +import { paymentMethods } from "@/constants/payment-method-constants"; const storeId = 'main'; @@ -147,7 +148,9 @@ const getDefaultState = () => ({ coverageStatus: coverageStatuses.PENDING, claimNumber: null }, - parentAccountNumber: 0 + parentAccountNumber: 0, + isPia: null, + piaType: null, }, contactInfo: { firstName: null, @@ -2127,7 +2130,13 @@ export const useMainStore = defineStore({ this.resetVehicleState(); this.resetDamageState(); this.resetBailout(); - } + }, + + savePaymentMethodChoice(paymentMethod) { + const isPia = paymentMethod !== paymentMethods.LATER; + this.order.payment.isPia = isPia; + this.order.payment.piaType = isPia ? paymentMethod : null; + }, }, persist: true From 462e4f93376e5e490bd6ebb1d611f08da237358b Mon Sep 17 00:00:00 2001 From: Matt Caimi Date: Thu, 1 Feb 2024 15:17:16 -0500 Subject: [PATCH 02/10] SSR-1064 linting --- src/constants/payment-method-constants.js | 8 +- src/iss-components/nav-bar/nav-bar.spec.js | 46 +++--- src/iss-components/nav-bar/nav-bar.vue | 43 +++--- .../payment-method-list-button.spec.js | 139 +++++++++--------- .../payment-method-list-button.vue | 38 ++--- .../payment-method-question.spec.js | 101 +++++++------ .../payment-method-question.vue | 56 +++---- src/layouts/payment-method/payment-method.vue | 58 +++----- src/store/index.js | 4 +- 9 files changed, 241 insertions(+), 252 deletions(-) diff --git a/src/constants/payment-method-constants.js b/src/constants/payment-method-constants.js index 0799f2b2..8f0ee825 100644 --- a/src/constants/payment-method-constants.js +++ b/src/constants/payment-method-constants.js @@ -1,7 +1,7 @@ export const paymentMethods = { NONE: null, - LATER: "Later", - CREDIT_CARD: "CreditCard", - PAYPAL: "Paypal", - AFTERPAY: "Afterpay", + LATER: 'Later', + CREDIT_CARD: 'CreditCard', + PAYPAL: 'Paypal', + AFTERPAY: 'Afterpay' }; diff --git a/src/iss-components/nav-bar/nav-bar.spec.js b/src/iss-components/nav-bar/nav-bar.spec.js index 68b9f6c8..bfd921a9 100644 --- a/src/iss-components/nav-bar/nav-bar.spec.js +++ b/src/iss-components/nav-bar/nav-bar.spec.js @@ -1,48 +1,55 @@ -import { mount } from "@vue/test-utils"; -import navbar from "./nav-bar"; +import { mount } from '@vue/test-utils'; +import navbar from './nav-bar'; -describe("nav-bar.vue", () => { - test("Should emit ForwardClicked on button click", async () => { +const mockMixin = { + methods: { + getCmsContent: jest.fn(), + getFooterInfoBoxHeight: jest.fn(() => 80) + } +}; + +describe('nav-bar.vue', () => { + test('Should emit ForwardClicked on button click', async () => { // Act const wrapper = mount(navbar, { - mixins: [mockMixin], + mixins: [mockMixin] }); wrapper.vm.buttonClick(); // Assert - expect(wrapper.emitted()["ForwardClicked"][0]).toHaveBeenCalled; + expect(wrapper.emitted()['ForwardClicked'][0]).toHaveBeenCalled; }); - test("Should emit BackClicked on link click", async () => { + test('Should emit BackClicked on link click', async () => { // Act const wrapper = mount(navbar, { - mixins: [mockMixin], + mixins: [mockMixin] }); wrapper.vm.linkClick(); // Assert - expect(wrapper.emitted()["BackClicked"][0]).toHaveBeenCalled; + expect(wrapper.emitted()['BackClicked'][0]).toHaveBeenCalled; }); - test("Should change button text when update button text is called", async () => { + test('Should change button text when update button text is called', async () => { // Act const wrapper = mount(navbar, { - mixins: [mockMixin], + mixins: [mockMixin] }); - wrapper.vm.updateButtonText("newText"); + wrapper.vm.updateButtonText('newText'); // Assert - expect(wrapper.componentVM.customButtontext).toBe("newText"); + expect(wrapper.componentVM.customButtontext).toBe('newText'); }); - test("should run removeLoader fn on buttonMain and return false for onkeydown fn", async () => { + test('should run removeLoader fn on buttonMain and return false for onkeydown fn', async () => { // Arrange const wrapper = mount(navbar, { - mixins: [mockMixin], + mixins: [mockMixin] }); // Act wrapper.vm.$refs.buttonMain.removeLoader = jest.fn(); wrapper.vm.removeLoader(); - const spy = jest.spyOn(document, "onkeydown"); + const spy = jest.spyOn(document, 'onkeydown'); document.onkeydown(); // Assert @@ -50,10 +57,3 @@ describe("nav-bar.vue", () => { expect(spy).toReturnWith(true); }); }); - -const mockMixin = { - methods: { - getCmsContent: jest.fn(), - getFooterInfoBoxHeight: jest.fn(() => 80), - }, -}; diff --git a/src/iss-components/nav-bar/nav-bar.vue b/src/iss-components/nav-bar/nav-bar.vue index 631e5c0e..67b107ee 100644 --- a/src/iss-components/nav-bar/nav-bar.vue +++ b/src/iss-components/nav-bar/nav-bar.vue @@ -43,41 +43,40 @@ diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js index 8cf6c55b..523e10ba 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.spec.js @@ -1,87 +1,34 @@ -import { shallowMount } from "@vue/test-utils"; -import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { shallowMount } from '@vue/test-utils'; +import { getMountOptions } from '@/helpers/unit-test-helper.js'; -import paymentMethodListButton from "@/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button"; +// eslint-disable-next-line max-len +import paymentMethodListButton from '@/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue'; const testConstants = { images: { - A: "imageA", - B: "imageB", - NONE: null, + A: 'imageA', + B: 'imageB', + NONE: null }, names: { - A: "nameA", - B: "nameB", + A: 'nameA', + B: 'nameB' }, content: { - withInline: "Button text with {custom:inlineImage} inline.", - noInline: "Button text with no inline", + withInline: 'Button text with {custom:inlineImage} inline.', + noInline: 'Button text with no inline' }, }; let cmsContent; -describe("Payment Method Question", () => { - beforeEach(() => { - cmsContent = {}; - }); - - describe("Side image", () => { - it("Renders side image if image is present and not inline", () => { - // Arrange - const props = generateDefaultProps(); - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - const showSideImage = wrapper.vm.shouldDisplaySideImage; - - expect(showSideImage).toBe(true); - }); - - it("Does not render side image if no image is present", () => { - // Arrange - let props = generateDefaultProps(); - - props.buttonImage = testConstants.images.NONE; - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - const showSideImage = wrapper.vm.shouldDisplaySideImage; - - expect(showSideImage).toBe(false); - }); - - it("Does not render side image if inline", () => { - // Arrange - let props = generateDefaultProps(); - - props.buttonLabel = testConstants.content.withInline; - props.altText = testConstants.content.withInline; - - const { wrapper } = setupMocks({ - propsData: props, - }); - - // Act - const showSideImage = wrapper.vm.shouldDisplaySideImage; - - expect(showSideImage).toBe(false); - }); - }); -}); - function generateDefaultProps() { return { buttonLabel: testConstants.noInline, altText: testConstants.noInline, - groupName: "payment-method", + groupName: 'payment-method', value: testConstants.names.A, - buttonImage: testConstants.images.A, + buttonImage: testConstants.images.A }; } @@ -91,9 +38,9 @@ function setupMocks(customMountOptions) { const mockMixin = { methods: { getCmsContent: jest.fn((widgetName, cmsFieldName) => { - return cmsContent?.[widgetName]?.[cmsFieldName] ?? ""; - }), - }, + return cmsContent?.[widgetName]?.[cmsFieldName] ?? ''; + }) + } }; mountOptions.global.mixins = [mockMixin]; @@ -102,3 +49,57 @@ function setupMocks(customMountOptions) { wrapper.vm.setCmsContent = jest.fn(); return { wrapper }; } + +describe('Payment Method Question', () => { + beforeEach(() => { + cmsContent = {}; + }); + + describe('Side image', () => { + it('Renders side image if image is present and not inline', () => { + // Arrange + const props = generateDefaultProps(); + const { wrapper } = setupMocks({ + propsData: props + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(true); + }); + + it('Does not render side image if no image is present', () => { + // Arrange + const props = generateDefaultProps(); + + props.buttonImage = testConstants.images.NONE; + + const { wrapper } = setupMocks({ + propsData: props + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(false); + }); + + it('Does not render side image if inline', () => { + // Arrange + const props = generateDefaultProps(); + + props.buttonLabel = testConstants.content.withInline; + props.altText = testConstants.content.withInline; + + const { wrapper } = setupMocks({ + propsData: props + }); + + // Act + const showSideImage = wrapper.vm.shouldDisplaySideImage; + + expect(showSideImage).toBe(false); + }); + }); +}); diff --git a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue index 2763f1af..871f8ba7 100644 --- a/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue +++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue @@ -1,8 +1,8 @@