import { shallowMount } from "@vue/test-utils"; import vinLookup from "./vin-lookup.vue"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js"; import store from "@/store"; jest.mock("@/store", () => ({ commit: jest.fn(), dispatch: jest.fn(), getters: { vehicle: { year: 2019, carId: 'initial carId' }, order: { serviceLocation: { zipCode: "45253" }, customer: { emailAddress: "builddigitaltest@safelite.com" } }, payment: { insuranceCoverage: { isVerified: true } }, damage: { glassToReplace: "windshield" } }, })); import { getDamageString, getIsWindshieldOnly, isGlassAvailableForCarId } from "@/helpers/damage-helper"; jest.mock("@/helpers/damage-helper", () => ({ isGlassAvailableForCarId: jest.fn(() => { return Promise.resolve(); }), getIsWindshieldOnly: jest.fn(), getDamageString: jest.fn(), })); describe("vin-lookup.vue", () => { it("Should update the funnel-footer forward button when VIN is changed", (done) => { //Arrange const { wrapper } = setupMocks({}); //Act wrapper.setData({ vin: "newValue" }); //Assert wrapper.vm.$nextTick(() => { expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toBeCalled(); done(); }); }); it("Should call navigateForward() if the store carId matches the vin response carId and forward button is clicked", async () => { // Arrange const { wrapper } = setupMocks({}); wrapper.vm.navigateForward = jest.fn(); // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.navigateForward).toHaveBeenCalled(); }); it("Should do a VIN lookup if the user has clicked on the VIN field and entered a new VIN or changed a previously matched VIN.", async () => { // Arrange const { wrapper } = setupMocks({}); wrapper.vm.vinTouched = true; wrapper.vm.vin = "foo"; wrapper.vm.initialVin = "!foo"; wrapper.vm.navigateForward = jest.fn(); const vehicleLookupApiResponse = { data: { carId: 'new carId' // does not match the store value } }; const vinPromise = Promise.resolve(vehicleLookupApiResponse); wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise); // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.lookupVehicle).toHaveBeenCalled(); }); it("Should not call navigateForward() if the store carId does not match the vin response carId and forward button is clicked", async () => { // Arrange const { wrapper } = setupMocks({}); // New lookup wrapper.vm.vinTouched = true; wrapper.vm.vin = ""; wrapper.vm.initialVin = "foo"; const vehicleLookupApiResponse = { data: { carId: 'new carId' // does not match the store value } }; const vinPromise = Promise.resolve(vehicleLookupApiResponse); wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise); wrapper.vm.navigateForward = jest.fn(); // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.navigateForward).not.toHaveBeenCalled(); }); it("Should call navigateForward() if the store carId does not match the vin response carId but does match previously enterted carId and forward button is clicked", async () => { // Arrange const { wrapper } = setupMocks({}); const vehicleLookupApiResponse = { data: { carId: 'new carId' // does not match the store value } }; const vinPromise = Promise.resolve(vehicleLookupApiResponse); wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise); wrapper.vm.navigateForward = jest.fn(); wrapper.vm.previouslyEnteredCarId = 'new carId'; // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.navigateForward).toHaveBeenCalled(); }); it("Should not call navigateForward() if zip service returns a non-serviceable flag", async () => { // Arrange const { wrapper } = setupMocks({}); const zipValidationApiResponse = { data: { isServiceable: false } }; const zipPromise = Promise.resolve(zipValidationApiResponse); wrapper.vm.validateZip = jest.fn().mockImplementation(() => zipPromise); wrapper.vm.setupUiForNonServiceableZip = jest.fn(); wrapper.vm.navigateForward = jest.fn(); wrapper.vm.previouslyEnteredCarId = 'new carId'; // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.navigateForward).not.toHaveBeenCalled(); }); it("Should not call navigateForward() when forward button is clicked but lookupVehicle errors out.", async () => { // Arrange const { wrapper } = setupMocks({}); wrapper.vm.vinTouched = true; wrapper.vm.vin = "foo"; wrapper.vm.initialVin = "!foo"; const vehicleLookupApiResponse = { status: { carId: 'new carId' // does not match the store value } }; const vinPromise = Promise.reject(vehicleLookupApiResponse); const response = { status: 404 }; wrapper.vm.lookupVehicle = jest.fn().mockImplementation((response) => vinPromise); wrapper.vm.navigateForward = jest.fn(); wrapper.vm.previouslyEnteredCarId = 'new carId'; // Act await wrapper.vm.forwardButtonAction(); //Assert expect(wrapper.vm.navigateForward).not.toHaveBeenCalled(); }); describe("navigateForward", () => { test("carId is different from returned vehicle and selected glass isn't available => continue with different glass", async () => { // Arrange const { wrapper } = setupMocks({ customMountOptions: { router: { navigateAfterSave: jest.fn() } } }); wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); wrapper.setData({ isCarIdDifferent: true, isSelectedGlassAvailableForVehicle: false }); // Act await wrapper.vm.navigateForward(); //Assert expect(wrapper.vm.$router.navigateAfterSave).toBeCalledTimes(1); expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, wrapper.vm.$route, expect.anything(), expect.anything(), expect.anything()); }) test("carId matches => navigateForwardWithSingleCarMatch", async () => { // Arrange const { wrapper } = setupMocks({}); wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); wrapper.setData({ isCarIdDifferent: false, }); // Act await wrapper.vm.navigateForward(); //Assert expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1); }) test("selected glass is available for returned vehicle => navigateForwardWithSingleCarMatch", async () => { // Arrange const { wrapper } = setupMocks({}); wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); wrapper.setData({ isSelectedGlassAvailableForVehicle: true, }); // Act await wrapper.vm.navigateForward(); //Assert expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1); }) }) }); function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions }); // Modify/augment default mount options mountOptions.global.mocks["$store"] = store; mountOptions.global.mixins = [mockMixin]; mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods const wrapper = shallowMount(vinLookup, mountOptions); mockOutPromises(wrapper); mockOutStubFunctions(wrapper); return { wrapper }; } function mockOutPromises(wrapper) { const zipValidationApiResponse = { data: { isServiceable: true } }; const vehicleLookupApiResponse = { data: { carId: 'initial carId' } }; const zipPromise = Promise.resolve(zipValidationApiResponse); const vinPromise = Promise.resolve(vehicleLookupApiResponse); wrapper.vm.validateZip = jest.fn().mockImplementation(() => zipPromise); wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise); } function mockOutStubFunctions(wrapper) { wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn(); } const mockMixin = { methods: { getCmsContent: jest.fn(() => "placeholder CMS content"), } }