diff --git a/src/constants/vehicle-lookup-alert-types.js b/src/constants/vehicle-lookup-alert-types.js index 551ebe0a..98961165 100644 --- a/src/constants/vehicle-lookup-alert-types.js +++ b/src/constants/vehicle-lookup-alert-types.js @@ -2,7 +2,8 @@ const vehicleLookupAlertTypes = Object.freeze({ NOT_FOUND: 'notFound', NOT_MATCHED: 'notMatched', TWO_IDENTICAL_YMM_MATCHED: 'twoIdenticalYMMMatched', - PERFECT_MATCH: 'perfectMatch' + PERFECT_MATCH: 'perfectMatch', + NO_SERVICE: 'noService' }); export default vehicleLookupAlertTypes; diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index 6bf15d2e..dfbb7159 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -110,7 +110,8 @@ describe('address-lookup.vue', () => { vinVehicles: [ { vehicle: { - carId: 'C00000' + carId: 'C00000', + canSafeliteService: true } } ] @@ -144,7 +145,8 @@ describe('address-lookup.vue', () => { vinVehicles: [ { vehicle: { - carId: 'C00000' + carId: 'C00000', + canSafeliteService: true } } ] @@ -275,7 +277,8 @@ describe('address-lookup.vue', () => { vinVehicles: [ { vehicle: { - carId: 'C11111' + carId: 'C11111', + canSafeliteService: true } } ] @@ -468,5 +471,76 @@ describe('address-lookup.vue', () => { // Assert expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1); }); + + test('selected vehicle is a non-serviceable big truck, display no service alert', async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: '1234 Main St', + city: 'Columbus', + state: 'OH', + zipCode: '43215' + }; + + const { wrapper } = setupMocks({ + vinVehicles: [ + { + vehicle: { + carId: 'BIGTRUCKCARID', + isBigTruck: true, + canSafeliteService: false + } + } + ] + }); + + useMainStore().order.vehicle.carId = 'BIGTRUCKCARID'; + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: 'alertNoService' }).isVisible()).toBe(true); + }); + test('selected vehicle is a serviceable big truck, do not display no service alert', async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: '1234 Main St', + city: 'Columbus', + state: 'OH', + zipCode: '43215' + }; + + const { wrapper } = setupMocks({ + vinVehicles: [ + { + vehicle: { + carId: 'BIGTRUCKCARID2', + isBigTruck: true, + canSafeliteService: true + } + } + ] + }); + + useMainStore().order.vehicle.carId = 'BIGTRUCKCARID2'; + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress + }, + }); + + // Act + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.findComponent({ ref: 'alertNoService' }).exists()).toBe(false); + }); }); }); diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 6a63e895..f778d642 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -53,6 +53,13 @@ cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget" alertClass="alert-danger" :isDismissible="false" /> + @@ -137,7 +144,8 @@ export default { isCarIdDifferent: false, isSelectedGlassAvailableForVehicle: true, customAlertData: {}, - forwardButtonCarStyle: '' + forwardButtonCarStyle: '', + displayNoServiceAlert: false }; }, computed: { @@ -262,6 +270,12 @@ export default { // Single VIN found const carFound = carsFound[0].vehicle; + if (!carFound.canSafeliteService) { + this.displayNoServiceAlert = true; + this.$refs.siteFooter.disableForwardButton(); + return this.$refs.siteFooter.removeLoader(); + } + this.isCarIdDifferent = carFound.carId !== useMainStore().order.vehicle.carId; if (this.isCarIdDifferent && carFound.carId !== this.previouslyEnteredCarId) { @@ -370,6 +384,7 @@ export default { this.displayVinNotFoundAlert = false; this.displayMatchedDifferentVehicleAlert = false; this.displayVinLookupByHomeAddressNotAllowedAlert = false; + this.displayNoServiceAlert = false; this.$refs.siteFooter.enableForwardAction(); } } diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js index 14d97555..faea9e87 100644 --- a/src/layouts/address-vehicles/address-vehicles.spec.js +++ b/src/layouts/address-vehicles/address-vehicles.spec.js @@ -120,6 +120,7 @@ function setupMocks({ wrapper.vm.navigateBack = baseMixin.methods.navigateBack; wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn(); wrapper.vm.$refs.siteFooter.removeLoader = jest.fn(); + wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn(); return { wrapper }; } @@ -248,4 +249,94 @@ describe('address-vehicles.vue', () => { // Assert expect(arePagePrerequisitesValid).toBe(true); }); + + test('selected vehicle is a non-serviceable big truck, display no service alert', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().order.vehicle.carId = 'BIGTRUCKCARID'; + useMainStore().applicationUser = { + pageData: { + 'address-vehicles': + [ + { + vehicle: { + carId: 'BIGTRUCKCARID', + make: 'Isuzu', + model: 'Reach', + style: 'Step Van', + year: 2015, + isBigTruck: true, + canSafeliteService: false + }, + vin: 'BIGTRUCKVIN' + } + ] + } + }; + + await wrapper.setData({ + selectedVehicleVin: 'BIGTRUCKVIN', + previouslyEnteredCarId: 'BIGTRUCKCARID' + }); + + wrapper.vm.selectedVehicle = { + vin: 'BIGTRUCKVIN', + vehicle: { + carId: 'BIGTRUCKCARID', + isBigTruck: true, + canSafeliteService: false + } + } + + // Act + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.findComponent({ ref: 'AlertNoService' }).isVisible()).toBe(true); + }); + + test('selected vehicle is a serviceable big truck, do not display no service alert', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().order.vehicle.carId = 'BIGTRUCKCARID2'; + useMainStore().applicationUser = { + pageData: { + 'address-vehicles': + [ + { + vehicle: { + carId: 'BIGTRUCKCARID2', + make: 'Mack', + model: 'Terrapro', + style: 'Cabover', + year: 2024, + isBigTruck: true, + canSafeliteService: true + }, + vin: 'BIGTRUCKVIN2' + } + ] + } + }; + + await wrapper.setData({ + selectedVehicleVin: 'BIGTRUCKVIN2', + previouslyEnteredCarId: 'BIGTRUCKCARID2' + }); +2 + wrapper.vm.selectedVehicle = { + vin: 'BIGTRUCKVIN2', + vehicle: { + carId: 'BIGTRUCKCARID2', + isBigTruck: true, + canSafeliteService: true + } + } + + // Act + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.findComponent({ ref: 'AlertNoService' }).exists()).toBe(false); + }); }); diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index 4dc43525..6f57e98a 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -26,6 +26,13 @@ :manualHeadline="AlertFoundMultipleVehiclesHeader" manualCopy="" :isDismissible="false" /> + { // Assert expect(wrapper.findComponent({ ref: 'alertVinNotFound' }).isVisible()).toBe(true); }); + test('non-serviceable big truck found, display NoServiceAlert', async () => { + // Arrange + const mockRegistrationLicensePlate = { + licensePlate: 'BIGTRUCKTEST' + }; + + const { wrapper } = setupMocks({ + lookupVinByPlateResponse: { + vin: 'BIGTRUCKVIN', + vehicle: { + carId: 'BIGTRUCKTESTCARID', + isBigTruck: true, + canSafeliteService: false + } + } + }); + + useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID'; + + await wrapper.setData({ + licensePlate: mockRegistrationLicensePlate + }); + + wrapper.vm.navigateForward = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: 'alertNoService' }).isVisible()).toBe(true); + }); + test('serviceable big truck found, do not display NoServiceAlert', async () => { + // Arrange + const mockRegistrationLicensePlate = { + licensePlate: 'BIGTRUCKTEST2' + }; + + const { wrapper } = setupMocks({ + lookupVinByPlateResponse: { + vin: 'BIGTRUCKVIN2', + vehicle: { + carId: 'BIGTRUCKTESTCARID2', + isBigTruck: true, + canSafeliteService: true + } + } + }); + + useMainStore().order.vehicle.carId = 'BIGTRUCKTESTCARID2'; + + await wrapper.setData({ + licensePlate: mockRegistrationLicensePlate + }); + + wrapper.vm.navigateForward = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: 'alertNoService' }).exists()).toBe(false); + }); }); describe('navigation', () => { diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index cca0a20a..991976ab 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -47,6 +47,13 @@ :manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody" alertClass="alert-warning" :isDismissible="false" /> + { // Assert expect(wrapper.vm.selectedVehicleVin).toBe(vin); }); + + test('selected vehicle is a non-serviceable big truck, display no service alert', async () => { + // Arrange + const vin = getRandomString(17, 17); + const policyVehicle = { + vin, + isBigTruck: true, + canSafeliteService: false + }; + + const { wrapper } = setupMocks({}); + + await wrapper.setData({ + selectedVehicleVin: vin, + selectedPolicyVehicle: policyVehicle, + policyVehicles: [policyVehicle], + policyVinFound: true + }); + + wrapper.vm.displayNoServiceAlert = true; + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.findComponent({ ref: 'AlertNoService' }).isVisible()).toBe(true); + }); + + test('selected vehicle is a serviceable big truck, do not display no service alert', async () => { + // Arrange + const vin = getRandomString(17, 17); + const policyVehicle = { + vin, + isBigTruck: true, + canSafeliteService: true + }; + + const { wrapper } = setupMocks({}); + + await wrapper.setData({ + selectedVehicleVin: vin, + selectedPolicyVehicle: policyVehicle, + policyVehicles: [policyVehicle], + policyVinFound: true + }); + + wrapper.vm.displayNoServiceAlert = false; + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.findComponent({ ref: 'AlertNoService' }).exists()).toBe(false); + }); }); diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 65cc7ea6..7b9ffb87 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -24,6 +24,13 @@ cmsWidgetName="PolicyVehiclesQuestion" :vehicles="VehiclesForQuestions" :validationRules="rules.optionRequired" /> + p.vin === this.selectedVehicleVin); } - return null; }, noCoverageForSelectedVehicle() { @@ -137,6 +146,7 @@ export default { }, watch: { async selectedVehicleVin(value) { + this.displayNoServiceAlert = false; if (value === vehicleSelectionOptions.VEHICLE_NOT_LISTED) { // clear previously selected vehicle and image this.mainStore.resetVehicleState(); @@ -151,6 +161,10 @@ export default { this.displayGeneric = true; return; } + if (!vehicle?.data.canSafeliteService) { + this.displayNoServiceAlert = true; + this.$refs.siteFooter.disableForwardButton(); + } if (vehicle) { // save selected vehicle to the store this.displayGeneric = false; diff --git a/src/layouts/vehicle-selection/vehicle-selection.vue b/src/layouts/vehicle-selection/vehicle-selection.vue index 59b96b38..5ff967aa 100644 --- a/src/layouts/vehicle-selection/vehicle-selection.vue +++ b/src/layouts/vehicle-selection/vehicle-selection.vue @@ -52,18 +52,23 @@ :updateValues="updateStyleValues" validationRules="style-required" inputId="styleQuestionField" /> - - + @@ -79,6 +84,7 @@ import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue'; import vehicleQuestion from '@/layouts/vehicle-selection/vehicle-question/vehicle-question.vue'; +import alert from '@/ux-components/alert/alert.vue'; import { useMainStore } from '@/store'; // Supporting files @@ -105,7 +111,8 @@ export default { siteFooter, // eslint-disable-next-line vue/no-reserved-component-names Form, - vehicleQuestion + vehicleQuestion, + alert }, mixins: [baseFormMixin], @@ -138,7 +145,8 @@ export default { selectedYear: year, selectedMake: make, selectedModel: model, - selectedStyle: style + selectedStyle: style, + displayNoServiceAlert: false }; }, computed: { @@ -146,9 +154,9 @@ export default { return !this.selectedStyle; } }, - watch: { selectedYear(value) { + this.resetAlert(); this.mainStore.updateVehicleYear(value); this.$refs.vehicleMakeQuestion.clearValues(); if (value) { @@ -156,6 +164,7 @@ export default { } }, selectedMake(value) { + this.resetAlert(); this.mainStore.updateVehicleMake(value); this.$refs.vehicleModelQuestion.clearValues(); if (value) { @@ -163,6 +172,7 @@ export default { } }, selectedModel(value) { + this.resetAlert(); this.mainStore.updateVehicleModel(value); this.$refs.vehicleStyleQuestion.clearValues(); if (value) { @@ -170,8 +180,16 @@ export default { } }, selectedStyle(value) { + this.resetAlert(); this.mainStore.updateVehicleStyle(value); - this.mainStore.setVehicle(); + this.mainStore.setVehicle( + this.selectedYear, + this.selectedMake, + this.selectedModel, + this.selectedStyle + ).then((result) => { + this.displayNoServiceAlert = !result.data.canSafeliteService; + }); } }, mounted() { @@ -185,6 +203,16 @@ export default { if (this.selectedModel) { this.$refs.vehicleStyleQuestion.getNewValues(); } + if (this.selectedStyle) { + this.mainStore.setVehicle( + this.selectedYear, + this.selectedMake, + this.selectedModel, + this.selectedStyle + ).then((result) => { + this.displayNoServiceAlert = !result.data.canSafeliteService; + }); + } }, methods: { arePagePrerequisitesValid() { @@ -264,7 +292,10 @@ export default { this.$route ); }); - } + }, + resetAlert() { + this.displayNoServiceAlert = false; + } } }; diff --git a/src/layouts/vin-lookup/vin-lookup-alerts/no-service-alert/no-service-alert.vue b/src/layouts/vin-lookup/vin-lookup-alerts/no-service-alert/no-service-alert.vue new file mode 100644 index 00000000..78190e1a --- /dev/null +++ b/src/layouts/vin-lookup/vin-lookup-alerts/no-service-alert/no-service-alert.vue @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.spec.js b/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.spec.js index 6f6a3e41..c35c5b7c 100644 --- a/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.spec.js +++ b/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.spec.js @@ -68,4 +68,17 @@ describe('vin-lookup-alerts.vue', () => { expect(twoIdenticalYMMVehicleAlert).toBeVisible(); }); + test('NoServiceAlert is displayed on the screen', () => { + mountOptions.props = { + activeAlertType: vehicleLookupAlertTypes.NO_SERVICE + }; + mountOptions.global.provide = { + vehicleFromLookup: {} + }; + + const { queryByRole } = render(VinLookupAlertsComponent, mountOptions); + const noServiceAlert = queryByRole('alert', { name: 'no-service-alert' }); + + expect(noServiceAlert).toBeVisible(); + }); }); diff --git a/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.vue b/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.vue index 014fcad0..f9be7ede 100644 --- a/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.vue +++ b/src/layouts/vin-lookup/vin-lookup-alerts/vin-lookup-alerts.vue @@ -10,6 +10,8 @@ v-else-if="isVehicleNotMatchedVisible" /> +