From 768191ea1abba338dd600ed92c27383d12e11fb7 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 2 May 2022 12:30:46 -0400 Subject: [PATCH 01/11] Omitting unneeded api parts call and adding unit tests --- jest.config.js | 1 - src/helpers/damage-helper.js | 19 +++++- src/helpers/damage-helper.spec.js | 59 ++++++++++--------- .../license-plate-lookup.vue | 40 +++++-------- 4 files changed, 65 insertions(+), 54 deletions(-) diff --git a/jest.config.js b/jest.config.js index d010bda25..dc59735c2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,7 +11,6 @@ module.exports = { "!src/constants/*.js", "!src/router/**/*.js", "!src/helpers/unit-test-helper.js", - "!src/helpers/damage-helper.js", "!src/layouts/component-test/component-test.vue", "!src/layouts/form-test/form-test.vue", "!src/layouts/vin-lookup/vin-lookup.vue", diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js index 453aadf69..49c7cd59c 100644 --- a/src/helpers/damage-helper.js +++ b/src/helpers/damage-helper.js @@ -3,7 +3,24 @@ import baseMixin from "@/mixins/base-mixin.js"; import { storeActions } from "@/constants/store-actions"; export function getDamageString() { - return store.getters.damage.glassToReplace.length > 1 ? "match" : store.getters.damage.glassToReplace[0].location; + const damageLocations = store.getters.damage.glassToReplace; + let returnString; + if(damageLocations.length > 1){ + returnString = "match" + } else { + switch(damageLocations[0].location) { + case "Windshield": + returnString = "windshield" + break; + case "Driver": + case "Passenger": + returnString = "side window" + break; + case "Rear": + returnString = "rear window" + } + } + return returnString; } export async function isGlassAvailableForCarId(carId){ diff --git a/src/helpers/damage-helper.spec.js b/src/helpers/damage-helper.spec.js index abc8defe2..e0a9f71cc 100644 --- a/src/helpers/damage-helper.spec.js +++ b/src/helpers/damage-helper.spec.js @@ -1,42 +1,47 @@ import {getDamageString, isGlassAvailableForCarId} from "./damage-helper"; -//import baseMixin from "@/mixins/base-mixin.js"; +import baseMixin from "@/mixins/base-mixin.js"; jest.mock("@/store", () => ({ getters: {damage: { glassToReplace: [{location: "Windshield", name: "windshield"}] } } - })); +})); describe("damage-helper.js", () => { it("Should return damage getter info", () => { const damage = getDamageString(); - expect(damage).toEqual("Windshield") + expect(damage).toEqual("windshield") }); }); - // describe("damage-helper.js", () => { - // it("Should return false if no mismatches between each array", async () => { - // const updatedOptions = { - // data: { - // windshieldOptions: {availableReplacementOptions: ["windshield"]} - // } - // } - // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn().mockImplementation(()=> { - // return updatedOptions; - // }); - // const misMatch = await isGlassAvailableForCarId(); - // expect(misMatch).toEqual(false); - // }); - // }); + describe("damage-helper.js", () => { + it("Should return true if no mismatches between each array exist", async () => { + const updatedOptions = { + data: { + windshieldOptions: {availableReplacementOptions: ["windshield"]} + } + } + baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn().mockImplementation(()=> { + return updatedOptions; + }); + const misMatch = await isGlassAvailableForCarId(); + expect(misMatch).toEqual(true); + }); + }); + + describe("damage-helper.js", () => { + it("Should return false if any mismatches between each array exist", async () => { + const updatedOptions = { + data: { + windshieldOptions: {availableReplacementOptions: ["Crack"]} + } + } + baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn().mockImplementation(()=> { + return updatedOptions; + }); + const misMatch = await isGlassAvailableForCarId(); + expect(misMatch).toEqual(false); + }); + }); - // describe("damage-helper.js", () => { - // it("Should return true if there are any mismatches between arrays", () => { - // const newOptions = { - // windshieldOptions: {availableReplacementOptions: ["window"]} - // } - // const currentOptions = [{location: "Windshield", name: "windshield"}]; - // const misMatch = compareGlassOptions(newOptions, currentOptions); - // expect(misMatch).toEqual(true); - // }); - // }); \ No newline at end of file diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index f9f0cb41c..da227d794 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -128,22 +128,22 @@ export default { }; }, computed: { - MatchedDifferentVehicleAlertHeader(){ + MatchedDifferentVehicleAlertHeader() { let text = this.getCmsContent("MatchedDifferentVehicleAlertWidget", "HeadlineText").replaceAll("{custom:damage}", getDamageString()); return text; }, - MatchedDifferentVehicleAlertBody(){ + MatchedDifferentVehicleAlertBody() { let text = this.getCmsContent("MatchedDifferentVehicleAlertWidget", "BodyText").replaceAll("{custom:damage}", getDamageString()).replaceAll("{custom:plateLookupYear}", this.customAlertData?.vehicleInfo?.year).replaceAll("{custom:plateLookupMake}", this.customAlertData?.vehicleInfo?.make).replaceAll("{custom:plateLookupModel}", this.customAlertData?.vehicleInfo?.model); return text; }, - NoServiceZipHeader(){ + NoServiceZipHeader() { let text = this.getCmsContent("NoServiceZipWidget", "HeadlineText").replaceAll("{custom:zip}", this.registrationZip); return text; }, - NoServiceZipBody(){ + NoServiceZipBody() { return this.getCmsContent("NoServiceZipWidget", "BodyText"); }, }, @@ -158,16 +158,16 @@ export default { store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, null); store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }, - getLicensePlateFromStore(){ + getLicensePlateFromStore() { return store.getters.vehicle.registration.licensePlate }, - getRegistrationZipFromStore(){ + getRegistrationZipFromStore() { return store.getters.vehicle.registration.zipCode }, - getEmailFromStore(){ + getEmailFromStore() { return store.getters.order.customer.emailAddress }, - getServiceZipFromStore(){ + getServiceZipFromStore() { return store.getters.order.serviceLocation.zip }, backButtonAction() { @@ -202,23 +202,13 @@ export default { return; } - this.updateCustomerInfo(vinLookup.data.vin, vinLookup.data.vehicle, zipValidation.data.state); + this.updateStoreInfo(vinLookup.data.vin, vinLookup.data.vehicle, zipValidation.data.state); - const partsData = await baseMixin.methods.dispatchNonBlockingStoreAction( - this.storeActions.GET_PARTS_OR_QUESTIONS, - { - carId: vinLookup.data.vehicle.carId, - glassArray: this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle ? [] : store.getters.damage.glassToReplace, - zipCode: this.serviceZip ? this.serviceZip : this.registrationZip, - vin: vinLookup.data.vin - }, - false - ); - this.navigateForward(partsData); + this.navigateForward(); }, - navigateForward(partsData){ + navigateForward() { if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ - this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, partsData.data); + this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {}); return; } else { navigateAfterSaveToHeritageFunnel(this.$route); @@ -237,7 +227,7 @@ export default { { licensePlate: plate, licenseState: state } ); }, - updateCustomerInfo(vin, vehicleInfo, registrationState) { + updateStoreInfo(vin, vehicleInfo, registrationState) { if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); } @@ -262,10 +252,10 @@ export default { licensePlate() { this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); }, - registrationZip(){ + registrationZip() { this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); }, - serviceZip(){ + serviceZip() { this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); } }, From 5e0e631180f12d55ba21daee339d73e9284ffc9c Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 May 2022 10:49:06 -0400 Subject: [PATCH 02/11] Unit tests --- jest.config.js | 1 - src/helpers/damage-helper.spec.js | 79 +++++++++-- .../license-plate-lookup.spec.js | 129 ++++++++++++++---- 3 files changed, 169 insertions(+), 40 deletions(-) diff --git a/jest.config.js b/jest.config.js index dc59735c2..55eb5be74 100644 --- a/jest.config.js +++ b/jest.config.js @@ -14,7 +14,6 @@ module.exports = { "!src/layouts/component-test/component-test.vue", "!src/layouts/form-test/form-test.vue", "!src/layouts/vin-lookup/vin-lookup.vue", - "!src/layouts/license-plate-lookup/license-plate-lookup.vue", "!src/layouts/vehicle-damage/windshield-damage-type-question/windshield-damage-type-question.vue", "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", "!src/layouts/part-questions/**/*.vue", diff --git a/src/helpers/damage-helper.spec.js b/src/helpers/damage-helper.spec.js index e0a9f71cc..68379ae1a 100644 --- a/src/helpers/damage-helper.spec.js +++ b/src/helpers/damage-helper.spec.js @@ -1,47 +1,100 @@ import {getDamageString, isGlassAvailableForCarId} from "./damage-helper"; import baseMixin from "@/mixins/base-mixin.js"; - -jest.mock("@/store", () => ({ - getters: {damage: { - glassToReplace: [{location: "Windshield", name: "windshield"}] - } - } -})); +import store from "@/store"; describe("damage-helper.js", () => { - it("Should return damage getter info", () => { + it("Should return match when multiple selected damage options are in the store", () => { + + // Arrange / Act + store.getters.damage.glassToReplace = [{location: "Windshield", name: "windshield"}, {location: "Passenger", name: "sideWindow"}]; + const damage = getDamageString(); - expect(damage).toEqual("windshield") + + // Assert + expect(damage).toEqual("match"); + }); + }); + + describe("damage-helper.js", () => { + it("Should return windshield when Windshield is the only selected damage option in the store", () => { + + // Arrange / Act + store.getters.damage.glassToReplace = [{location: "Windshield", name: "windshield"}]; + + const damage = getDamageString(); + + // Assert + expect(damage).toEqual("windshield"); + }); + }); + + describe("damage-helper.js", () => { + it("Should return side window when Driver or Passenger is the only selected damage option in the store", () => { + + // Arrange / Act + store.getters.damage.glassToReplace = [{location: "Passenger", name: "sideWindow"}]; + + const damage = getDamageString(); + + // Assert + expect(damage).toEqual("side window"); + }); + }); + + describe("damage-helper.js", () => { + it("Should return rear window when Rear is the only selected damage option in the store", () => { + + // Arrange / Act + store.getters.damage.glassToReplace = [{location: "Rear", name: "rear"}]; + + const damage = getDamageString(); + + // Assert + expect(damage).toEqual("rear window"); }); }); describe("damage-helper.js", () => { it("Should return true if no mismatches between each array exist", async () => { + // Arrange + store.getters.damage.glassToReplace = [{location: "Windshield", name: "windshield"}]; + const updatedOptions = { data: { windshieldOptions: {availableReplacementOptions: ["windshield"]} } } + + // Act baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn().mockImplementation(()=> { return updatedOptions; }); - const misMatch = await isGlassAvailableForCarId(); - expect(misMatch).toEqual(true); + const isGlassAvailable = await isGlassAvailableForCarId(); + + // Assert + expect(isGlassAvailable).toEqual(true); }); }); describe("damage-helper.js", () => { it("Should return false if any mismatches between each array exist", async () => { + // Arrange + store.getters.damage.glassToReplace = [{location: "Windshield", name: "windshield"}]; + const updatedOptions = { data: { windshieldOptions: {availableReplacementOptions: ["Crack"]} } } + + // Act baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn().mockImplementation(()=> { return updatedOptions; }); - const misMatch = await isGlassAvailableForCarId(); - expect(misMatch).toEqual(false); + const isGlassAvailable = await isGlassAvailableForCarId(); + + // Assert + expect(isGlassAvailable).toEqual(false); }); }); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 63459a97f..ef169c813 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -1,5 +1,5 @@ // Components -import vehicleDamage from "@/layouts/license-plate-lookup/license-plate-lookup.vue"; +import licensePlateLookup from "@/layouts/license-plate-lookup/license-plate-lookup.vue"; // Supporting Files import { settleAllPromises } from "@/helpers/layout-helper.js"; @@ -29,25 +29,15 @@ jest.mock("@/store", () => ({ dispatch: jest.fn(), getters: { order: { - customer: { - emailAddress: "test@test.com" - }, - serviceLocation: { - zip: "43443" - } + customer: { emailAddress: "test@test.com"}, + serviceLocation: {zip: "11111"}, }, vehicle: { - carId: "C00000000", - image: "test.jpg", - payment: { - insuranceCoverage: { - isVerified: false - } - }, registration: { - licensePlate: "HWV4445", - zipCode: "43224" - } + licensePlate: "TESTPLATE", + zipCode: "12345", + carId: "TESTID" + }, }, eventBusItem: jest.fn(), damage: { @@ -62,7 +52,7 @@ describe("license-plate-lookup.vue", () => { const { wrapper } = setupMocks({}); //Act - vehicleDamage.beforeRouteEnter.call( + licensePlateLookup.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "license-plate-lookup" } }, undefined, @@ -84,7 +74,7 @@ describe("license-plate-lookup.vue", () => { const { wrapper } = setupMocks({}); //Act - vehicleDamage.beforeRouteEnter.call( + licensePlateLookup.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "license-plate-lookup" } }, undefined, @@ -99,6 +89,99 @@ describe("license-plate-lookup.vue", () => { }); }); +describe("license-plate-lookup.vue", () => { + test("getLicensePlateFromStore returns store license plate", async () => { + + // Arrange + const { wrapper } = setupMocks({}); + + // ACT + const licensePlate = wrapper.vm.getLicensePlateFromStore(); + + // Assert + expect(licensePlate).toEqual("TESTPLATE"); + }); +}); + +describe("license-plate-lookup.vue", () => { + test("getRegistrationZipFromStore returns store registration zip", async () => { + + // Arrange + const { wrapper } = setupMocks({}); + + // ACT + const registrationZip = wrapper.vm.getRegistrationZipFromStore(); + + // Assert + expect(registrationZip).toEqual("12345"); + }); +}); + +describe("license-plate-lookup.vue", () => { + test("getEmailFromStore returns store customer email", async () => { + + // Arrange + const { wrapper } = setupMocks({}); + + // ACT + const customerEmail = wrapper.vm.getEmailFromStore(); + + // Assert + expect(customerEmail).toEqual("test@test.com"); + }); +}); + +describe("license-plate-lookup.vue", () => { + test("getServiceZipFromStore returns store service zip", async () => { + + // Arrange + const { wrapper } = setupMocks({}); + + // ACT + const serviceZip = wrapper.vm.getServiceZipFromStore(); + + // Assert + expect(serviceZip).toEqual("11111"); + }); +}); + +describe("license-plate-lookup.vue", () => { + test("Navigate forward should be called when data entered matches store data", async () => { + + // Arrange + const { wrapper } = setupMocks({ + pageHeaderWidgetHeaderText: "", + mountOptionsMockData: { + router: { navigateAfterSave: jest.fn(), }, + }, + }); + + wrapper.vm.licensePlate = "TESTPLATE"; + wrapper.vm.registrationZip = "12345"; + wrapper.vm.validateZip = jest.fn().mockImplementation(() => { + return {data: {isServiceable: true}}; + }); + wrapper.vm.lookupVin = jest.fn().mockImplementation(() => { + return {data: {vehicle: {carId: 'TESTID'}}, catch: () => "test"}; + }); + + //Act + licensePlateLookup.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "license-plate-lookup" } }, + undefined, + (c) => c(wrapper.vm) + ); + + await wrapper.vm.forwardButtonAction(); + + //Assert + expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled(); + expect(wrapper.vm.isCarIdDifferent).toEqual(false); + }); +}); + + function setupMocks({ pageHeaderWidgetHeaderText = {}, @@ -106,12 +189,6 @@ function setupMocks({ router: { navigate: jest.fn(), }, - store: { - getters: { - vehicle: {}, - payment: { insuranceCoverage: { isVerified: false } }, - }, - }, }, }) { //Mock api responses @@ -139,7 +216,7 @@ function setupMocks({ const mountOptions = getMountOptions(mountOptionsMockData); mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods - const wrapper = shallowMount(vehicleDamage, mountOptions); + const wrapper = shallowMount(licensePlateLookup, mountOptions); wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; From e640ff292c8b1507a1019764a75fe059c3ee7417 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 3 May 2022 13:14:26 -0400 Subject: [PATCH 03/11] Fixing routing table and creating unit tests --- .../license-plate-lookup.spec.js | 2 +- src/router/router-constants/routing-table.js | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 5a8fa5fab..d7f51de66 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -33,10 +33,10 @@ jest.mock("@/store", () => ({ serviceLocation: {zip: "11111"}, }, vehicle: { + carId: "TESTID", registration: { licensePlate: "TESTPLATE", zipCode: "12345", - carId: "TESTID" }, }, eventBusItem: jest.fn(), diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3290c43eb..83d2c57de 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -137,18 +137,6 @@ const routingTable = [ scenario: navigationScenarios.CLICKED_BACK, destinationFmgPageValue: fmgPageValues.ESTIMATE, }, - { - scenario: navigationScenarios.CONTINUING_WITH_PARTS_QUESTION, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, - }, - { - scenario: navigationScenarios.CONTINUING_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS, - }, - { - scenario: navigationScenarios.CONTINUING_WITH_SINGLE_PART, - destinationFmgPageValue: fmgPageValues.REVEAL, - }, { scenario: navigationScenarios.CLICKED_FORWARD, destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, From 842a444e5c0a4545147fe26973f658d445f6a9fd Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 4 May 2022 16:28:20 -0400 Subject: [PATCH 04/11] Fixing lpl page and nav scenario --- .../navigation-helper.spec.js | 4 +- .../license-plate-lookup.vue | 219 ++++++++++-------- 2 files changed, 118 insertions(+), 105 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index fd06920c2..17561ba52 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -175,7 +175,7 @@ describe("getPageToRouteExistingOrderTo", () => { expect(result).toBe('vehicle-damage'); }); - test("getPageToRouteExistingOrderTo, should return vin-lookup", async () => { + test("getPageToRouteExistingOrderTo, should return license-plate-lookup", async () => { // Arrange const toRoute = { query: {} @@ -228,7 +228,7 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('vin-lookup'); + expect(result).toBe('license-plate-lookup'); }); test("getPageToRouteExistingOrderTo, should return estimate", async () => { diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index ff1a2b10d..f63aea287 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -1,46 +1,35 @@ From 47380eda80047d1615938edb8a86949ea2c08c61 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 5 May 2022 12:11:31 -0400 Subject: [PATCH 05/11] Fixing unit tests --- src/helpers/damage-helper.js | 2 +- .../license-plate-lookup.spec.js | 40 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js index 25fcecc57..443712991 100644 --- a/src/helpers/damage-helper.js +++ b/src/helpers/damage-helper.js @@ -8,7 +8,7 @@ export function getDamageString() { if(damageLocations.length > 1){ returnString = "match" } else { - switch(damageLocations[0].location) { + switch(damageLocations[0]?.location) { case "Windshield": returnString = "windshield" break; diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 074e2dc75..609ddcf2e 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -151,6 +151,9 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.validateZip = jest.fn().mockImplementation(() => { return {data: {isServiceable: true}}; }); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); const vinLookup = {data: {vehicle: {carId: "TESTID"}}} wrapper.vm.lookupVin = jest.fn().mockImplementation(() => { return {catch: () => vinLookup}; @@ -182,6 +185,9 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.validateZip = jest.fn().mockImplementation(() => { return {data: {isServiceable: false}}; }); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn(); //Act licensePlateLookup.beforeRouteEnter.call( @@ -207,6 +213,9 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.validateZip = jest.fn().mockImplementation(() => { return {data: {isServiceable: true}}; }); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); const vinLookup = {data: {vehicle: {carId: "TESTID1"}}} wrapper.vm.lookupVin = jest.fn().mockImplementation(() => { return {catch: () => vinLookup}; @@ -238,6 +247,9 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.validateZip = jest.fn().mockImplementation(() => { return {data: {isServiceable: true}}; }); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); const vinLookup = {data: {vehicle: {carId: "TESTID1"}}} wrapper.vm.lookupVin = jest.fn().mockImplementation(() => { return {catch: () => vinLookup}; @@ -321,15 +333,12 @@ describe("license-plate-lookup.vue", () => { //Act wrapper.vm.isCarIdDifferent = true; wrapper.vm.isSelectedGlassAvailableForVehicle = false; + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); store.commit = jest.fn(); store.dispatch = jest.fn(); - licensePlateLookup.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "license-plate-lookup" } }, - undefined, - (c) => c(wrapper.vm) - ); const vehicleInfo = {year: "2020", make: "honda", model: "civic", style: "2 door", carId: "TestId", category: "testCat", imageUrl: "image.jpg", imageVifNumber: "123", imageColor: "blue"} await wrapper.vm.updateCustomerInfo('vin', vehicleInfo, 'registrationState'); @@ -348,14 +357,11 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.isCarIdDifferent = true; wrapper.vm.isSelectedGlassAvailableForVehicle = false; wrapper.vm.$router.navigateAfterSave = jest.fn(); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); store.dispatch = jest.fn(); - licensePlateLookup.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "license-plate-lookup" } }, - undefined, - (c) => c(wrapper.vm) - ); await wrapper.vm.navigateForward(); //Assert @@ -372,16 +378,12 @@ describe("license-plate-lookup.vue", () => { //Act wrapper.vm.isCarIdDifferent = false; wrapper.vm.$router.navigateAfterSaveToHeritageFunnel = jest.fn(); + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { + return ''; + }); - licensePlateLookup.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "license-plate-lookup" } }, - undefined, - (c) => c(wrapper.vm) - ); await wrapper.vm.navigateForward(); - //Assert expect(wrapper.vm.$router.navigateAfterSaveToHeritageFunnel).toHaveBeenCalled(); }); From 3c06e44da556152bc877a7c40d79369cfc195a15 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 6 May 2022 09:57:31 -0400 Subject: [PATCH 06/11] CSR-520 loading modal --- src/assets/img/loader.gif | Bin 0 -> 71541 bytes src/assets/img/windshield.png | Bin 0 -> 1074 bytes .../loading-modal/loading-modal.vue | 126 ++++++++++++++++++ src/layouts/address-lookup/address-lookup.vue | 12 ++ .../license-plate-lookup.vue | 15 ++- src/layouts/vin-lookup/vin-lookup.vue | 15 ++- 6 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 src/assets/img/loader.gif create mode 100644 src/assets/img/windshield.png create mode 100644 src/common-components/loading-modal/loading-modal.vue diff --git a/src/assets/img/loader.gif b/src/assets/img/loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..c069b049ddb19c9a7a18085afa73109cc14500a5 GIT binary patch literal 71541 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 literal 0 HcmV?d00001 diff --git a/src/common-components/loading-modal/loading-modal.vue b/src/common-components/loading-modal/loading-modal.vue new file mode 100644 index 000000000..4f1365802 --- /dev/null +++ b/src/common-components/loading-modal/loading-modal.vue @@ -0,0 +1,126 @@ + + + + + \ No newline at end of file diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 6d0240ae0..395c519b3 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -6,6 +6,14 @@ v-slot="{ meta }" autocomplete="off" >
+ + + + @@ -68,6 +76,7 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he import customerQuestions from "@/layouts/address-lookup/customer-questions/customer-questions"; import alert from "@/ux-components/alert/alert"; import textboxQuestion from "@/common-components/textbox-question/textbox-question"; +import loadingModal from '@/common-components/loading-modal/loading-modal.vue'; import { Form } from "vee-validate"; import { defineRule } from "vee-validate"; @@ -251,6 +260,7 @@ export default { // if the car entered is the same as the car found OR the glass options for the found car match the users damage selections if (carEntered.carId == carFound.carId || isGlassAvailableForCarId(carFound.carId)) { + this.$refs.loadingModal.showModal(); navigateAfterSaveToHeritageFunnel(this.$route); } else { // if not then navigate to the "vehicle-damage" page @@ -260,6 +270,7 @@ export default { // if multiple cars were found if (carsFound.find(car => car.carId === carEntered.carId)) { // and one of them matches the car id entered + this.$refs.loadingModal.showModal(); navigateAfterSaveToHeritageFunnel(this.$route); } else { // and there is no match, navigate to "address-vehicle" page @@ -359,6 +370,7 @@ export default { customerQuestions, textboxQuestion, alert, + loadingModal, Form }, }; diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index cce368d5c..c2409df3d 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -5,9 +5,15 @@ ref="theForm" v-slot="{ meta }" > -
+
+ + + + diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 0072708f4..f41f9a943 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -5,9 +5,15 @@ ref="theForm" v-slot="{ meta }" > -
+
+ + + + From 78f965ec4f4f35d25e406ab49929ced40c2b0abf Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 6 May 2022 10:12:04 -0400 Subject: [PATCH 07/11] CSR-520 loading modal --- .../license-plate-lookup.vue | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index d22d311e2..a1f507697 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -1,6 +1,14 @@ @@ -169,7 +170,7 @@ import baseMixin from "@/mixins/base-mixin.js"; import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "@/constants/store-mutations"; import { errorMessages } from "@/constants/error-messages"; -import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper"; +import { getDamageString, getIsWindshieldOnly, isGlassAvailableForCarId } from "@/helpers/damage-helper"; import { required, regex } from "@/helpers/validation-rules"; import { Form, defineRule } from "vee-validate"; import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; @@ -260,6 +261,13 @@ export default { return this.getCmsContent("PerfectMatchNewVinAlert", "BodyText").replaceAll("{custom:damage}", getDamageString()) }, + PerfectMatchNewVinAlertReadOnlyHeader () { + return this.getCmsContent("PerfectMatchNewVinAlertReadOnly", "HeadlineText"); + }, + PerfectMatchNewVinAlertReadOnlyBody () { + return this.getCmsContent("PerfectMatchNewVinAlertReadOnly", "BodyText").replaceAll("{custom:damage}", + getIsWindshieldOnly()) + }, isVinFieldReadOnly(){ return this.$store.getters.payment.insuranceCoverage.isVerified; }, From e1fa0df8209fc6d9cb61d2b5aeeb3f8fd0f05f1f Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 6 May 2022 15:28:02 -0400 Subject: [PATCH 10/11] CSR-520 broken test fix --- src/layouts/license-plate-lookup/license-plate-lookup.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 609ddcf2e..71a9e2a28 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -10,6 +10,9 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { nextTick } from "vue"; import store from "@/store"; +jest.mock('@/assets/img/loader.gif', () => 'loader.gif') +jest.mock('@/assets/img/windshield.png', () => 'windshield.png') + // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ settleAllPromises: jest.fn(), @@ -378,6 +381,7 @@ describe("license-plate-lookup.vue", () => { //Act wrapper.vm.isCarIdDifferent = false; wrapper.vm.$router.navigateAfterSaveToHeritageFunnel = jest.fn(); + wrapper.vm.$refs.loadingModal.showModal = jest.fn(); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { return ''; }); From aab32ef7b1fcc499a72c2a48274591c18474c19d Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 6 May 2022 16:12:56 -0400 Subject: [PATCH 11/11] Bug fixes, 1) added zipToDisplay datum for cases when registration zip entered is also not valid, 2) changed navigateAfterSaveToHeritageFunnel function to exported function as it is not in global and fixed unit tests with it. 3) Fixed updateServiceLocationZipCode name in vuex. --- .../license-plate-lookup/license-plate-lookup.spec.js | 6 +++--- .../license-plate-lookup/license-plate-lookup.vue | 9 +++++++-- src/store/index.js | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 609ddcf2e..6e86cd9f5 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -3,6 +3,7 @@ import licensePlateLookup from "@/layouts/license-plate-lookup/license-plate-loo // Supporting Files import { settleAllPromises } from "@/helpers/layout-helper.js"; +import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper"; import baseMixin from "@/mixins/base-mixin"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { shallowMount, flushPromises } from "@vue/test-utils"; @@ -377,15 +378,14 @@ describe("license-plate-lookup.vue", () => { //Act wrapper.vm.isCarIdDifferent = false; - wrapper.vm.$router.navigateAfterSaveToHeritageFunnel = jest.fn(); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { return ''; }); - + navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn(); await wrapper.vm.navigateForward(); //Assert - expect(wrapper.vm.$router.navigateAfterSaveToHeritageFunnel).toHaveBeenCalled(); + expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toHaveBeenCalled(); }); }); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 356a8ec9e..84b58e93d 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -61,6 +61,9 @@ import { import { errorMessages } from "@/constants/error-messages"; +import { + navigateAfterSaveToHeritageFunnel +} from "@/helpers/heritage-integration/navigation-helper"; import { getDamageString, isGlassAvailableForCarId, @@ -125,6 +128,7 @@ export default { previouslyEnteredCarId: "", customAlertData: {}, isSelectedGlassAvailableForVehicle: true, + zipToDisplay: this.getRegistrationZipFromStore(), }; }, mounted() { @@ -162,7 +166,7 @@ export default { let text = this.getCmsContent( "NoServiceZipWidget", "HeadlineText" - ).replaceAll("{custom:zip}", this.registrationZip); + ).replaceAll("{custom:zip}", this.zipToDisplay); return text; }, NoServiceZipBody() { @@ -214,6 +218,7 @@ export default { this.isVinValid = true; this.isRegistrationZipServicable = false; this.isCarIdDifferent = false; + this.zipToDisplay = this.serviceZip ? this.serviceZip : this.registrationZip; return; } @@ -265,7 +270,7 @@ export default { ); return; } else { - this.$router.navigateAfterSaveToHeritageFunnel(this.$route); + navigateAfterSaveToHeritageFunnel(this.$route); return; } }, diff --git a/src/store/index.js b/src/store/index.js index 75bd4807d..d570b5c4e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -144,9 +144,9 @@ export const mutations = { updateRegistrationAddress(state, registrationAddress){ state.order.vehicle.registration.address = registrationAddress; }, - updateServiceLocationZip(state, serviceLocationZip){ + updateServiceLocationZipCode(state, serviceLocationZip){ state.order.vehicle.registration.zip = serviceLocationZip; - }, + }, updateRegistrationCity(state, serviceCity){ state.order.vehicle.registration.city = serviceCity; },