From 1e4f5f24ed4d86e7b140e6a0d4c7f05ea1fae0d3 Mon Sep 17 00:00:00 2001 From: Minojhini Valaiyapathi Date: Tue, 8 Apr 2025 15:19:30 -0400 Subject: [PATCH] CASH-353 - Estimate pages serviceable Zip code change - error --- .../address-lookup/address-lookup.spec.js | 45 ++++++++++++++++ src/layouts/address-lookup/address-lookup.vue | 35 ++++++++++++- .../license-plate-lookup.spec.js | 48 +++++++++++++++++ .../license-plate-lookup.vue | 35 +++++++++++++ src/layouts/service-zip/service-zip.spec.js | 39 ++++++++++++++ src/layouts/service-zip/service-zip.vue | 35 ++++++++++++- src/layouts/vehicle/vehicle.vue | 2 +- src/layouts/vin-lookup/vin-lookup.spec.js | 34 ++++++++++++ src/layouts/vin-lookup/vin-lookup.vue | 52 +++++++++++++++++-- 9 files changed, 319 insertions(+), 6 deletions(-) diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index 677c14069..19a46abb8 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -182,6 +182,39 @@ describe("address-lookup.vue", () => { // Assert expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true); }); + test("should show the AlertNoService when displayNoServiceAlert is true", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: true, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + + // Set displayNoServiceAlert to true + await wrapper.setData({ displayNoServiceAlert: true }); + + // Check if the AlertNoService component is rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(true); + }); + test("should hide the AlertNoService when displayNoServiceAlert is false", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: false, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + // Ensure displayNoServiceAlert is false + await wrapper.setData({ displayNoServiceAlert: false }); + + // Check if the AlertNoService component is not rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(false); + }); }); describe("navigation", () => { @@ -741,6 +774,18 @@ function setupMocks({ wrapper.vm.setCmsContent = jest.fn(); wrapper.vm.$refs.navbar.updateButtonText = jest.fn(); wrapper.vm.$refs.navbar.removeLoader = jest.fn(); + const closestShops = { + data: { + providers: [ + { id: 1, name: "Shop 1" }, + { id: 2, name: "Shop 2" }, + ], + }, + }; + + wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => { + return new Promise((resolve) => resolve(closestShops)); + }); return { wrapper }; } diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index f8cac123b..d3e3b7b98 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -81,13 +81,20 @@ + + :isForwardActionDisabled="!meta.valid || displayNoServiceAlert" /> @@ -164,6 +171,8 @@ export default { emailOrSms: this.getEmailOrSmsFromStore(), }, serviceZipCode: this.getServiceZipFromStore(), + carId: this.getCarIdfromStore(), + isHeavyTruck: this.getIsVehicleHeavyTruckFromStore(), displayNonServiceableZipAlert: false, displayVinNotFoundAlert: false, displayMatchedDifferentVehicleAlert: false, @@ -175,6 +184,7 @@ export default { displayInvalidZipAlert: false, showServiceZipField: this.getServiceZipFromStore(), isZipServiceable: false, + displayNoServiceAlert: false }; }, methods: { @@ -219,6 +229,19 @@ export default { getServiceZipFromStore() { return this.$store.getters.order.serviceLocation.zipCode; }, + getCarIdfromStore() { + return store.getters.vehicle.carId; + }, + getIsVehicleHeavyTruckFromStore() { + return store.getters.isHeavyTruckVehicle; + }, + async findClosestApplicableShops() { + return await this.dispatchStoreActionWithLogging( + storeActions.GET_CLOSEST_APPLICABLE_SHOPS, + { zip: this.serviceZipCode, carId: this.carId }, + "address-lookup" + ); + }, async forwardButtonAction() { this.resetWarningsAndErrors(); @@ -278,6 +301,14 @@ export default { return this.$refs.navbar.removeLoader(); } this.displayInvalidZipAlert = false; + const closestShops = await this.findClosestApplicableShops( + this.serviceZipCode, + this.carId + ); + this.displayNoServiceAlert = !closestShops?.data?.providers?.length; + if (this.displayNoServiceAlert) { + return this.$refs.navbar.removeLoader(); + } const carsFound = resultMap.vinLookupResponse.vinVehicles; @@ -430,6 +461,7 @@ export default { this.displayNonServiceableZipAlert = false; this.displayMatchedDifferentVehicleAlert = false; this.displayVinLookupByHomeAddressNotAllowedAlert = false; + this.displayNoServiceAlert = false; }, }, mounted() { @@ -481,6 +513,7 @@ export default { handler(newValue) { // If they modify the service zip code, then hide the error message. this.displayNonServiceableZipAlert = false; + this.displayNoServiceAlert = false; }, }, showServiceZipField: { 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 2d4b729d8..2ffe61193 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -611,6 +611,42 @@ describe("license-plate-lookup.vue", () => { expect(arePagePrerequisitesValid).toBe(false); }); }); + + describe("alerts", () => { + test("should show the AlertNoService when displayNoServiceAlert is true", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: true, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + + // Set displayNoServiceAlert to true + await wrapper.setData({ displayNoServiceAlert: true }); + + // Check if the AlertNoService component is rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(true); + }); + test("should hide the AlertNoService when displayNoServiceAlert is false", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: false, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + // Ensure displayNoServiceAlert is false + await wrapper.setData({ displayNoServiceAlert: false }); + + // Check if the AlertNoService component is not rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(false); + }); + }); }); function setupMocks({ @@ -716,6 +752,18 @@ function setupMocks({ wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ""); wrapper.vm.$refs.navbar.updateButtonText = jest.fn(); wrapper.vm.$refs.navbar.removeLoader = jest.fn(); + const closestShops = { + data: { + providers: [ + { id: 1, name: "Shop 1" }, + { id: 2, name: "Shop 2" }, + ], + }, + }; + + wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => { + return new Promise((resolve) => resolve(closestShops)); + }); return { wrapper, apiPromise }; } diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 8b9c83c67..6bf71378f 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -76,6 +76,14 @@ :manualCopy="AlertMatchedDifferentVehicleBody" alertClass="alert-warning" v-bind:isDismissible="false" /> + + { expect(wrapper.vm.displayInvalidZipAlert).toBe(false); expect(wrapper.vm.displayNonServiceableZipAlert).toBe(false); }); + test("should show the AlertNoService when displayNoServiceAlert is true", async () => { + // Arrange + // no changes to store + applyMockStoreDataToGetters(); + + const wrapper = setupMocks({}); + wrapper.vm.serviceZipCode = "12345"; + + // Act + wrapper.vm.displayNoServiceAlert = true; + + // Check if the AlertNoService component is rendered + expect(wrapper.vm.displayNoServiceAlert).toBe(true); + }); + test("should hide the AlertNoService when displayNoServiceAlert is false", async () => { + // Arrange + // no changes to store + applyMockStoreDataToGetters(); + + const wrapper = setupMocks({}); + wrapper.vm.serviceZipCode = "12345"; + //ACT + wrapper.vm.displayNoServiceAlert = false; + + // Check if the AlertNoService component is rendered + expect(wrapper.vm.displayNoServiceAlert).toBe(false); + }); }); }); @@ -509,6 +538,16 @@ function setupMocks({ customMountOptions, customZipQuery, customZipDataResponse ]; const wrapper = shallowMount(serviceZip, mountOptions); + wrapper.vm.findClosestApplicableShops = jest.fn().mockImplementation(() => { + return Promise.resolve({ + data: { + providers: [ + { id: 1, name: "Shop 1" }, + { id: 2, name: "Shop 2" }, + ], + }, + }); + }); return wrapper; } diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index 9528d50bc..5b8f0375b 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -46,11 +46,19 @@ v-model="customAlertData" v-if="displayNonServiceableZipAlert" alertClass="alert-danger" /> + + @@ -110,8 +118,11 @@ export default { return { serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode, emailOrSms: this.getEmailOrSmsFromStore(), + carId: this.getCarIdfromStore(), + isHeavyTruck: this.getIsVehicleHeavyTruckFromStore(), displayInvalidZipAlert: false, displayNonServiceableZipAlert: false, + displayNoServiceAlert: false, }; }, @@ -184,6 +195,19 @@ export default { arePagePrerequisitesValid() { return store.getters.damage.isRepair || store.getters.damage.glassToReplace?.length > 0; }, + getCarIdfromStore() { + return store.getters.vehicle.carId; + }, + getIsVehicleHeavyTruckFromStore() { + return store.getters.isHeavyTruckVehicle; + }, + async findClosestApplicableShops() { + return await this.dispatchStoreActionWithLogging( + storeActions.GET_CLOSEST_APPLICABLE_SHOPS, + { zip: this.serviceZipCode, carId: this.carId }, + "service-zip" + ); + }, async backButtonAction() { const skipVin = await skipVinLookup(); // route to move backwards @@ -252,6 +276,14 @@ export default { return this.$refs.navbar.removeLoader(); } this.displayNonServiceableZipAlert = false; + const closestShops = await this.findClosestApplicableShops( + this.serviceZipCode, + this.carId + ); + this.displayNoServiceAlert = !closestShops?.data?.providers?.length; + if (this.displayNoServiceAlert) { + return this.$refs.navbar.removeLoader(); + } const payment = this.$store.getters.payment; const policy = this.$store.getters.policy; @@ -309,6 +341,7 @@ export default { watch: { serviceZipCode() { this.displayNonServiceableZipAlert = false; + this.displayNoServiceAlert = false; }, }, components: { diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index bad52fb02..53c70176f 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -430,7 +430,7 @@ export default { ); }, isBigTruckAndCanService() { - return this.isBigTruck && this.canSafeliteService; + return true;//this.isBigTruck && this.canSafeliteService; }, }, methods: { diff --git a/src/layouts/vin-lookup/vin-lookup.spec.js b/src/layouts/vin-lookup/vin-lookup.spec.js index 39aa0f008..458f9fc48 100644 --- a/src/layouts/vin-lookup/vin-lookup.spec.js +++ b/src/layouts/vin-lookup/vin-lookup.spec.js @@ -32,6 +32,7 @@ jest.mock("@/store", () => ({ damage: { glassToReplace: "windshield", }, + isHeavyTruckVehicle: true, }, })); @@ -257,6 +258,39 @@ describe("vin-lookup.vue", () => { // Assert expect(wrapper.findAllComponents({ name: "alert" }).length).toBe(1); }); + + test("should show the AlertNoService when displayNoServiceAlert is true", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: true, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + // Set displayNoServiceAlert to true + await wrapper.setData({ displayNoServiceAlert: true }); + + // Check if the AlertNoService component is rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(true); + }); + test("should hide the AlertNoService when displayNoServiceAlert is false", async () => { + const { wrapper } = setupMocks({ + isZipServiceable: true, + displayNoServiceAlert: false, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + // Ensure displayNoServiceAlert is false + await wrapper.setData({ displayNoServiceAlert: false }); + + // Check if the AlertNoService component is not rendered + const alertNoService = wrapper.findComponent({ ref: "AlertNoService" }); + expect(alertNoService.exists()).toBe(false); + }); }); describe("getVinFromImage", () => { diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index f913993b2..9a69a8450 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -71,7 +71,8 @@ vinPopulatedOnPageLoad && isInsuranceVerified && !displayInvalidZipAlert && - !displayNonServiceableZipAlert + !displayNonServiceableZipAlert && + !displayNoServiceAlert " alertClass="alert-success" /> @@ -107,14 +108,23 @@ vinPopulatedOnPageLoad && !isInsuranceVerified && !displayInvalidZipAlert && - !displayNonServiceableZipAlert + !displayNonServiceableZipAlert && + !displayNoServiceAlert " alertClass="alert-success" /> + + @@ -197,6 +207,8 @@ export default { vin: this.getVinFromStore(), serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode, emailOrSms: this.getEmailOrSmsFromStore(), + carId: this.getCarIdfromStore(), + isHeavyTruck: this.getIsVehicleHeavyTruckFromStore(), isCarIdDifferent: false, customAlertData: {}, previouslyEnteredCarId: "", @@ -207,6 +219,7 @@ export default { displayVinNotFoundAlert: false, displayMatchedDifferentVehicleAlert: false, displayVinScanFailedAlert: false, + displayNoServiceAlert: false }; }, methods: { @@ -222,6 +235,12 @@ export default { getZipFromStore() { return this.$store.getters.order.serviceLocation.zipCode; }, + getCarIdfromStore() { + return store.getters.vehicle.carId; + }, + getIsVehicleHeavyTruckFromStore() { + return store.getters.isHeavyTruckVehicle; + }, attachCustomEvents() { this.prependActionToMethod(this, this.forwardButtonAction, () => { this.pushEventToGA( @@ -245,6 +264,13 @@ export default { ); } }, + async findClosestApplicableShops() { + return await this.dispatchStoreActionWithLogging( + storeActions.GET_CLOSEST_APPLICABLE_SHOPS, + { zip: this.serviceZipCode, carId: this.carId }, + "vin-lookup" + ); + }, async forwardButtonAction() { this.resetAlerts(); @@ -277,6 +303,15 @@ export default { return this.$refs.navbar.removeLoader(); } this.displayInvalidZipAlert = false; + // If a VIN has already been found. Validate the Service Zip (in case of changes) + var closestShops = await this.findClosestApplicableShops( + this.serviceZipCode, + this.carId + ); + this.displayNoServiceAlert = !closestShops?.data?.providers?.length; + if (this.displayNoServiceAlert) { + return this.$refs.navbar.removeLoader(); + } // If either lookup fails, remove the loader and stop processing the page. if (!resultMap.vehicleLookupResponse || !resultMap.zipCodeData.isServiceable) { @@ -394,6 +429,15 @@ export default { ); } + closestShops = await this.findClosestApplicableShops( + this.serviceZipCode, + this.carId + ); + this.displayNoServiceAlert = !closestShops?.data?.providers?.length; + if (this.displayNoServiceAlert) { + return this.$refs.navbar.removeLoader(); + } + // if no value due to field being optional, blank both phone and email address if (!this.emailOrSms) { await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); @@ -476,6 +520,7 @@ export default { this.displayInvalidZipAlert = false; this.displayVinNotFoundAlert = false; this.displayVinScanFailedAlert = false; + this.displayNoServiceAlert = false; }, }, mounted() { @@ -552,6 +597,7 @@ export default { }, serviceZipCode() { this.displayNonServiceableZipAlert = false; + this.displayNoServiceAlert = false; }, }, components: {