From 457c112243ce3a3139de2fae733718d8b59cfc88 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 20 Jul 2026 10:31:14 -0500 Subject: [PATCH 1/8] INSR-10109 Initial Setup for Vin Required Parts Lookup --- src/constants/bailoutMessage.js | 4 +- src/constants/endpoints.js | 2 +- src/helpers/unit-test-helper.js | 1 + .../address-lookup/address-lookup.spec.js | 5 +- src/layouts/address-lookup/address-lookup.vue | 10 +-- .../address-vehicles/address-vehicles.spec.js | 8 +- .../address-vehicles/address-vehicles.vue | 17 ++-- .../license-plate-lookup.vue | 6 +- src/layouts/vin-lookup/vin-lookup.spec.js | 24 +++--- src/layouts/vin-lookup/vin-lookup.vue | 38 +-------- src/mixins/base-mixin.js | 3 + src/mixins/vehicle-questions-mixin.js | 4 +- src/mixins/vin-pages-mixin.js | 22 ++++++ src/mixins/vin-pages-mixin.spec.js | 77 ++++++++++++++++++- src/store/index.js | 22 ++++-- 15 files changed, 159 insertions(+), 84 deletions(-) diff --git a/src/constants/bailoutMessage.js b/src/constants/bailoutMessage.js index 4c7a73ee..69330535 100644 --- a/src/constants/bailoutMessage.js +++ b/src/constants/bailoutMessage.js @@ -102,9 +102,9 @@ const bailoutMessage = Object.freeze({ code: bailoutCode.NeedHelp, message: 'User clicked the Need Help link in the app.' }), - YMMNotFound: () => ({ + YMMNotFound: (message = null) => ({ code: bailoutCode.YMMNotFound, - message: 'Vin Required vehicle' + message: `Vin Required vehicle` + message ? ` ${message}` : '' }) }); diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index c3c14480..5d71083a 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -70,7 +70,7 @@ const endpoints = Object.freeze({ url: `${PARTS_V1_BASE_URL}/parts-or-questions`, method: 'POST' }, - GetPartsOrQuestionsVinRequired: { + GetPartsOrQuestionsV2: { url: `${PARTS_V2_BASE_URL}/parts-or-questions`, method: 'POST' }, diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 5d6b21bc..1faea43f 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -43,6 +43,7 @@ export function getMountOptions(mockData) { mocks.pushEventToGA = jest.fn(); mocks.$loadScript = mockData?.loadScript; mocks.prependActionToMethod = jest.fn(); + mocks.navigateBailout = jest.fn(); const global = { mocks, diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index aead77c4..88b8021c 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -442,7 +442,7 @@ describe('address-lookup.vue', () => { useMainStore().order.vehicle.carId = 'C0000'; // Act - wrapper.vm.navigateForward(carsFound); + await wrapper.vm.navigateForward(carsFound); // Assert expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1); @@ -482,9 +482,10 @@ describe('address-lookup.vue', () => { }); useMainStore().order.vehicle.carId = 'CARID3'; + useMainStore().order.vehicle.vinRequired = false; // Act - wrapper.vm.navigateForward(carsFound); + await wrapper.vm.navigateForward(carsFound); // Assert expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1); diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 35acc137..b2747a0d 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -81,7 +81,6 @@ import alert from '@/ux-components/alert/alert.vue'; import { Form } from 'vee-validate'; // Supporting files -import { experimentSettings } from '@/constants/experiments'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; import settleAllPromises from '@/helpers/layout-helper'; import routerParams from '@/router/router-constants/router-params'; @@ -345,13 +344,8 @@ export default { { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true } ); } else if (matchingCars.length === 1) { - const ymmsBailoutEnabled = this.getSettingValue(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED) === 'true'; - if (ymmsBailoutEnabled && this.mainStore.order.vehicle.vinRequired) { - this.mainStore.setBailout(bailoutMessage.YMMNotFound()); - return this.$router.navigate( - this.navigationScenarios.BAILOUT, - this.$route - ); + if (await this.handleVinRequiredVehicle(this.vin)) { + return; } await this.navigateForwardWithSingleCarMatch(); } else { diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js index bb2c83f2..fd78ac3c 100644 --- a/src/layouts/address-vehicles/address-vehicles.spec.js +++ b/src/layouts/address-vehicles/address-vehicles.spec.js @@ -6,6 +6,7 @@ import { shallowMount } from '@vue/test-utils'; import { getMountOptions } from '@/helpers/unit-test-helper.js'; import { useMainStore } from '@/store'; import { fetchCmsContentForPage } from '@/helpers/cms-content-helper'; +import vinPagesMixin from '@/mixins/vin-pages-mixin'; jest.mock('@/helpers/damage-helper', () => ({ isGlassAvailableForCarId: jest.fn().mockImplementation(() => true), @@ -24,6 +25,11 @@ jest.mock('@/helpers/cms-content-helper', () => ({ // Mock our module for promises. jest.mock('@/helpers/layout-helper.js', () => jest.fn()); +jest.mock('@/mixins/vin-pages-mixin', () => ({ + methods: { + handleVinRequiredVehicle: jest.fn().mockReturnValue(false) + } +})); function setupMocks({ route = null, @@ -121,7 +127,7 @@ function setupMocks({ } }; - mountOptions.mixins = [mockMixin]; + mountOptions.mixins = [mockMixin, vinPagesMixin]; const wrapper = shallowMount(addressVehicles, mountOptions); diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index b3ea74e8..40d3fb64 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -72,7 +72,6 @@ import settleAllPromises from '@/helpers/layout-helper'; import { useMainStore } from '@/store'; import issPageValues from '@/router/router-constants/issPage-values'; import errorMessages from '@/constants/error-messages'; -import { experimentSettings } from '@/constants/experiments'; import { required } from '@/helpers/validation-rules'; import { Form, defineRule } from 'vee-validate'; import { isGlassAvailableForCarId } from '@/helpers/damage-helper'; @@ -233,6 +232,10 @@ export default { }, async forwardButtonAction() { this.mainStore.resetBailout(); + if (await this.handleVinRequiredVehicle(this.vin)) { + return; + } + const vinLookup = await useMainStore().lookupVehicleByVin(this.selectedVehicle.vin); if (!vinLookup) { return; @@ -257,15 +260,6 @@ export default { false ); - const ymmsBailoutEnabled = this.getSettingValue(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED) === 'true'; - if (ymmsBailoutEnabled && this.mainStore.order.vehicle.vinRequired) { - this.mainStore.setBailout(bailoutMessage.YMMNotFound()); - return this.$router.navigate( - this.navigationScenarios.BAILOUT, - this.$route - ); - } - await this.navigateForward(); }, async navigateForward() { @@ -282,6 +276,9 @@ export default { { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true } ); } else { + if (await this.handleVinRequiredVehicle(this.vin)) { + return; + } await this.navigateForwardWithSingleCarMatch(); } }, diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 165e0084..634ad9fc 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -307,11 +307,7 @@ export default { const ymmsBailoutEnabled = this.getSettingValue(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED) === 'true'; if (ymmsBailoutEnabled && this.mainStore.order.vehicle.vinRequired) { - this.mainStore.setBailout(bailoutMessage.YMMNotFound()); - return this.$router.navigate( - this.navigationScenarios.BAILOUT, - this.$route - ); + return this.$router.navigateBailout(bailoutMessage.YMMNotFound()); } return this.navigateForward(); diff --git a/src/layouts/vin-lookup/vin-lookup.spec.js b/src/layouts/vin-lookup/vin-lookup.spec.js index b5e9efe6..5a6289f9 100644 --- a/src/layouts/vin-lookup/vin-lookup.spec.js +++ b/src/layouts/vin-lookup/vin-lookup.spec.js @@ -51,8 +51,8 @@ const getPartsOrQuestions = { methodName: 'getPartsOrQuestions', mockResponse: null }; -const getPartsOrQuestionsVinRequired = { - methodName: 'getPartsOrQuestionsVinRequired', +const getPartsOrQuestionsV2 = { + methodName: 'getPartsOrQuestionsV2', mockResponse: null }; @@ -384,8 +384,8 @@ describe('vin-lookup.vue', () => { .mockResolvedValue(lookupVehicleByVin.mockResponse); jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) .mockResolvedValue(getPartsOrQuestions.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsVinRequired.methodName) - .mockResolvedValue(getPartsOrQuestionsVinRequired.mockResponse); + jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsV2.methodName) + .mockResolvedValue(getPartsOrQuestionsV2.mockResponse); const { container } = render(VinLookupComponent, mountOptions); @@ -417,8 +417,8 @@ describe('vin-lookup.vue', () => { .mockResolvedValue(lookupVehicleByVin.mockResponse); jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) .mockResolvedValue(getPartsOrQuestions.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsVinRequired.methodName) - .mockResolvedValue(getPartsOrQuestionsVinRequired.mockResponse); + jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsV2.methodName) + .mockResolvedValue(getPartsOrQuestionsV2.mockResponse); const { container } = render(VinLookupComponent, mountOptions); @@ -452,8 +452,8 @@ describe('vin-lookup.vue', () => { .mockResolvedValue(lookupVehicleByVin.mockResponse); jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) .mockResolvedValue(getPartsOrQuestions.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsVinRequired.methodName) - .mockResolvedValue(getPartsOrQuestionsVinRequired.mockResponse); + jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsV2.methodName) + .mockResolvedValue(getPartsOrQuestionsV2.mockResponse); store.getCapabilityQuestions.mockResolvedValueOnce({ data: [] }); const { container } = render(VinLookupComponent, mountOptions); @@ -487,8 +487,8 @@ describe('vin-lookup.vue', () => { .mockResolvedValue(lookupVehicleByVin.mockResponse); jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) .mockResolvedValue(getPartsOrQuestions.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsVinRequired.methodName) - .mockResolvedValue(getPartsOrQuestionsVinRequired.mockResponse); + jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsV2.methodName) + .mockResolvedValue(getPartsOrQuestionsV2.mockResponse); const { container } = render(VinLookupComponent, mountOptions); @@ -525,8 +525,8 @@ describe('vin-lookup.vue', () => { .mockResolvedValue(lookupVehicleByVin.mockResponse); jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName) .mockResolvedValue(getPartsOrQuestions.mockResponse); - jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsVinRequired.methodName) - .mockResolvedValue(getPartsOrQuestionsVinRequired.mockResponse); + jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestionsV2.methodName) + .mockResolvedValue(getPartsOrQuestionsV2.mockResponse); const { container } = render(VinLookupComponent, mountOptions); diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index ffb0364d..fecbfcd2 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -42,7 +42,6 @@