From 1ed8063e946988fa0399a0ed74fac12aed18fe96 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 13 May 2022 12:56:30 -0400 Subject: [PATCH 1/6] fix zip type error in lookup-vin-by-address API call --- src/layouts/address-lookup/address-lookup.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index a9cf1bd53..551ef94c9 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -308,8 +308,8 @@ export default { { licenseLastName: lastName, licenseStreetAddress: streetAddress, - licenseZip: zip, - licenseState: state + licenseZip: (typeof zip !== "string") ? zip.toString() : zip; + licenseState: state, }, false ); }, From c07f259dfc2aa78d0469b0071457f0f0426266b0 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Fri, 13 May 2022 12:59:11 -0400 Subject: [PATCH 2/6] CSR-347: fix errant semi colon --- src/layouts/address-lookup/address-lookup.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 551ef94c9..653825016 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -308,7 +308,7 @@ export default { { licenseLastName: lastName, licenseStreetAddress: streetAddress, - licenseZip: (typeof zip !== "string") ? zip.toString() : zip; + licenseZip: (typeof zip !== "string") ? zip.toString() : zip, licenseState: state, }, false ); From 855e3acc9d868023a9de58f072d68707e961885f Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 1 Jun 2022 08:26:30 -0400 Subject: [PATCH 3/6] CSR-347: return out of forwardButtonAction if no lookupVin found / remove unused var --- src/layouts/address-vehicles/address-vehicles.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index 34937bfb7..dc2e53484 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -162,8 +162,10 @@ export default { async forwardButtonAction() { const vinLookup = await this.lookupVin(this.selectedVehicle.vin).catch(() => { this.$refs.funnelFooter.removeLoader(); - return; }); + if (!vinLookup) { + return; + } this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId); this.updateCustomerInfo(this.selectedVehicle.vin, this.selectedVehicle.vehicle); this.navigateForward(); @@ -210,7 +212,7 @@ export default { }, watch: { - selectedVehicleVin(vehicleVin) { + selectedVehicleVin() { // does this vehicle match the previously selected carId? this.isCarIdDifferent = this.selectedVehicle.vehicle.carId !== store.getters.vehicle.carId; this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`); From 5e4b43d5c771b56f0df0c36b0b2ead33f1f3b75b Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 1 Jun 2022 08:27:08 -0400 Subject: [PATCH 4/6] CSR-347: restore address-vehicle tests to be included --- jest.config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/jest.config.js b/jest.config.js index 839db4378..e8d3abcc9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -23,8 +23,6 @@ module.exports = { "!src/layouts/address-lookup/address-lookup.vue", "!src/layouts/address-lookup/customer-questions/customer-questions.vue", "!src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue", - "!src/layouts/address-vehicles/address-vehicles.vue", - "!src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue", "!src/common-components/dropdown-question/dropdown-question.vue", "!src/common-components/textbox-question/textbox-question.vue", "!src/ux-components/alert\alert.vue", From c5c9e89007f73e96ab9815d2e47e780e8d7267d1 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 1 Jun 2022 08:43:11 -0400 Subject: [PATCH 5/6] CSR-347: add unit tests for address-vehicles page/components --- .../address-vehicles-question.spec.js | 63 ++++ .../address-vehicles/address-vehicles.spec.js | 349 ++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100644 src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js create mode 100644 src/layouts/address-vehicles/address-vehicles.spec.js 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 }; +} From 882b79ad7d28f32d2c95d0dfa5e9a5468e730290 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 1 Jun 2022 08:52:46 -0400 Subject: [PATCH 6/6] CSR-347: remove accidentally included test code --- src/layouts/address-lookup/address-lookup.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index e9578fb3b..8e58d09b0 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -329,7 +329,7 @@ export default { { licenseLastName: lastName, licenseStreetAddress: streetAddress, - licenseZip: (typeof zip !== "string") ? zip.toString() : zip, + licenseZip: zip, licenseState: state, }, false );