import { shallowMount } from "@vue/test-utils"; import scheduling from "./scheduling"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { settleAllPromises } from "@/helpers/layout-helper"; import store from "@/store"; jest.mock("@/store", () => ({ dispatch: jest.fn().mockResolvedValue(null), getters: { order: { serviceLocation: { zipCode: "43235", appointmentType: null }, payment: { isInsurance: false, insuranceCoverage: { isVerified: false } }, referralNumber: "", damage: { isRepair: false }, lineItems: { glassParts: [] }, policy: { isItac: false, isNoComp: false }, }, applicationUser: { experiments: [], }, }, })); jest.mock("@/helpers/layout-helper", () => ({ settleAllPromises: jest.fn().mockResolvedValue({}), })); jest.mock("@/helpers/cms-content-helper", () => ({ fetchCmsContentForPage: jest.fn().mockResolvedValue({}), })); jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ navigateToHeritageFunnel: jest.fn(), })); jest.mock("@/helpers/debug-log-helper", () => ({ debugLog: jest.fn(), })); jest.mock("@/helpers/page-prerequisites-helper.js", () => ({ flushPagePrereqsLogs: jest.fn(), hasServiceZipInfo: jest.fn(() => true), hasGlassPartsOrRepairInfo: jest.fn(() => true), hasInsuranceInfo: jest.fn(() => true), })); function setupMocks() { const baseMixin = { methods: { getCmsContent: jest.fn(() => ""), setCmsContent: jest.fn(), getTotalLineItemPrice: jest.fn(() => 0), }, }; const mountOptions = getMountOptions({ route: { name: "scheduling" }, router: { navigate: jest.fn(), navigateWithSaving: jest.fn(), navigateWithoutSaving: jest.fn(), }, }); mountOptions.global.mixins = [baseMixin]; const wrapper = shallowMount(scheduling, mountOptions); return { wrapper }; } describe("scheduling.vue", () => { describe("intercept overlay", () => { test("does not render interceptOverlay when isLoadingDates is false", async () => { const { wrapper } = setupMocks(); await wrapper.setData({ isLoadingDates: false }); expect(wrapper.find("intercept-overlay-stub").exists()).toBe(false); wrapper.unmount(); }); test("renders interceptOverlay when isLoadingDates is true", async () => { const { wrapper } = setupMocks(); await wrapper.setData({ isLoadingDates: true }); expect(wrapper.find("intercept-overlay-stub").exists()).toBe(true); wrapper.unmount(); }); }); describe("handleRequestMoreDates", () => { test("sets isLoadingDates to true while fetching and false after resolving", async () => { let resolve; settleAllPromises.mockReturnValueOnce( new Promise((r) => { resolve = r; }) ); const { wrapper } = setupMocks(); const fetchPromise = wrapper.vm.handleRequestMoreDates(); expect(wrapper.vm.isLoadingDates).toBe(true); resolve({}); await fetchPromise; expect(wrapper.vm.isLoadingDates).toBe(false); wrapper.unmount(); }); test("completes without invoking loadingModal methods (stub has none)", async () => { // The loadingModal stub rendered by shallowMount has no showModal/hideModal. // If those calls were still in handleRequestMoreDates they would throw here. settleAllPromises.mockResolvedValueOnce({}); const { wrapper } = setupMocks(); await expect(wrapper.vm.handleRequestMoreDates()).resolves.toBeUndefined(); wrapper.unmount(); }); test("batches inshop provider requests into a single getShopTimeSlotsV2 call", async () => { store.dispatch.mockClear(); settleAllPromises.mockResolvedValueOnce({ inshopTimeSlots: { providerTimeSlots: [ { providerNumber: "05018", days: [{ date: "2026-07-22", timeSlots: [] }] }, { providerNumber: "05019", days: [{ date: "2026-07-22", timeSlots: [] }] }, ], }, }); const { wrapper } = setupMocks(); wrapper.vm.inShopProvidersAndTimeslots = [ { provider: { providerNumber: "05018" }, timeSlots: { days: [] } }, { provider: { providerNumber: "05019" }, timeSlots: { days: [] } }, ]; wrapper.vm.datePickerEndDate = "2026-07-21"; await wrapper.vm.handleRequestMoreDates(); const shopTimeSlotDispatches = store.dispatch.mock.calls.filter( ([actionName]) => actionName === "getShopTimeSlotsV2" ); expect(shopTimeSlotDispatches).toHaveLength(1); expect(shopTimeSlotDispatches[0][1].payload.providerNumbers).toEqual([ "05018", "05019", ]); expect(shopTimeSlotDispatches[0][1].payload.endDate).toBeDefined(); wrapper.unmount(); }); test("maps batched inshop providerTimeSlots back onto provider entries", async () => { settleAllPromises.mockResolvedValueOnce({ inshopTimeSlots: { providerTimeSlots: [ { providerNumber: "05018", days: [{ date: "2026-07-22", timeSlots: [{ id: "slot-a" }] }], }, { providerNumber: "05019", days: [{ date: "2026-07-22", timeSlots: [{ id: "slot-b" }] }], }, ], }, }); const { wrapper } = setupMocks(); wrapper.vm.inShopProvidersAndTimeslots = [ { provider: { providerNumber: "05018" }, timeSlots: { days: [] } }, { provider: { providerNumber: "05019" }, timeSlots: { days: [] } }, ]; wrapper.vm.datePickerEndDate = "2026-07-21"; await wrapper.vm.handleRequestMoreDates(); expect(wrapper.vm.inShopProvidersAndTimeslots[0].timeSlots.days).toHaveLength(1); expect( wrapper.vm.inShopProvidersAndTimeslots[0].timeSlots.days[0].timeSlots[0].id ).toBe("slot-a"); expect( wrapper.vm.inShopProvidersAndTimeslots[1].timeSlots.days[0].timeSlots[0].id ).toBe("slot-b"); wrapper.unmount(); }); }); });