import { shallowMount, flushPromises } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { applicationConfig } from "@/constants/application-config"; import { storeActions } from "@/constants/store-actions"; import quote from "@/layouts/quote/quote.vue"; import store from "@/store"; import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper"; import { nextTick } from "vue"; import { experimentSettings } from "@/constants/experiments"; import experimentMixin from "@/mixins/experiment-mixin.js"; import baseMixin from "@/mixins/base-mixin.js"; import { containsLineItemWithPartType } from "../../helpers/service-package-helper"; import { savePageData } from "../../router/methods/helpers/save-page-data"; jest.mock("@/store", () => ({ commit: jest.fn(), // Mock store.commit dispatch: jest.fn(), getters: { order: { lineItems: { glassParts: [], supportingItems: [], vaps: [], promos: [], }, payment: { insuranceCoverage: {}, isInsurance: false, parentAccountNumber: 167132, }, }, payment: { insuranceCoverage: {}, isInsurance: false, }, customer: { emailAddress: "test@test.com", }, }, })); // Mock fetchCmsContentForPage jest.mock("@/helpers/cms-content-helper", () => ({ fetchCmsContentForPage: () => Promise.resolve("content"), })); jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ navigateToHeritageFunnel: jest.fn(), })); jest.mock("@/helpers/service-package-helper", () => ({ containsLineItemWithPartType: jest.fn(), })); jest.mock("@/helpers/promotions-helper", () => ({ revalidatePromosAndValidateQueryStringPromo: jest.fn(() => { return { validatePromoResponse: null, revalidatePromoResponse: null }; }), })); jest.mock( "@/store", () => { return {}; }, { virtual: true } ); // START beforeRouteEnter mock arranging // jest.mock("@/mixins/base-mixin", () => ({ methods: { dispatchStoreAction(action, items, encode) { if (action === mockPriceOrderStoreAction) return items; else return mockStoreActionResults[action]; }, dispatchStoreActionWithLogging(action, items, pageName, encode) { if (action === mockPriceOrderStoreAction) return items; else return mockStoreActionResults[action]; }, getTierOnePackagePrice() { return mockTierOnePrice; }, filterOutFees(items) { return null; }, filterOutServicePackageDiscountPart(items) { return null; }, isFormValid(form) { return true; }, }, })); jest.mock("@/router/methods/helpers/save-page-data", () => ({ savePageData: jest.fn(), })); const mockExperimentSettings = experimentSettings; jest.mock("@/mixins/experiment-mixin.js", () => ({ methods: { getSettingValue(settingName) { if (settingName === mockExperimentSettings.SERVICE_PACKAGE_DISCOUNT) { return true; } if ( settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL ) { return 300; } else if ( settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL ) { return 500; } return "test"; }, hasSettingEqualTo(settingName) { if (settingName === mockExperimentSettings.DISPLAY_AFTERPAY_BREAKOUT_DISPLAY) { return false; } return "test"; }, }, })); const mockMixin = { methods: { filterOutFees: jest.fn().mockImplementation(() => { return null; }), isFormValid: jest.fn().mockImplementation(() => { return true; }), }, }; let mockTierOnePrice = 501; const mockPriceOrderStoreAction = storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA; const mockStoreActionResults = {}; mockStoreActionResults[storeActions.GET_WIPERS] = Promise.resolve([ { partNumber: "SBB24", partType: "FRONT WIPER" }, ]); mockStoreActionResults[storeActions.GET_RAIN_DEFENSE] = Promise.resolve({ partNumber: "RAIN DEFENSE", partType: "RAIN DEFENSE", }); mockStoreActionResults[storeActions.GET_SUPPORTING_ITEMS] = Promise.resolve([ { partNumber: "WSREPAIR", partType: "WSREPAIR" }, ]); // END beforeRouteEnter mock arranging store.getters = { order: { payment: { insuranceCoverage: {}, isInsurance: false, parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, }, customer: { emailAddress: "test@test.com", }, }, }; afterEach(() => { // reset store after each test store.getters = { order: { payment: { parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, }, }, payment: { insuranceCoverage: {}, isInsurance: false, }, customer: { emailAddress: "test@test.com", }, }; }); describe("quote.vue", () => { test("IsInsurance false should navigateWithSaving", async () => { //Arrange store.commit = jest.fn(); // Ensure store.commit is mocked store.getters.payment = { insuranceCoverage: {}, isInsurance: false, }; store.getters.order = { lineItems: [], payment: { parentAccountNumber: 167132, }, }; const { wrapper } = setupMocks({ customMountOptions: { router: { navigateWithSaving: jest.fn(), }, route: { quote }, }, }); wrapper.vm.dispatchStoreAction = jest.fn(() => { return { data: [], }; }); //Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); }); test("should pass arePagePrerequisitesValid with a repair order", () => { //Arrange store.getters = { order: { lineItems: [], serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, damage: { isRepair: true, }, payment: { insuranceCoverage: { isVerified: false, }, }, referralNumber: "1234567", }, }; const { wrapper } = setupMocks({}); let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); expect(arePagePrerequisitesValid).toBe(true); }); test("should pass arePagePrerequisitesValid with a replace order", () => { //Arrange store.getters = { order: { serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, damage: { isRepair: false, }, referralNumber: "1234567", lineItems: { glassParts: ["item", "item2"], }, payment: { insuranceCoverage: { isVerified: false, }, }, }, }; const { wrapper } = setupMocks({}); let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); expect(arePagePrerequisitesValid).toBe(true); }); test("should fail arePagePrerequisitesValid without glass parts or flagged as repair", () => { //Arrange store.getters = { order: { lineItems: [], serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, damage: { isRepair: false, }, referralNumber: "1234567", }, }; const { wrapper } = setupMocks({}); let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); expect(arePagePrerequisitesValid).toBe(false); }); test("should have non-null values for necessary data members after 'beforeRouteEnter'", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: {}, customer: { emailAddress: "test@test.com", }, serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); //mock this to avoid needing to populate this.$route in an unrelated test wrapper.vm.getDefaultIsInsuranceSelectedValue = jest.fn(); //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.lineItems !== null).toBe(true); expect(wrapper.vm.availableVaps !== null).toBe(true); expect(wrapper.vm.availableLineItems !== null).toBe(true); // This should have its own test //expect(vm.isInsuranceSelected !== null).toBe(true); }); test("Returns true if service package discount setting is true", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: {}, customer: { emailAddress: "test@test.com", }, serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); wrapper.vm.$route = { query: { isInsurance: "false" } }; const isServicePackageDiscount = experimentMixin.methods.getSettingValue( experimentSettings.SERVICE_PACKAGE_DISCOUNT ); //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(isServicePackageDiscount).toBe(true); }); test("should default to insurance if query param 'isInsurance' is true", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: null, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); wrapper.vm.$route = { query: { isInsurance: "true" } }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(true); }); test("should use amount threshold if query param 'isInsurance' is false", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: null, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; mockTierOnePrice = 200; const { wrapper } = setupMocks({}); //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote", isInsurance: false } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(false); }); test("should default to insurance if insurance selection is saved to store", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: true, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); // Ensure that query param isn't overriding selection wrapper.vm.$route = { query: null }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(true); }); test("should default to cash if cash selection is saved to store", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: false, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); // Ensure that query param isn't overriding selection wrapper.vm.$route = { query: null }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(false); }); test("should default to cash if total economy package price is under $500", async () => { // Also needs no query parameter or previous selection in store to be present //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: null, // Ensure that previous selection isn't overriding selection }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; mockTierOnePrice = 200; const { wrapper } = setupMocks({}); // Ensure that query param isn't overriding selection wrapper.vm.$route = { query: null }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(false); }); test("should default to cash if offer = cash, despite all other checks pointing to insurance selection", async () => { // Also needs no query parameter or previous selection in store to be present //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: true, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; mockTierOnePrice = 505; const { wrapper } = setupMocks({}); //Act await quote.beforeRouteEnter.call( wrapper.vm, { name: "quote", query: { isInsuranceSelected: true, offer: "cash" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(false); }); test("should default to insurance if total economy package price is over $500", async () => { // Also needs no query parameter or previous selection in store to be present //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: null, // Ensure that previous selection isn't overriding selection }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: null, }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; mockTierOnePrice = 505; const { wrapper } = setupMocks({}); // Ensure that query param isn't overriding selection wrapper.vm.$route = { query: null }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(true); }); test("Should default to insurance if user Service zip is from certain States", async () => { //Arrange store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, payment: { isInsurance: null, }, customer: { emailAddress: "test@test.com", }, serviceLocation: { state: "AZ", }, }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; const { wrapper } = setupMocks({}); wrapper.vm.$route = { query: null }; //Act await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, (c) => c(wrapper.vm) ); //Assert expect(wrapper.vm.isInsuranceSelected).toBe(true); }); test("On forward button action save promos", async () => { //Arrange store.commit = jest.fn(); // Ensure store.commit is mocked store.getters.payment = { insuranceCoverage: {}, isInsurance: false, }; store.getters.order = { lineItems: [], payment: { parentAccountNumber: 167132, }, }; const { wrapper } = setupMocks({ customMountOptions: { router: { navigateWithSaving: jest.fn(), }, route: { quote }, }, }); wrapper.vm.forwardButtonAction(); expect(wrapper.vm.lineItems.promos !== null).toBe(true); }); test("On forward button action save supporting lineItems", async () => { // Arrange store.commit = jest.fn(); // Ensure store.commit is mocked store.getters.payment = { insuranceCoverage: {}, isInsurance: false, }; store.getters.order = { lineItems: [], payment: { parentAccountNumber: 167132, }, }; const { wrapper } = setupMocks({ customMountOptions: { router: { navigateWithSaving: jest.fn(), }, route: { quote }, }, }); wrapper.vm.forwardButtonAction(); expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith( "saveSupportingItems", wrapper.vm.lineItems.supportingItems, false ); }); }); describe("quote.vue", () => { test("should call forwardButtonAction if isExternalParameter and Insurance is true and form is valid", async () => { // Set up the store with isExternalParameter as true store.getters = { lineItems: { glassParts: ["item", "item2"], }, pageData: jest.fn((page) => { if (page === "quote") { return { saveProgressPopupSkipped: true }; } return {}; }), applicationUser: { experiments: [], }, order: { lineItems: { glassParts: ["item", "item2"], }, serviceLocation: { zipCode: "12345", zipCodeCtu: "value", }, damage: { isRepair: false, }, referralNumber: "1234567", payment: { isInsurance: true, inactivePromos: [], }, customer: { emailAddress: "test@test.com", }, }, externalParameterState: { isExternalParameter: 1 }, externalParameterQuote: { isInsurance: true, servicePackage: "glassonly", }, payment: { isInsurance: true, inactivePromos: [], }, vehicle: { cardId: "123", }, experimentSettings: { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; // Set up the component const { wrapper } = setupMocks({}); wrapper.vm.$route = { query: null }; wrapper.vm.forwardButtonAction = jest.fn(); const nextFunction = jest.fn((c) => { c(wrapper.vm); }); // Call the method that contains the if-else logic await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, undefined, nextFunction ); await nextTick(); await nextTick(); expect(nextFunction).toHaveBeenCalled(); expect(baseMixin.methods.isFormValid).toHaveBeenCalled(); expect(baseMixin.methods.isFormValid()).toBe(true); await wrapper.vm.$nextTick(); expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); }); }); function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions, }); mountOptions.mixins = [ { methods: { getSettingValue: jest.fn(), }, }, ]; baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn(); baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); mountOptions.global.mocks["$store"] = store; mountOptions["attachTo"] = document.body; const wrapper = shallowMount(quote, mountOptions); wrapper.vm.setCmsContent = jest.fn(); wrapper.vm.getCmsContent = jest.fn(); return { wrapper }; }