diff --git a/src/constants/bailoutMessage.js b/src/constants/bailoutMessage.js index 8894f05c..64ba4324 100644 --- a/src/constants/bailoutMessage.js +++ b/src/constants/bailoutMessage.js @@ -63,7 +63,7 @@ const bailoutMessage = Object.freeze({ }), HeavyTruckVehicle: (carId) => ({ code: bailoutCode.HeavyTruckVehicle, - message: `User selected a heavy truck vehicle. Car ID: ${carId}` + message: `User selected a big truck that Safelite cannot service. Car ID: ${carId}` }), NoPartsAvailable: () => ({ code: bailoutCode.NoPartsAvailable, diff --git a/src/constants/vehicle-lookup-alert-types.js b/src/constants/vehicle-lookup-alert-types.js index 98961165..d2d88ee5 100644 --- a/src/constants/vehicle-lookup-alert-types.js +++ b/src/constants/vehicle-lookup-alert-types.js @@ -1,9 +1,9 @@ const vehicleLookupAlertTypes = Object.freeze({ NOT_FOUND: 'notFound', NOT_MATCHED: 'notMatched', + NO_SERVICE: 'noService', TWO_IDENTICAL_YMM_MATCHED: 'twoIdenticalYMMMatched', - PERFECT_MATCH: 'perfectMatch', - NO_SERVICE: 'noService' + PERFECT_MATCH: 'perfectMatch' }); export default vehicleLookupAlertTypes; diff --git a/src/helpers/bailout-helper.js b/src/helpers/bailout-helper.js index b0d364c5..2ae8440f 100644 --- a/src/helpers/bailout-helper.js +++ b/src/helpers/bailout-helper.js @@ -12,6 +12,8 @@ function canBailoutNavigateBack() { case BailoutCode.VehicleNotFound: case BailoutCode.RequestCallback: case BailoutCode.TPANotEnabled: + case BailoutCode.CoverageCancelledByUser: + case BailoutCode.HeavyTruckVehicle: return true; default: diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index 648190c2..e7bc0b16 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -466,76 +466,5 @@ 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 cf6e6e4c..5a7b9b14 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -55,14 +55,6 @@ alertClass="alert-danger" :isCollapsible="true" :isDismissible="false" /> - { // 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: 2016, - 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' - }); - - 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/bailout-page/bailout-page.vue b/src/layouts/bailout-page/bailout-page.vue index b5000ce6..8617ce77 100644 --- a/src/layouts/bailout-page/bailout-page.vue +++ b/src/layouts/bailout-page/bailout-page.vue @@ -204,7 +204,9 @@ export default { methods: { backButtonAction() { // route to move backwards - this.mainStore.resetBailout(); + if (this.bailout.bailoutCode !== BailoutCode.HeavyTruckVehicle) { + this.mainStore.resetBailout(); + } this.$router.navigateWithSpinner( this.navigationScenarios.CLICKED_BACK_PREVIOUS, this.$route 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 d02a06a0..0ca7e719 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -151,68 +151,6 @@ describe('license-plate-lookup.vue', () => { // 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 ac6bb727..ce7cfb2d 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -59,13 +59,6 @@ :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 9cedd58d..019c0059 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -27,17 +27,10 @@ buttonText="Add another vehicle" class="w-100" @clickEvent="addAnotherVehicle" /> - @@ -67,10 +60,10 @@ import { } from '@/helpers/policy-vehicle-helper'; import coverageType from '@/constants/coverage-type'; import coverageStatuses from '@/constants/coverage-statuses'; -import alert from '@/ux-components/alert/alert.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import buttonMain from '@/ux-components/button-main/button-main.vue'; import { buttonVariants } from '@/constants/component-variants'; +import bailoutMessage from '@/constants/bailoutMessage'; export default { name: 'policy-vehicles', @@ -80,8 +73,7 @@ export default { siteHeader, siteFooter, policyVehiclesQuestion, - Form, - alert + Form }, mixins: [BaseFormMixin], async beforeRouteEnter(to, from, next) { @@ -103,7 +95,6 @@ export default { rules: { optionRequired: globalRules.OPTION_REQUIRED }, - displayNoServiceAlert: false, buttonVariants }; }, @@ -147,7 +138,6 @@ export default { }, watch: { async selectedVehicleVin(value) { - this.displayNoServiceAlert = false; if (value === vehicleSelectionOptions.VEHICLE_NOT_LISTED) { // clear previously selected vehicle and image this.mainStore.resetVehicleState(); @@ -157,10 +147,6 @@ export default { // get vehicle details from selected VIN try { const vehicle = await this.lookupVehicleByVin(value); - if (!vehicle?.data.canSafeliteService) { - this.displayNoServiceAlert = true; - return; - } if (vehicle) { // save selected vehicle to the store useMainStore().updateVehicle({ @@ -201,6 +187,11 @@ export default { try { const vehicleLookupResponse = await this.lookupVehicleByVin(this.selectedVehicleVin); + if (!vehicleLookupResponse?.data.canSafeliteService) { + this.mainStore.setBailout( + bailoutMessage.HeavyTruckVehicle(vehicleLookupResponse?.data?.carId) + ); + } useMainStore().updateVehicle({ ...vehicleLookupResponse.data, policyVehicleId: vehicle.id, @@ -242,6 +233,11 @@ export default { {}, {} ); + } else if (this.mainStore.isBailout) { + this.$router.navigate( + this.navigationScenarios.BAILOUT, + this.$route + ); } else if (this.endorsementsForSelectedVehicle?.length > 0 && (this.endorsementsForSelectedVehicle?.includes(endorsementOptions.PARKING_GUARD) || this.endorsementsForSelectedVehicle?.includes(endorsementOptions.EDUCATOR)) diff --git a/src/layouts/vehicle-selection/vehicle-selection.vue b/src/layouts/vehicle-selection/vehicle-selection.vue index e489fe0d..26276c37 100644 --- a/src/layouts/vehicle-selection/vehicle-selection.vue +++ b/src/layouts/vehicle-selection/vehicle-selection.vue @@ -46,18 +46,11 @@ :updateValues="updateStyleValues" validationRules="style-required" inputId="styleQuestionField" /> - @@ -72,7 +65,6 @@ import siteHeader from '@/iss-components/site-header/site-header.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.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 @@ -97,8 +89,7 @@ export default { siteSubHeader, siteFooter, Form, - vehicleQuestion, - alert + vehicleQuestion }, mixins: [baseFormMixin], @@ -131,15 +122,13 @@ export default { selectedYear: year, selectedMake: make, selectedModel: model, - selectedStyle: style, - displayNoServiceAlert: false + selectedStyle: style }; }, computed: { }, watch: { selectedYear(value) { - this.resetAlert(); this.mainStore.updateVehicleYear(value); this.$refs.vehicleMakeQuestion.clearValues(); if (value) { @@ -147,7 +136,6 @@ export default { } }, selectedMake(value) { - this.resetAlert(); this.mainStore.updateVehicleMake(value); this.$refs.vehicleModelQuestion.clearValues(); if (value) { @@ -155,7 +143,6 @@ export default { } }, selectedModel(value) { - this.resetAlert(); this.mainStore.updateVehicleModel(value); this.$refs.vehicleStyleQuestion.clearValues(); if (value) { @@ -164,16 +151,7 @@ export default { }, selectedStyle(value) { if (value) { - this.resetAlert(); this.mainStore.updateVehicleStyle(value); - this.mainStore.setVehicle( - this.selectedYear, - this.selectedMake, - this.selectedModel, - this.selectedStyle - ).then((result) => { - this.displayNoServiceAlert = !result.data.canSafeliteService; - }); } } }, @@ -188,16 +166,6 @@ 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() { @@ -208,12 +176,23 @@ export default { }, navigateForward() { - this.mainStore.setVehicle().then(() => { - this.$router.navigate( - this.navigationScenarios.CLICKED_FORWARD, + this.mainStore.setVehicle().then((result) => { + if (!result.data.canSafeliteService) { + this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(this.mainStore.order.vehicle.carId)); + } + + if (this.mainStore.isBailout) { + return this.$router.navigate( + this.navigationScenarios.BAILOUT, this.$route ); } + + return this.$router.navigate( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); + } ); }, async updateYearValues() { 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 33e4e7e5..a9c2c11a 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 @@ -67,17 +67,4 @@ 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.spec.js b/src/layouts/vin-lookup/vin-lookup.spec.js index b5808d77..5e82c2f8 100644 --- a/src/layouts/vin-lookup/vin-lookup.spec.js +++ b/src/layouts/vin-lookup/vin-lookup.spec.js @@ -488,36 +488,6 @@ describe('vin-lookup.vue', () => { ); }); }); - test('Display no service alert if entered vin cannot be serviced', async () => { - const user = userEvent.setup(); - mountOptions.global.stubs.vinQuestion = false; - - mountOptions.data = () => ({ - vinWithNonMatchingCarId: false, - isCarIdDifferentFromTheStore: false, - vin: mockValidVin - }); - - getPartsOrQuestions.mockResponse = vehicleWithNoAdditionalPartsOrQuestionsMockResponse; - - jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName) - .mockResolvedValue(lookupVehicleByVinCannotService.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) - .mockResolvedValue(getPartsOrQuestions.mockResponse); - - const { container } = render(VinLookupComponent, mountOptions); - - const vinInput = container.querySelector(vinInputSelector); - await user.type(vinInput, mockValidVin); - - const continueButton = container.querySelector(continueButtonQuerySelector); - await user.click(continueButton); - - await flushPromises(); - await waitFor(() => { - expect(container).toContainHTML('noService'); - }); - }); test('Policy Vehicle with invalid vin corrected. Click "Continue", execute navigate with navigationScenario.CORRECTED_VIN_FROM_POLICY_VEHICLE', async () => { const user = userEvent.setup(); diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 05582873..e7470aca 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -179,9 +179,8 @@ export default { const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin); if (!vehicleLookupResponse.data.canSafeliteService) { - this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NO_SERVICE; + this.mainStore.setBailout(bailoutMessage.HeavyTruckVehicle(vehicleLookupResponse.data.carId)); this.resetVehicleFromLookup(); - this.$refs.siteFooter.disableForwardButton(); showIssLoadingModal(false); return; } diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 88d65525..92d8dd10 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -304,6 +304,7 @@ export default { }, methods: { async forwardButtonAction() { + this.mainStore.resetVehicleState(); this.mainStore.updatePolicyData(this.welcomePageModel); // We want to await this separately. It's quick and if this has an invalid zip we don't want to be waiting on the slower API calls diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 6efed9ee..b4bdad07 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -361,6 +361,14 @@ export default { const self = vm ?? this; const currentPage = self.$route.query.issPage; + if (self.mainStore.isBailout) { + self.$router.navigate( + self.navigationScenarios.BAILOUT, + self.$route + ); + return; + } + const hasPartQuestions = this.hasPartQuestions(partsOrQuestions); const hasGlassLocationWithMultipleParts = this.hasGlassLocationWithMultipleParts(partsOrQuestions); const hasChildPartQuestions = this.hasChildPartQuestions(partsOrQuestions); diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 8a45d37b..aa686acd 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -14,6 +14,10 @@ const routingTable = () => [ { scenario: navigationScenarios.CLICKED_FORWARD, destinationIssPageValue: issPageValues.POLICY_HOLDER_DETAILS + }, + { + scenario: navigationScenarios.BAILOUT, + destinationIssPageValue: issPageValues.BAILOUT_PAGE } ] },