diff --git a/src/constants/experiments.js b/src/constants/experiments.js
index f89aad963..b702b11bb 100644
--- a/src/constants/experiments.js
+++ b/src/constants/experiments.js
@@ -6,6 +6,8 @@ const experimentSettings = {
GOOGLE_CUSTOM_DIMENSION_INDEX: "Google Custom Dimension Index",
SUPPRESS_VIN_CAPTURE: "SuppressVinCapture",
DISPLAY_AVAILABILITY_INDICATORS: "DisplayAvailabilityIndicators",
+ PIA_EXPERIENCE: "PIA Experience",
+ SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA",
};
const experimentTriggers = {
diff --git a/src/constants/payment-method-constants.js b/src/constants/payment-method-constants.js
new file mode 100644
index 000000000..807e44c0e
--- /dev/null
+++ b/src/constants/payment-method-constants.js
@@ -0,0 +1,13 @@
+export const paymentMethods = {
+ NONE: null,
+ LATER: "Later",
+ CREDIT_CARD: "CreditCard",
+ PAYPAL: "Paypal",
+ AFTERPAY: "Afterpay",
+};
+
+export const paymentTimes = {
+ NONE: null,
+ ADVANCE: "Advance",
+ LATER: "Later",
+};
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 000000000..8cf6c55bb
--- /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 000000000..2763f1af9
--- /dev/null
+++ b/src/layouts/payment-method/payment-method-question/payment-method-list-button/payment-method-list-button.vue
@@ -0,0 +1,123 @@
+
+
+
+
![]()
+
+
+
+
+
+ {{ getInlineAltText(token) }}
+
+
+ {{ token }}
+
+
+
+
+
+
+
+
+
+
+
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 000000000..d3a486d57
--- /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 000000000..473e36114
--- /dev/null
+++ b/src/layouts/payment-method/payment-method-question/payment-method-question.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/payment-method/payment-method.spec.js b/src/layouts/payment-method/payment-method.spec.js
index 130a2def4..803f10829 100644
--- a/src/layouts/payment-method/payment-method.spec.js
+++ b/src/layouts/payment-method/payment-method.spec.js
@@ -5,6 +5,7 @@ import customerDetails from "@/layouts/payment-method/payment-method.vue";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
+import { experimentSettings } from "@/constants/experiments";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
@@ -15,6 +16,8 @@ jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
submitWorkOrder: jest.fn(),
}));
+let piaDisabledFlag = false;
+
describe("payment-method.vue", () => {
describe("navigation", () => {
test("if the back button is clicked, navigate back", async () => {
@@ -52,19 +55,37 @@ function setupMocks() {
},
};
- const wrapper = shallowMount(
- customerDetails,
- getMountOptions({
- router: {
- navigate: jest.fn(),
- navigateWithSaving: jest.fn(),
- navigateWithoutSaving: jest.fn(),
- },
- store: {
- getters: store.getters,
- },
- })
- );
+ const mountOptions = getMountOptions({
+ router: {
+ navigate: jest.fn(),
+ navigateWithSaving: jest.fn(),
+ navigateWithoutSaving: jest.fn(),
+ },
+ store: {
+ getters: store.getters,
+ },
+ });
+
+ const mockMixin = {
+ methods: {
+ getSettingValue: jest.fn((settingName) => {
+ if (!piaDisabledFlag) {
+ if (settingName === experimentSettings.PIA_EXPERIENCE) {
+ return "PIA Optional";
+ }
+ if (settingName === experimentSettings.SUBMIT_ORDER_ENABLE_PIA) {
+ return "true";
+ }
+ }
+
+ return "false";
+ }),
+ },
+ };
+
+ mountOptions.global.mixins = [mockMixin];
+
+ const wrapper = shallowMount(customerDetails, mountOptions);
return { wrapper };
}
diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue
index 28fe0fd31..eac00fe15 100644
--- a/src/layouts/payment-method/payment-method.vue
+++ b/src/layouts/payment-method/payment-method.vue
@@ -38,46 +38,13 @@
:rainDefenseItem="availableRainDefense"
vapsTilesCmsName="VapsProductTiles" />
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/store/index.js b/src/store/index.js
index add9f355f..2c2eb8492 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -598,7 +598,10 @@ export const getters = {
funnelServiceCity: state.order.serviceLocation.city,
funnelServiceState: state.order.serviceLocation.state,
funnelServiceZipCode: state.order.serviceLocation.zipCode,
+ funnelServiceZipCodeCtu: state.order.serviceLocation.zipCodeCtu,
+ funnelProviderNumber: state.order.serviceLocation.provider.providerNumber,
funnelParentAccountNumber: state.order.payment.parentAccountNumber,
+ funnelReferralType: state.order.payment.isInsurance ? "INSURANCE" : "CASH QUOTE",
funnelIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified,
funnelHasRecalibrationPart: getHasRecalibrationPart(state),
funnelSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1,
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index d55862e3e..9ae8065ae 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -2934,6 +2934,9 @@ describe("Getters", () => {
funnelSupportingItems: null,
funnelVaps: null,
funnelGlassToReplace: null,
+ funnelProviderNumber: "1",
+ funnelReferralType: "CASH QUOTE",
+ funnelServiceZipCodeCtu: "11111",
};
//Act
@@ -2948,12 +2951,17 @@ describe("Getters", () => {
city: mockStateValues.funnelServiceCity,
state: mockStateValues.funnelServiceState,
zipCode: mockStateValues.funnelServiceZipCode,
+ zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
+ provider: {
+ providerNumber: mockStateValues.funnelProviderNumber,
+ },
});
mutations.updateParentAcctNumber(storeState, mockStateValues.funnelParentAccountNumber);
mutations.updateInsuranceVerifiedStatus(
storeState,
mockStateValues.funnelIsCoverageVerified
);
+ mutations.updateIsInsurance(storeState, false);
mutations.updateGlassParts(storeState, mockStateValues.funnelGlassParts);
mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems);
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
@@ -2981,6 +2989,9 @@ describe("Getters", () => {
funnelSelectedBackGlass: false,
funnelSelectedDriverSideGlass: false,
funnelSelectedPassengerSideGlass: false,
+ funnelProviderNumber: mockStateValues.funnelProviderNumber,
+ funnelReferralType: mockStateValues.funnelReferralType,
+ funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
});
});
@@ -3003,6 +3014,9 @@ describe("Getters", () => {
funnelGlassParts: [],
funnelOtherParts: [],
funnelGlassToReplace: [],
+ funnelProviderNumber: "1",
+ funnelReferralType: "CASH QUOTE",
+ funnelServiceZipCodeCtu: "11111",
};
//Act
@@ -3017,12 +3031,17 @@ describe("Getters", () => {
city: mockStateValues.funnelServiceCity,
state: mockStateValues.funnelServiceState,
zipCode: mockStateValues.funnelServiceZipCode,
+ zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
+ provider: {
+ providerNumber: mockStateValues.funnelProviderNumber,
+ },
});
mutations.updateParentAcctNumber(storeState, mockStateValues.funnelParentAccountNumber);
mutations.updateInsuranceVerifiedStatus(
storeState,
mockStateValues.funnelIsCoverageVerified
);
+ mutations.updateIsInsurance(storeState, false);
mutations.updateGlassParts(storeState, mockStateValues.funnelGlassParts);
mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems);
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
@@ -3050,6 +3069,9 @@ describe("Getters", () => {
funnelSelectedBackGlass: false,
funnelSelectedDriverSideGlass: false,
funnelSelectedPassengerSideGlass: false,
+ funnelProviderNumber: mockStateValues.funnelProviderNumber,
+ funnelReferralType: mockStateValues.funnelReferralType,
+ funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
});
});
@@ -3085,6 +3107,9 @@ describe("Getters", () => {
glassName: "Single",
},
],
+ funnelProviderNumber: "1",
+ funnelReferralType: "CASH QUOTE",
+ funnelServiceZipCodeCtu: "11111",
};
//Act
@@ -3099,9 +3124,14 @@ describe("Getters", () => {
city: mockStateValues.serviceCity,
state: mockStateValues.serviceState,
zipCode: mockStateValues.serviceZipCode,
+ zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
+ provider: {
+ providerNumber: mockStateValues.funnelProviderNumber,
+ },
});
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
+ mutations.updateIsInsurance(storeState, false);
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems);
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
@@ -3129,6 +3159,9 @@ describe("Getters", () => {
funnelSelectedBackGlass: false,
funnelSelectedDriverSideGlass: false,
funnelSelectedPassengerSideGlass: false,
+ funnelProviderNumber: mockStateValues.funnelProviderNumber,
+ funnelReferralType: mockStateValues.funnelReferralType,
+ funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
});
});
@@ -3190,6 +3223,9 @@ describe("Getters", () => {
glassName: "Quarter",
},
],
+ funnelProviderNumber: "1",
+ funnelReferralType: "CASH QUOTE",
+ funnelServiceZipCodeCtu: "11111",
};
//Act
@@ -3204,9 +3240,14 @@ describe("Getters", () => {
city: mockStateValues.serviceCity,
state: mockStateValues.serviceState,
zipCode: mockStateValues.serviceZipCode,
+ zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
+ provider: {
+ providerNumber: mockStateValues.funnelProviderNumber,
+ },
});
mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber);
mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified);
+ mutations.updateIsInsurance(storeState, false);
mutations.updateGlassParts(storeState, mockStateValues.glassParts);
mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems);
mutations.updateVaps(storeState, mockStateValues.funnelVaps);
@@ -3234,6 +3275,9 @@ describe("Getters", () => {
funnelSelectedBackGlass: true,
funnelSelectedDriverSideGlass: true,
funnelSelectedPassengerSideGlass: true,
+ funnelProviderNumber: mockStateValues.funnelProviderNumber,
+ funnelReferralType: mockStateValues.funnelReferralType,
+ funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu,
});
});
});