DigitalConsumer.FixMyGlass/src/fmg-components/save-progress-modal-question/save-progress-modal-question.spec.js
2026-08-03 13:20:25 -04:00

269 lines
9.4 KiB
JavaScript

import { mount } from "@vue/test-utils";
import saveProgressModalQuestion from "./save-progress-modal-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { storeActions } from "@/constants/store-actions";
import { saveProgressCmsWidgets } from "@/constants/save-progress-cms-widgets";
import { saveQuote } from "@/helpers/heritage-integration/order-helper.js";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments";
jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
saveQuote: jest.fn().mockResolvedValue(undefined),
}));
jest.mock("@/helpers/save-progress-sms-consent/save-progress-sms-consent-helper", () => ({
...jest.requireActual("@/helpers/save-progress-sms-consent/save-progress-sms-consent-helper"),
getSaveProgressSmsConsentConfig: jest.fn().mockReturnValue({
copy: {
transactional: "Sign me up for updates about my upcoming service.",
marketing: "Sign me up for promotional and product offers.",
},
value: { transactional: false, marketing: false },
}),
}));
jest.mock("@/digital-components/modal/modal", () => ({
methods: {
openModal: jest.fn(),
closeModal: jest.fn(),
resetButtonStyle: jest.fn(),
resetForm: jest.fn(),
validate: jest.fn().mockResolvedValue({ valid: true }),
},
}));
jest.mock("@/ux-components/alert/alert", () => ({
name: "alert",
template: "<div />",
}));
describe("save-progress-modal-question", () => {
beforeEach(() => {
jest.clearAllMocks();
experimentMixin.methods.hasSettingEqualTo = jest.fn().mockReturnValue(false);
});
describe("when openModal is run", () => {
test("the modal should open", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "testModal",
},
});
wrapper.vm.openModal();
expect(wrapper.vm.modal).not.toBeNull();
});
});
describe("legacy email-only mode", () => {
test("should save email to the store", async () => {
const { wrapper, dispatchStoreAction } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
pageName: "part-questions",
},
});
wrapper.vm.userInput = "test@example.com";
await wrapper.vm.saveProgress();
expect(dispatchStoreAction).toHaveBeenCalledWith(
storeActions.SAVE_EMAIL,
"test@example.com",
false
);
expect(saveQuote).toHaveBeenCalledWith({ pageNameToLog: "part-questions" });
expect(wrapper.vm.isProgressSaved).toBe(true);
});
test("should use the legacy disclaimer widget", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressModalWidget: { FooterText2: "Legacy disclaimer" },
},
});
expect(wrapper.vm.modalDisclaimerText).toBe("Legacy disclaimer");
});
});
describe("consent management mode", () => {
beforeEach(() => {
experimentMixin.methods.hasSettingEqualTo = jest
.fn()
.mockImplementation(
(settingName, settingValue) =>
settingName === experimentSettings.SHOW_CONSENT_MANAGEMENT &&
settingValue === "true"
);
});
test("should default to the phone tab when opened", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
});
wrapper.vm.openModal();
expect(wrapper.vm.isPhoneTabSelected).toBe(true);
});
test("should use popup-specific tab labels from CMS widgets", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressPopupWidget_PhoneSpecific: { HeadlineText: "PHONE" },
SaveProgressPopupWidget_EmailSpecific: { HeadlineText: "EMAIL" },
},
});
expect(wrapper.vm.contactTabs).toEqual([
{ label: "PHONE", value: "PhoneAnswer" },
{ label: "EMAIL", value: "EmailAnswer" },
]);
});
test("should use the modal question CMS widgets for phone and email inputs", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
});
expect(wrapper.vm.phoneQuestionWidgetName).toBe(
saveProgressCmsWidgets.MODAL_PHONE_QUESTION
);
expect(wrapper.vm.emailQuestionWidgetName).toBe(
saveProgressCmsWidgets.MODAL_EMAIL_QUESTION
);
});
test("should use the email-specific popup disclaimer on the email tab", async () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressPopupWidget_EmailSpecific: { BodyText: "Email disclaimer" },
SaveProgressPopupWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
},
});
wrapper.vm.selectContactMethod("EmailAnswer");
await wrapper.vm.$nextTick();
expect(wrapper.vm.modalDisclaimerText).toBe("Email disclaimer");
});
test("should use the phone-specific popup disclaimer on the phone tab", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressPopupWidget_EmailSpecific: { BodyText: "Email disclaimer" },
SaveProgressPopupWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
},
});
wrapper.vm.contactMethod = "PhoneAnswer";
expect(wrapper.vm.modalDisclaimerText).toBe("Phone disclaimer");
});
test("should show consent errors when phone is valid but transactional consent is missing", async () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
});
wrapper.vm.contactMethod = "PhoneAnswer";
wrapper.vm.userInput = "5551234567";
wrapper.vm.smsConsent = { transactional: false, marketing: false };
await wrapper.vm.validatePhoneAndSave();
expect(wrapper.vm.showConsentErrors).toBe(true);
});
test("should save phone and sms consent when valid", async () => {
const { wrapper, dispatchStoreAction } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
pageName: "vehicle-parts",
},
});
wrapper.vm.contactMethod = "PhoneAnswer";
wrapper.vm.userInput = "555-123-4567";
wrapper.vm.smsConsent = { transactional: true, marketing: true };
await wrapper.vm.saveProgress();
expect(dispatchStoreAction).toHaveBeenCalledWith(
storeActions.SAVE_PHONE_NUMBER,
"5551234567",
false
);
expect(dispatchStoreAction).toHaveBeenCalledWith(
storeActions.SAVE_IS_SMS_OPT_IN,
true,
false
);
expect(dispatchStoreAction).toHaveBeenCalledWith(
storeActions.SAVE_IS_SMS_MARKETING_OPT_IN,
true,
false
);
expect(saveQuote).toHaveBeenCalledWith({ pageNameToLog: "vehicle-parts" });
});
test("should reset sms consent when switching tabs", async () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
});
wrapper.vm.contactMethod = "PhoneAnswer";
wrapper.vm.smsConsent = { transactional: true, marketing: true };
wrapper.vm.selectContactMethod("EmailAnswer");
await wrapper.vm.$nextTick();
expect(wrapper.vm.smsConsent).toEqual({ transactional: false, marketing: false });
});
});
});
function setupMocks({ options, props, cmsContent = {} }) {
const mountOptions = getMountOptions({
...options,
});
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
const mockBaseMixin = {
methods: {
getCmsContent: jest.fn((widgetName, fieldName) => cmsContent[widgetName]?.[fieldName]),
dispatchStoreAction,
},
};
if (props) mountOptions.propsData = props;
mountOptions.global.mixins = [mockBaseMixin];
const wrapper = mount(saveProgressModalQuestion, mountOptions);
return { wrapper, dispatchStoreAction };
}