import { shallowMount } from "@vue/test-utils"; import schedulingZipSearch from "./scheduling-zip-search"; import store from "@/store"; import { errorMessages } from "@/constants/error-messages"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { getBillToAccountNumber, getZipCodeData, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; jest.mock("@/store", () => ({ dispatch: jest.fn().mockResolvedValue(null), })); jest.mock( "@/layouts/service-location/helpers/service-location-helper/service-location-helper", () => ({ getZipCodeData: jest.fn().mockResolvedValue({ state: "OH", zipCodeCtu: "03357", }), getBillToAccountNumber: jest.fn().mockResolvedValue("87291"), }) ); const MOCK_CMS_CONTENT = { ServiceZipQuestionWidget: { QuestionText: "Service ZIP code:", }, }; function mountComponent(props = {}, cmsContent = {}) { const cmsContentByWidget = { ...MOCK_CMS_CONTENT, ...cmsContent, ServiceZipQuestionWidget: { ...MOCK_CMS_CONTENT.ServiceZipQuestionWidget, ...cmsContent.ServiceZipQuestionWidget, }, }; const cmsMixin = { methods: { getCmsContent: jest.fn((widgetName, fieldName) => { return cmsContentByWidget[widgetName]?.[fieldName] ?? ""; }), }, }; const mountOptions = getMountOptions({ route: { name: "scheduling" }, mixins: [cmsMixin], }); return shallowMount(schedulingZipSearch, { props: { modelValue: "", pageNameToLog: "scheduling", ...props, }, global: mountOptions.global, }); } describe("scheduling-zip-search.vue", () => { beforeEach(() => { jest.clearAllMocks(); }); test("prefills the zip input and CMS label from modelValue / ServiceZipQuestionWidget", () => { const wrapper = mountComponent({ modelValue: "43235" }); expect(wrapper.find("#sz-service-zip").element.value).toBe("43235"); expect(wrapper.vm.zipLabelText).toBe("Service ZIP code:"); expect(wrapper.find("label").html()).toContain("Service ZIP code:"); wrapper.unmount(); }); test("shows required error when searching with a blank zip", async () => { const wrapper = mountComponent({ modelValue: "" }); await wrapper.vm.onZipSearch({ preventDefault: jest.fn() }); expect(wrapper.vm.errorMessage).toBe(errorMessages.SERVICE_ZIP_REQUIRED); expect(wrapper.find(".scheduling-zip-search__error").classes()).toContain("active"); expect(getZipCodeData).not.toHaveBeenCalled(); expect(wrapper.emitted("zip-searched")).toBeUndefined(); wrapper.unmount(); }); test("shows format error when zip is invalid", async () => { const wrapper = mountComponent({ modelValue: "123" }); await wrapper.vm.onZipSearch({ preventDefault: jest.fn() }); expect(wrapper.vm.errorMessage).toBe(errorMessages.SERVICE_ZIP_FORMAT); expect(getZipCodeData).not.toHaveBeenCalled(); expect(wrapper.emitted("zip-searched")).toBeUndefined(); wrapper.unmount(); }); test("does not search when disabled", async () => { const wrapper = mountComponent({ modelValue: "44101", disabled: true }); await wrapper.vm.onZipSearch({ preventDefault: jest.fn() }); expect(getZipCodeData).not.toHaveBeenCalled(); expect(wrapper.emitted("zip-searched")).toBeUndefined(); wrapper.unmount(); }); test("saves zip info and emits billToAccountNumber when a valid zip is searched", async () => { const wrapper = mountComponent({ modelValue: "44101" }); await wrapper.vm.onZipSearch({ preventDefault: jest.fn() }); expect(getZipCodeData).toHaveBeenCalledWith("44101", "scheduling"); expect(getBillToAccountNumber).toHaveBeenCalledWith("03357", "scheduling"); expect(store.dispatch).toHaveBeenCalledWith("saveServiceZipCodeInfo", { zipCode: "44101", state: "OH", zipCodeCtu: "03357", }); expect(wrapper.emitted("zip-searched")).toEqual([ [{ zipCode: "44101", billToAccountNumber: "87291" }], ]); wrapper.unmount(); }); test("focusZipInput scrolls and focuses the zip input", () => { const wrapper = mountComponent({ modelValue: "43235" }); const zipInput = wrapper.find("#sz-service-zip").element; zipInput.scrollIntoView = jest.fn(); zipInput.focus = jest.fn(); wrapper.vm.focusZipInput(); expect(zipInput.scrollIntoView).toHaveBeenCalledWith({ behavior: "smooth", block: "center", }); expect(zipInput.focus).toHaveBeenCalledWith({ preventScroll: true }); wrapper.unmount(); }); });