From 6e204f7ad217feb3b0332c0b6bb8945c7e52303e Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 6 Feb 2026 10:31:16 -0500 Subject: [PATCH 1/2] CASH-1790 add more unit tests --- jest.config.js | 6 +----- src/layouts/schedule/schedule.vue | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/jest.config.js b/jest.config.js index 7b59ea2c1..6c0addf5f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -32,11 +32,7 @@ module.exports = { "!src/layouts/payment-pia-return/*.vue", // Temp test exclusion while in development "!src/layouts/insurance/*.vue", // Temp test exclusion while in development "!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development - "!src/layouts/schedule/**/*.vue", // Temp test exclusion while in development "!src/digital-components/date-picker/**/*.vue", // Temp test exclusion while in development - - "!src/**/*-june-2025.vue", // Exclude these temporary files for CASH-845 project - "!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development "!src/experiment-components/*.vue", // END @@ -44,7 +40,7 @@ module.exports = { testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], coverageThreshold: { global: { - statements: 64, + statements: 68, }, }, // Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 48424f085..e20c025fb 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -1326,8 +1326,8 @@ export default { if (isMobileSelected === undefined) { isMobileSelected = this.appointmentType === AppointmentTypeStrings.MOBILE; } - let storedDate = store.getters.order.schedule.date; - if (isMobileSelected) storedDate += "-mobile"; + let storedDate = store.getters.order.schedule?.date; + if (isMobileSelected && storedDate) storedDate += "-mobile"; return storedDate; }, getSelectedTimeSlotInfo() { From 2e0363ec78b098b9345d6d9c00b25950ba403615 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 6 Feb 2026 10:43:50 -0500 Subject: [PATCH 2/2] CASH-1790 add schedule unit tests --- src/layouts/schedule/schedule.spec.js | 183 ++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/layouts/schedule/schedule.spec.js diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js new file mode 100644 index 000000000..7d5cdcec1 --- /dev/null +++ b/src/layouts/schedule/schedule.spec.js @@ -0,0 +1,183 @@ +// Components +import schedule from "@/layouts/schedule/schedule.vue"; + +// Supporting Files +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { routeData } from "@/router/constants/routes"; +import store from "@/store"; +import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; + +const storeMocked = { + getters: { + payment: { isInsurance: false }, + order: { + payment: { isInsurance: false, insuranceCoverage: { isVerified: false } }, + referralNumber: "", + serviceLocation: { + address: "", + address2: "", + city: "", + state: "", + zipCode: "00000", + zipCodeCtu: "000", + appointmentType: null, + provider: {}, + isVehicleProtected: false, + }, + schedule: { + date: "", + routeCode: "", + startTime: "", + endTime: "", + jobMinMinutes: null, + jobMaxMinutes: null, + }, + policy: { + isItac: false, + isNoComp: false, + }, + damage: { isRepair: false }, + lineItems: { glassParts: [] }, + }, + vehicle: { + cardId: "", + }, + lineItems: { + supportingItems: [], + }, + applicationUser: { + experiments: [], + }, + isMobileAppointment: false, + }, +}; + +jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ + navigateToHeritageFunnel: jest.fn(), +})); + +describe("schedule.vue", () => { + describe("navigation", () => { + test("backButtonAction => non-insurance: navigateWithoutSaving called", () => { + // Arrange + const { wrapper, mocks } = setupMocks(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalledWith( + mocks.navigationScenarios.CLICKED_BACK, + routeData.SCHEDULE.name + ); + }); + + test("backButtonAction => insurance verified: navigateToHeritageFunnel called", () => { + // Arrange + store.getters.order.payment.isInsurance = true; + store.getters.order.payment.insuranceCoverage = { isVerified: true }; + store.getters.order.referralNumber = ""; + const { wrapper } = setupMocks(); + + // Act + wrapper.vm.backButtonAction(); + + // Assert + expect(navigateToHeritageFunnel).toHaveBeenCalledWith({ + shouldSaveSession: false, + pageNameToLog: "schedule", + navType: "back", + }); + }); + }); + + describe("computed: isForwardActionDisabled", () => { + test("should be true when routeCode missing or appointmentType not set", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + selectedTimeSlotInfo: { timeSlot: { routeCode: null } }, + appointmentType: null, + }); + expect(wrapper.vm.isForwardActionDisabled).toBe(true); + }); + + test("should be false when routeCode present and appointmentType set", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + selectedTimeSlotInfo: { timeSlot: { routeCode: "RC123" } }, + appointmentType: "SomeType", + }); + expect(wrapper.vm.isForwardActionDisabled).toBe(false); + }); + }); + + describe("computed: selectedRouteCodeData", () => { + test("should return null when routeCode not set", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + selectedTimeSlotInfo: { timeSlot: { routeCode: null } }, + }); + expect(wrapper.vm.selectedRouteCodeData).toBeNull(); + }); + + test("should return routeCode and premium flag when set", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + selectedTimeSlotInfo: { + timeSlot: { routeCode: "RC999" }, + isPremiumAppointment: true, + }, + }); + expect(wrapper.vm.selectedRouteCodeData).toEqual({ + routeCode: "RC999", + isPremiumAppointment: true, + }); + }); + }); + + describe("forwardButtonAction (early exit path)", () => { + test("shows recal acknowledgement popup and does not navigate when required", async () => { + const { wrapper } = setupMocks(); + // Force the recal-ack modal path + wrapper.vm.showRecalAcknowledgementModal = jest.fn(() => true); + await wrapper.setData({ isRecalAcknowledgedForScheduling: null }); + + await wrapper.vm.forwardButtonAction(); + + expect(wrapper.vm.showRecalAcknowledgementPopup).toBe(true); + expect(wrapper.vm.$router.navigateWithSaving).not.toHaveBeenCalled(); + }); + }); +}); + +function setupMocks(mountOptionsMockData = {}) { + const route = { name: "schedule" }; + const defaultMountOptions = { + route: route, + router: { + navigate: jest.fn(), + navigateWithSaving: jest.fn(), + navigateWithoutSaving: jest.fn(), + }, + store: { ...storeMocked }, + }; + const mockBaseMixin = { + methods: { + getTierOnePackagePrice: jest.fn(), + filterOutFees: jest.fn(), + getCmsContent: jest.fn(), + }, + }; + const baseMountOptions = getMountOptions({ + ...defaultMountOptions, + ...mountOptionsMockData, + }); + + baseMountOptions.global.mixins = [mockBaseMixin]; + baseMountOptions.global.mocks.pageName = route.name; + const wrapper = shallowMount(schedule, baseMountOptions); + wrapper.getCmsContent = jest.fn(); + + return { wrapper, mocks: baseMountOptions.global?.mocks || {} }; +}