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: {