269 lines
9.4 KiB
JavaScript
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 };
|
|
}
|