182 lines
6.7 KiB
JavaScript
182 lines
6.7 KiB
JavaScript
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();
|
|
});
|
|
});
|
|
});
|