diff --git a/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js new file mode 100644 index 000000000..eaa24c9d4 --- /dev/null +++ b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js @@ -0,0 +1,63 @@ +import { shallowMount } from "@vue/test-utils"; +import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question"; + + +describe("addressVehiclesQuestion.vue", () => { + + it("Should return content for differentVehicleAlertHeader", () => { + // Arrange + const wrapper = shallowMount(addressVehiclesQuestion, { + mixins: [mockMixin], + }); + + // Assert + expect(wrapper.vm.differentVehicleAlertHeader).toEqual('FoundWindshieldTestReturn'); + }); + + it("Should return content for differentVehicleAlertBody", () => { + // Arrange + const wrapper = shallowMount(addressVehiclesQuestion, { + mixins: [mockMixin], + propsData: { + vehicles: ["1", "2"], + modelValue: ["1", "2"], + } + }); + + // Assert + expect(wrapper.vm.differentVehicleAlertBody).toEqual('FoundWindshieldTestReturn'); + }); + + it("Should emit a modelValue change when setting selectedVehicleVin", async () => { + // Arrange + const wrapper = shallowMount(addressVehiclesQuestion, { + mixins: [mockMixin], + propsData: { + vehicles: ["1", "2"], + modelValue: ["1", "2"], + } + }); + + // Act + const localThis = { $emit: jest.fn() } + addressVehiclesQuestion.computed.selectedVehicleVin.set.call(localThis, 'newValue'); + + // Assert + expect(localThis.$emit).toBeCalledWith("update:modelValue", "newValue"); + }); + +}); + +const mockMixin = { + methods: { + getCmsContent: jest.fn((contentName) => { + if (contentName === "FoundWindshield") { + return 'FoundWindshieldTestReturn'; + } + return null; + }), + vehicles: jest.fn(() => { + return [{ vehicle: "test" }]; + }) + } + } diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js new file mode 100644 index 000000000..2fdd10276 --- /dev/null +++ b/src/layouts/address-vehicles/address-vehicles.spec.js @@ -0,0 +1,349 @@ +// Components +import addressVehicles from "@/layouts/address-vehicles/address-vehicles"; + +// Supporting Files +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import store from "@/store"; +import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper"; + + +// Mock our module for promises. +jest.mock("@/helpers/damage-helper", () => ({ + isGlassAvailableForCarId: () => { + return false; + }, +})); + + +describe("addressVehicles.vue", () => { + + test("Should return true for valid page requisites if carId / zipCode / emailAddress / pageData exists", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$router.navigate = jest.fn(); + + // Act + const result = wrapper.vm.arePagePrerequisitesValid(); + + //Assert + expect(result).toBe(true); + + wrapper.unmount(); + }); + + test("Should return false for valid page requisites if carId is missing", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$router.navigate = jest.fn(); + + // Act + wrapper.vm.$store.getters.order.vehicle.carId = null; + const result = wrapper.vm.arePagePrerequisitesValid(); + + //Assert + expect(result).toBe(false); + + wrapper.unmount(); + }); + + + // NOTE: this test is only here to meet code coverage; it does not test any logic in the original function + test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$router.navigate = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + }); + wrapper.vm.backButtonAction(); + + //Assert + expect(wrapper.vm.$router.navigate).toBeCalled(); + + wrapper.unmount(); + }); + + // NOTE: this test is only here to meet code coverage; it does not test any logic in the original function + test("Should run several related methods if forwardButtonAction is run", async () => { + // Arrange + const { wrapper } = setupMocks({}); + const lookupVinResponse = { + data: { + carId: "456" + } + } + + // the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn(); + wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse)); + wrapper.vm.$router.navigateAfterSave = jest.fn(); + wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {}); + wrapper.vm.navigateForward = jest.fn().mockImplementation(()=> {}); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + }); + + await wrapper.vm.forwardButtonAction(); + wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.vm.updateCustomerInfo).toBeCalled(); + expect(wrapper.vm.navigateForward).toBeCalled(); + + wrapper.unmount(); + }); + + test("Should return out of forwardButtonAction if lookupVin returns with an error", async () => { + // Arrange + const { wrapper } = setupMocks({}); + + const lookupVinResponse = { + error: "there is an error" + } + + // the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn(); + wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse)); + wrapper.vm.$router.navigateAfterSave = jest.fn(); + wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {}); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + }); + await wrapper.vm.forwardButtonAction(); + wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.vm.forwardButtonAction).toReturn; + + wrapper.unmount(); + }); + + test("Should send dispatch reset if carId is different and selected glass not available for vehicle on updateCustomerInfo", async () => { + // Arrange + const { wrapper } = setupMocks({}); + const lookupVinResponse = { + data: { + carId: "456" + } + } + + // the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse)); + wrapper.vm.$router.navigateAfterSave = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + isSelectedGlassAvailableForVehicle: false, + isCarIdDifferent: true, + }); + await wrapper.vm.updateCustomerInfo(wrapper.vm.selectedVehicle.vin, wrapper.vm.selectedVehicle.vehicle); + + //Assert + expect(store.dispatch).toBeCalledWith("resetDamageAndDependencies"); + + wrapper.unmount(); + }); + + // NOTE: this test is only here to meet code coverage; it does not test any logic in the original function + test("Should send dispatch store action if lookupVin is called", async () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + await wrapper.vm.lookupVin('1234567890'); + + //Assert + expect(store.dispatch).toBeCalledWith("lookupVehicleByVin", {"vin": "1234567890"}); + + wrapper.unmount(); + }); + + test("If selectedVehicleVin changes, then should update isCarIdDifferent", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + isCarIdDifferent: false, + }); + await wrapper.vm.resetDependentState(); + + //Assert + expect(wrapper.vm.isCarIdDifferent).toBe(true); + + wrapper.unmount(); + }); + + test("If selectedVehicleVin changes, then text on funnel footer should be updated", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + isCarIdDifferent: false, + }); + await wrapper.vm.resetDependentState(); + + //Assert + expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toBeCalled(); + + wrapper.unmount(); + }); + + test("Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.$router.navigateAfterSave = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + isSelectedGlassAvailableForVehicle: false, + isCarIdDifferent: true, + }); + await wrapper.vm.navigateForward(); + + //Assert + expect(wrapper.vm.$router.navigateAfterSave).toBeCalledTimes(1); + + wrapper.unmount(); + }); + + test("Should navigate to navigateAfterSaveToHeritageFunnel if carId is not different on navigateForward", async () => { + // Arrange + const { wrapper } = setupMocks({}); + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.$refs.loadingModal.showModal = jest.fn(); + navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn(); + + // Act + wrapper.setData({ + selectedVehicleVin: ['5NMS3CADXLH233004'], + isSelectedGlassAvailableForVehicle: true, + isCarIdDifferent: false, + }); + await wrapper.vm.navigateForward(); + + //Assert + expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toBeCalledTimes(1); + + wrapper.unmount(); + }); + +}); + + +function setupMocks({ + // modelValueProp = "1900", + cmsQuestionText = "CMS text goes here", + // dataFromStoreApi = [], +}) { + //Mock store + store.dispatch = jest.fn(() => {}); + store.getters = { + pageData: jest.fn((pageName) => { + // console.log('pageName: ', pageName) // address-vehicles + return [ + { + vehicle: { + "carId": "CR00069309", + "category": "SUV", + "year": 2020, + "make": "Hyundai", + "model": "Santa Fe", + "style": "4 door utility", + "imageUrl": "https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg", + "imageVifNumber": "13769", + "imageVifColor": "white" + }, + vin: "5NMS3CADXLH233004" + }, + ]; + }), + order: { + vehicle: { + carId: "123", + }, + serviceLocation: { + zipCode: "12345" + }, + customer: { + emailAddress: "qw@er.ty" + } + }, + damage: { + glassToReplace: "Windshield" + }, + vehicle: { + carId: "456", + } + }; + + // baseMixin.methods.dispatchStoreAction = jest.fn(); + + + const mountOptions = getMountOptions({ + store: { + dispatch: store.dispatch, + getters: store.getters, + }, + router: { + navigate: jest.fn(), + }, + }); + + //Mock props + const mockMixin = { + methods: { + getCmsContent: jest.fn((contentName) => { + if (contentName === "FoundMultipleVehicles") { + return 'FoundMultipleVehiclesTestReturn'; + } + if (contentName === "ProvideVinAlert") { + return 'ProvideVinAlertTestReturn'; + } + return null; + }), + // dispatchStoreAction: jest.fn(() => { + // console.log("23424243") + // }), + // isGlassAvailableForCarId: () => { + // console.log("%%%%%%%%%%%%%%%") + // return Promise.resolve(true) + // } + + // lookupVin: jest.fn(() => Promise.resolve(lookupVinResponse)), + + }, + } + // mountOptions.propsData = { + // modelValue: modelValueProp, + // }; + + mountOptions.mixins = [mockMixin]; + + const wrapper = shallowMount(addressVehicles, mountOptions); + + //Mock CMS content + const cmsContent = { + QuestionText: cmsQuestionText, + }; + + return { wrapper }; +}