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/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue
index dbcfebdc8..7107e64e8 100644
--- a/src/fmg-components/cart/cart.vue
+++ b/src/fmg-components/cart/cart.vue
@@ -7,7 +7,7 @@
@click="toggleClass()">
@@ -110,7 +110,7 @@ export default {
return price;
},
getAmountDue() {
- return baseMixin.methods.getAmountDue(this.storeLineItems);
+ return baseMixin.methods.getDisplayAmountDue(this.storeLineItems);
},
removeItem(item) {
this.$emit("cart-remove", item);
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 eddaa6a20..ecd310c5c 100644
--- a/src/layouts/payment-method/payment-method.vue
+++ b/src/layouts/payment-method/payment-method.vue
@@ -78,8 +78,13 @@