diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js index 9e7952fd0..b75fed709 100644 --- a/src/layouts/schedule/schedule.spec.js +++ b/src/layouts/schedule/schedule.spec.js @@ -7,6 +7,22 @@ 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"; +import { partNumberStrings } from "@/constants/part-number-strings"; + +let mockDisplayMSR = false; +jest.mock("@/mixins/experiment-mixin.js", () => ({ + methods: { + getSettingValue(settingName) { + // "DisplayMSR" is experimentSettings.DISPLAY_MSR + if (settingName === "DisplayMSR") { + return mockDisplayMSR ? "true" : "false"; + } + return null; + }, + hasSettingEqualTo: jest.fn(), + hasSetting: jest.fn(), + }, +})); const storeMocked = { getters: { @@ -231,6 +247,145 @@ describe("schedule.vue", () => { expect(result).toBe(false); }); }); + + describe("computed: isMobileStaticRecalibrationApplicable", () => { + beforeEach(() => { + mockDisplayMSR = false; + }); + + test("returns false when displayMSR experiment is off, even for cash orders", async () => { + mockDisplayMSR = false; + const { wrapper } = setupMocks(); + await wrapper.setData({ + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: false }, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(false); + }); + + test("returns false when mobileFeePart is null, even for cash orders with DISPLAY_MSR on", async () => { + mockDisplayMSR = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ mobileFeePart: null }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(false); + }); + + test("returns false when mobileFeePart is not MOBILE_STATIC_RECAL_FEE, even for cash orders", async () => { + mockDisplayMSR = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ + mobileFeePart: { partNumber: "SOME_OTHER_PART", isInsurable: false }, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(false); + }); + + test("returns true when DISPLAY_MSR is on, part is MOBILE_STATIC_RECAL_FEE, and order is cash", async () => { + mockDisplayMSR = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: false }, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(true); + }); + + test("returns true when DISPLAY_MSR is on, part is MOBILE_STATIC_RECAL_FEE, and part is insurable (insurance order)", async () => { + mockDisplayMSR = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: true }, + }); + store.getters.order.payment.isInsurance = true; + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(true); + }); + + test("returns false when DISPLAY_MSR is on, part is MOBILE_STATIC_RECAL_FEE, insurance order, and part is NOT insurable", async () => { + mockDisplayMSR = true; + store.getters.payment.isInsurance = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: false }, + }); + + expect(wrapper.vm.isMobileStaticRecalibrationApplicable).toBe(false); + + store.getters.payment.isInsurance = false; + }); + }); + + describe("computed: isServiceableMobile — recalibration cannot be done mobile", () => { + beforeEach(() => { + mockDisplayMSR = false; + }); + + test("returns false when recal is NOT mobile serviceable and MSR is not applicable (cash order, no MSR part)", async () => { + const { wrapper } = setupMocks(); + // Cash order, no MSR feature, no MOBILE_STATIC_RECAL_FEE part + await wrapper.setData({ + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: false, + mobileFeePart: null, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isServiceableMobile).toBe(false); + }); + + test("returns false when recal is NOT mobile serviceable and MSR experiment is off (cash order)", async () => { + mockDisplayMSR = false; + const { wrapper } = setupMocks(); + await wrapper.setData({ + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: false, + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: false }, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isServiceableMobile).toBe(false); + }); + + test("returns true when both glass and recal ARE mobile serviceable", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: true, + mobileFeePart: null, + }); + + expect(wrapper.vm.isServiceableMobile).toBe(true); + }); + + test("returns true when recal is NOT mobile serviceable but MSR is applicable (DISPLAY_MSR on, MSR part, cash)", async () => { + mockDisplayMSR = true; + const { wrapper } = setupMocks(); + await wrapper.setData({ + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: false, + mobileFeePart: { partNumber: partNumberStrings.MOBILE_STATIC_RECAL_FEE, isInsurable: false }, + }); + store.getters.order.payment.isInsurance = false; + + expect(wrapper.vm.isServiceableMobile).toBe(true); + }); + + test("falls back to isGlassServiceableMobile when isRecalibrationServiceableMobile is null", async () => { + const { wrapper } = setupMocks(); + await wrapper.setData({ + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: null, + mobileFeePart: null, + }); + + expect(wrapper.vm.isServiceableMobile).toBe(true); + }); + }); }); function setupMocksForArePagePrerequisitesValid() { diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index f5462fb9e..497e40838 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -705,11 +705,9 @@ export default { }, isMobileStaticRecalibrationApplicable() { return ( - (this.displayMSR && - this.mobileFeePart?.partNumber == partNumberStrings.MOBILE_STATIC_RECAL_FEE && - this.enableMSRSplitPay) || - this.isCashItacNoComp || - this.mobileFeePart?.isInsurable + this.displayMSR && + this.mobileFeePart?.partNumber == partNumberStrings.MOBILE_STATIC_RECAL_FEE && + (this.isCashItacNoComp || this.mobileFeePart?.isInsurable) ); }, displayMSR() { @@ -719,13 +717,6 @@ export default { ?.toLowerCase() === "true" ); }, - enableMSRSplitPay() { - return ( - experimentMixin.methods - .getSettingValue(experimentSettings.ENABLE_MSR_SPLIT_PAY) - ?.toLowerCase() === "true" - ); - }, isMSRFeeNotCoveredByInsurance() { return ( this.isMobileSelected &&