428 lines
16 KiB
JavaScript
428 lines
16 KiB
JavaScript
import { mount, flushPromises } from "@vue/test-utils";
|
|
import saveProgressPopupQuestion from "./save-progress-popup-question";
|
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
import { storeActions } from "@/constants/store-actions";
|
|
import { saveQuote } from "@/helpers/heritage-integration/order-helper.js";
|
|
|
|
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: {
|
|
closeModal: jest.fn(),
|
|
resetButtonStyle: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
describe("save-progress-popup-question ", () => {
|
|
describe("when closeModal is run ", () => {
|
|
test("the modal should close ", () => {
|
|
// Arrange
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "testModal",
|
|
},
|
|
});
|
|
|
|
// Act
|
|
wrapper.vm.closeModal();
|
|
|
|
// Assert
|
|
expect(wrapper.vm.modal).not.toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("contact method tabs", () => {
|
|
test("should default to the email tab", () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
expect(wrapper.vm.isPhoneTabSelected).toBe(false);
|
|
});
|
|
|
|
test("should use tab labels from phone and email specific CMS widgets", () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
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 disclaimer BodyText from the selected tab widget", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
cmsContent: {
|
|
SaveProgressPopupWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
|
|
SaveProgressPopupWidget_EmailSpecific: { BodyText: "Email disclaimer" },
|
|
},
|
|
});
|
|
|
|
expect(wrapper.vm.modalDisclaimerText).toBe("Email disclaimer");
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.modalDisclaimerText).toBe("Phone disclaimer");
|
|
});
|
|
|
|
test("should use phone question CMS widget on the phone tab", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.phoneQuestionWidgetName).toBe("SaveProgressPopupPhoneQuestionWidget");
|
|
});
|
|
|
|
test("should show email content when the email tab is selected", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
expect(wrapper.vm.contactMethod).toBe("EmailAnswer");
|
|
expect(wrapper.vm.isPhoneTabSelected).toBe(false);
|
|
expect(wrapper.vm.emailQuestionWidgetName).toBe("SaveProgressPopupEmailQuestionWidget");
|
|
});
|
|
|
|
test("should show phone content when the phone tab is selected", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.contactMethod).toBe("PhoneAnswer");
|
|
expect(wrapper.vm.isPhoneTabSelected).toBe(true);
|
|
expect(wrapper.vm.userInput).toBe("");
|
|
});
|
|
|
|
test("should reset sms consent when switching tabs", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.smsConsent = { transactional: true, marketing: true };
|
|
wrapper.vm.showConsentErrors = true;
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.smsConsent).toEqual({ transactional: false, marketing: false });
|
|
expect(wrapper.vm.showConsentErrors).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("validatePhoneAndSave", () => {
|
|
test("should show consent errors when phone is valid but no consent is selected", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
wrapper.vm.modal.validate = jest.fn().mockResolvedValue({ valid: true });
|
|
const resetSpy = jest.spyOn(wrapper.vm, "resetPhoneSendButtonStyle");
|
|
const scrollSpy = jest
|
|
.spyOn(wrapper.vm, "scrollConsentIntoView")
|
|
.mockResolvedValue(undefined);
|
|
|
|
await wrapper.vm.validatePhoneAndSave();
|
|
|
|
expect(wrapper.vm.showConsentErrors).toBe(true);
|
|
expect(scrollSpy).toHaveBeenCalled();
|
|
expect(resetSpy).toHaveBeenCalled();
|
|
});
|
|
|
|
test("should scroll consent checkboxes into view", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
const mockScrollIntoView = jest.fn();
|
|
const consentEl = document.createElement("fieldset");
|
|
consentEl.className = "save-progress-popup-sms-consent";
|
|
consentEl.scrollIntoView = mockScrollIntoView;
|
|
wrapper.element.appendChild(consentEl);
|
|
|
|
await wrapper.vm.scrollConsentIntoView();
|
|
|
|
expect(mockScrollIntoView).toHaveBeenCalledWith({
|
|
behavior: "smooth",
|
|
block: "nearest",
|
|
});
|
|
});
|
|
|
|
test("should reset the send button loader when phone validation fails", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
wrapper.vm.modal.validate = jest.fn().mockResolvedValue({ valid: false });
|
|
const resetSpy = jest.spyOn(wrapper.vm, "resetPhoneSendButtonStyle");
|
|
|
|
await wrapper.vm.validatePhoneAndSave();
|
|
|
|
expect(wrapper.vm.showConsentErrors).toBe(false);
|
|
expect(resetSpy).toHaveBeenCalled();
|
|
});
|
|
|
|
test("should save when phone and consent are valid", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
await flushPromises();
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
wrapper.vm.userInput = "555-123-4567";
|
|
wrapper.vm.smsConsent = { transactional: true, marketing: false };
|
|
wrapper.vm.modal.validate = jest.fn().mockResolvedValue({ valid: true });
|
|
const resetSpy = jest.spyOn(wrapper.vm, "resetPhoneSendButtonStyle");
|
|
|
|
await wrapper.vm.validatePhoneAndSave();
|
|
|
|
expect(wrapper.vm.showConsentErrors).toBe(false);
|
|
expect(wrapper.vm.isProgressSaved).toBe(true);
|
|
expect(resetSpy).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("footer button suppression", () => {
|
|
test("should suppress the modal footer button on the phone tab", async () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.isFooterButtonSuppressed).toBe(true);
|
|
});
|
|
|
|
test("should show the modal footer button on the email tab before save", () => {
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
},
|
|
});
|
|
|
|
expect(wrapper.vm.isFooterButtonSuppressed).toBe(false);
|
|
});
|
|
|
|
test("should suppress the modal footer button after a successful email save", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.userInput = "test@example.com";
|
|
|
|
await wrapper.vm.saveProgress();
|
|
|
|
expect(wrapper.vm.isFooterButtonSuppressed).toBe(true);
|
|
});
|
|
|
|
test("should reset the modal footer button loader before suppressing it after save", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.userInput = "test@example.com";
|
|
wrapper.vm.modal.resetButtonStyle = jest.fn();
|
|
|
|
await wrapper.vm.saveProgress();
|
|
|
|
expect(wrapper.vm.modal.resetButtonStyle).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("saveProgress", () => {
|
|
test("should save phone number and sms consent when phone tab is selected", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
wrapper.vm.userInput = "555-123-4567";
|
|
wrapper.vm.smsConsent = { transactional: true, marketing: false };
|
|
|
|
await wrapper.vm.saveProgress();
|
|
|
|
expect(dispatchStoreAction).toHaveBeenCalledWith(
|
|
storeActions.SAVE_PHONE_NUMBER,
|
|
"5551234567",
|
|
false
|
|
);
|
|
expect(dispatchStoreAction).not.toHaveBeenCalledWith(
|
|
storeActions.SAVE_EMAIL,
|
|
expect.anything(),
|
|
false
|
|
);
|
|
expect(dispatchStoreAction).toHaveBeenCalledWith(
|
|
storeActions.SAVE_IS_SMS_OPT_IN,
|
|
true,
|
|
false
|
|
);
|
|
expect(saveQuote).toHaveBeenCalledWith({ pageNameToLog: "quote" });
|
|
expect(wrapper.vm.isProgressSaved).toBe(true);
|
|
expect(wrapper.vm.savedContactMethod).toBe("PhoneAnswer");
|
|
});
|
|
|
|
test("should save email when email tab is selected", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.userInput = "test@example.com";
|
|
|
|
await wrapper.vm.saveProgress();
|
|
|
|
expect(dispatchStoreAction).toHaveBeenCalledWith(
|
|
storeActions.SAVE_EMAIL,
|
|
"test@example.com",
|
|
false
|
|
);
|
|
expect(dispatchStoreAction).not.toHaveBeenCalledWith(
|
|
storeActions.SAVE_PHONE_NUMBER,
|
|
expect.anything(),
|
|
false
|
|
);
|
|
expect(saveQuote).toHaveBeenCalledWith({ pageNameToLog: "quote" });
|
|
expect(wrapper.vm.savedContactMethod).toBe("EmailAnswer");
|
|
});
|
|
|
|
test("should not allow switching tabs after a successful phone save", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
wrapper.vm.userInput = "555-123-4567";
|
|
wrapper.vm.smsConsent = { transactional: true, marketing: false };
|
|
|
|
await wrapper.vm.saveProgress();
|
|
wrapper.vm.selectContactMethod("EmailAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.contactMethod).toBe("PhoneAnswer");
|
|
expect(wrapper.vm.isContactMethodTabDisabled("EmailAnswer")).toBe(true);
|
|
expect(wrapper.vm.isContactMethodTabDisabled("PhoneAnswer")).toBe(false);
|
|
});
|
|
|
|
test("should not allow switching tabs after a successful email save", async () => {
|
|
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
|
|
const { wrapper } = setupMocks({
|
|
props: {
|
|
modalWidgetName: "SaveProgressPopupWidget",
|
|
pageName: "quote",
|
|
},
|
|
});
|
|
|
|
wrapper.vm.dispatchStoreAction = dispatchStoreAction;
|
|
wrapper.vm.userInput = "test@example.com";
|
|
|
|
await wrapper.vm.saveProgress();
|
|
wrapper.vm.selectContactMethod("PhoneAnswer");
|
|
await wrapper.vm.$nextTick();
|
|
|
|
expect(wrapper.vm.contactMethod).toBe("EmailAnswer");
|
|
expect(wrapper.vm.isContactMethodTabDisabled("PhoneAnswer")).toBe(true);
|
|
expect(wrapper.vm.isContactMethodTabDisabled("EmailAnswer")).toBe(false);
|
|
});
|
|
});
|
|
});
|
|
|
|
function setupMocks({ options, props, cmsContent = {} }) {
|
|
const mountOptions = getMountOptions({
|
|
...options,
|
|
});
|
|
|
|
const mockBaseMixin = {
|
|
methods: {
|
|
getCmsContent: jest.fn(
|
|
(widgetName, fieldName) => cmsContent[widgetName]?.[fieldName] ?? ""
|
|
),
|
|
dispatchStoreAction: jest.fn(),
|
|
},
|
|
};
|
|
|
|
if (props) mountOptions.propsData = props;
|
|
|
|
mountOptions.global.mixins = [mockBaseMixin];
|
|
|
|
const wrapper = mount(saveProgressPopupQuestion, mountOptions);
|
|
|
|
return { wrapper };
|
|
}
|