diff --git a/src/constants/bailoutMessage.js b/src/constants/bailoutMessage.js index 4c7a73ee..6f313650 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/helpers/vehicle-helper.js b/src/helpers/vehicle-helper.js new file mode 100644 index 00000000..7902b3fa --- /dev/null +++ b/src/helpers/vehicle-helper.js @@ -0,0 +1,21 @@ +import { useMainStore } from '@/store'; +import { experimentSettings } from '@/constants/experiments'; +import experimentMixin from '@/mixins/experiment-mixin'; + +export function hasYMMExperimentBailoutSettingEnabled() { + return ymmIsVinRequired() && experimentMixin.methods.hasSettingEqualTo(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED, 'true'); +} + +export function hasYMMExperimentPageSettingEnabled() { + return ymmIsVinRequired() && experimentMixin.methods.hasSettingEqualTo(experimentSettings.ISS_YMMS_VIN_REQUIRED_PAGE_ENABLED, 'true'); +} + +export function hasYMMExperimentSettingEnabled() { + return ymmIsVinRequired() + && (experimentMixin.methods.hasSettingEqualTo(experimentSettings.ISS_YMMS_VIN_REQUIRED_PAGE_ENABLED, 'true') + || experimentMixin.methods.hasSettingEqualTo(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED, 'true')); +} + +function ymmIsVinRequired() { + return useMainStore().order?.vehicle?.vinRequired === true; +} \ No newline at end of file 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..b8bd1bc3 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -81,9 +81,9 @@ 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 { hasYMMExperimentBailoutSettingEnabled } from '@/helpers/vehicle-helper'; import routerParams from '@/router/router-constants/router-params'; import { getDamageString, @@ -345,13 +345,9 @@ 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 (hasYMMExperimentBailoutSettingEnabled()) { + this.navigateBailout(bailoutMessage.YMMNotFound()); + 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..a465cb07 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -72,8 +72,8 @@ 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 { hasYMMExperimentBailoutSettingEnabled } from '@/helpers/vehicle-helper'; import { Form, defineRule } from 'vee-validate'; import { isGlassAvailableForCarId } from '@/helpers/damage-helper'; import { @@ -233,6 +233,7 @@ export default { }, async forwardButtonAction() { this.mainStore.resetBailout(); + const vinLookup = await useMainStore().lookupVehicleByVin(this.selectedVehicle.vin); if (!vinLookup) { return; @@ -257,13 +258,9 @@ 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 - ); + if (hasYMMExperimentBailoutSettingEnabled()) { + this.navigateBailout(bailoutMessage.YMMNotFound()); + return; } await this.navigateForward(); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 165e0084..a428afa4 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -78,7 +78,7 @@ import settleAllPromises from '@/helpers/layout-helper'; import { useMainStore } from '@/store'; import bailoutMessage from '@/constants/bailoutMessage'; import errorMessages from '@/constants/error-messages'; -import { experimentSettings } from '@/constants/experiments'; +import { hasYMMExperimentBailoutSettingEnabled } from '@/helpers/vehicle-helper'; import { required } from '@/helpers/validation-rules'; import { defineRule, Form } from 'vee-validate'; import { @@ -305,13 +305,9 @@ 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 - ); + if (hasYMMExperimentBailoutSettingEnabled()) { + this.navigateBailout(bailoutMessage.YMMNotFound()); + return; } return this.navigateForward(); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 42ae3603..240bc587 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -428,9 +428,19 @@ export default { this.$route ); } else if (this.mainStore.order.vehicle.vin || !this.isWindshieldReplace) { - // If vin already exists or not replacing windshield, get parts/questions and navigate forward - - const partsOrQuestionsResponse = await this.getPartsOrQuestions(); + let partsOrQuestionsResponse; + const isVinRequired = this.mainStore.order.vehicle.vinRequired; + if (isVinRequired) { + this.mainStore.resetBailout(); + partsOrQuestionsResponse = await this.getPartsOrQuestionsV2(); + if (partsOrQuestionsResponse.data.partsOrQuestions.length === 0) { + this.navigateBailout(bailoutMessage.YMMNotFound('No Parts Returned')); + return; + } + } else { + // If vin already exists or not replacing windshield, get parts/questions and navigate forward + partsOrQuestionsResponse = await this.getPartsOrQuestions(); + } // Comes from vehicleQuestionsMixin.navigateForward() await this.navigateForward( diff --git a/src/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods.vue b/src/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods.vue index ea6d97df..244865ba 100644 --- a/src/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods.vue +++ b/src/layouts/vehicle-lookup/vin-lookup-methods/vin-lookup-methods.vue @@ -15,8 +15,8 @@ // Import Other Supporting Files import { useMainStore } from '@/store'; -import { experimentSettings } from '@/constants/experiments'; import vinLookupMethodSelections from '@/constants/vin-lookup-methods'; +import { hasYMMExperimentSettingEnabled } from '@/helpers/vehicle-helper'; import settleAllPromises from '@/helpers/layout-helper'; import globalRules from '@/constants/global-rules'; @@ -67,9 +67,9 @@ export default { answers.splice(homeAddressIndex, 1); } - const ymmsBailoutEnabled = this.getSettingValue(experimentSettings.ISS_YMMS_VIN_REQUIRED_BAILOUT_ENABLED) === 'true'; + const ymmsExperimentEnabled = hasYMMExperimentSettingEnabled(); const isVinRequired = useMainStore().order.vehicle.vinRequired; - if (isVinRequired && ymmsBailoutEnabled) { + if (isVinRequired && ymmsExperimentEnabled) { const vinIndex = answers.findIndex(answer => answer.Name === vinLookupMethodSelections.NOVIN); if (vinIndex >= 0) { answers.splice(vinIndex, 1); 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..9a937146 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -42,7 +42,6 @@