diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index ca1555e7b..13ad55b34 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -75,8 +75,8 @@ const endpoints = { url: "/analytics/api/v1/analytics/activity", method: "POST", }, - GetExperimentsByUserForGa: { - url: "/analytics/api/v1/analytics/get-experiments-for-GA", + GetExperimentsByUser: { + url: "/analytics/api/v1/analytics/get-experiments", method: "GET", } }; diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 17012ab68..963ba0b5d 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -21,6 +21,7 @@ const errorMessages = { SERVICE_ZIP_FORMAT: "Please enter a valid Service ZIP", VIN_REQUIRED: "Please enter your VIN", VIN_FORMAT: "Please enter a valid VIN", + OPTION_REQUIRED: "Please select an option", }; export { errorMessages }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 74dac5043..fe100d5e3 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -20,7 +20,7 @@ const storeActions = { VALIDATE_ZIP: "validateZip", LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", LOG_ACTIVITY: "logActivity", - GET_EXPERIMENTS_BY_USER_FOR_GA: "getExperimentsByUserForGa", + GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser", // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleAndDependencies", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 3f42f9a5f..65f4719ec 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -22,7 +22,7 @@ const storeMutations = { UPDATE_REGISTRATION_ZIP_CODE: "updateRegistrationZipCode", UPDATE_REGISTRATION_FIRST_NAME: "updateRegistrationFirstName", UPDATE_REGISTRATION_LAST_NAME: "updateRegistrationLastName", - UPDATE_SERVICE_LOCATION_ZIP: "updateServiceLocationZip", + UPDATE_SERVICE_LOCATION_ZIP_CODE: "updateServiceLocationZipCode", UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress", // ORDER MUTATIONS diff --git a/src/constants/vin-lookup-method-selections.js b/src/constants/vin-lookup-method-selections.js new file mode 100644 index 000000000..46f1e2044 --- /dev/null +++ b/src/constants/vin-lookup-method-selections.js @@ -0,0 +1,7 @@ +const vinLookupMethodSelections = { + MANUALVIN: "ManualVin", + LICENSEPLATE: "LicensePlate", + HOMEADDRESS: "HomeAddress", +}; + +export { vinLookupMethodSelections }; \ No newline at end of file diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 49c4ab354..61c07203d 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -93,9 +93,9 @@ async function getLatestPageForRedirection() { return fmgPageValues.VEHICLE_DAMAGE; } else { if (store.getters.vehicle.vin) { - return fmgPageValues.LICENSE_PLATE_LOOKUP; - } else { return fmgPageValues.VIN_LOOKUP; + } else { + return fmgPageValues.ESTIMATE; } } } diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index de5df0239..fd06920c2 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -175,7 +175,7 @@ describe("getPageToRouteExistingOrderTo", () => { expect(result).toBe('vehicle-damage'); }); - test("getPageToRouteExistingOrderTo, should return license-plate-lookup", async () => { + test("getPageToRouteExistingOrderTo, should return vin-lookup", async () => { // Arrange const toRoute = { query: {} @@ -228,7 +228,7 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('license-plate-lookup'); + expect(result).toBe('vin-lookup'); }); test("getPageToRouteExistingOrderTo, should return estimate", async () => { @@ -283,7 +283,7 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('vin-lookup'); + expect(result).toBe('estimate'); }); test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => { diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 770dd893e..6577ed6ff 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -23,6 +23,7 @@ export function getMountOptions(mockData) { mocks.pushPageViewToGA = jest.fn(); mocks.logEvent = jest.fn(); mocks.pushExperimentsToDataLayer = jest.fn(); + mocks.prependActionToMethod = jest.fn(); mocks.dispatchStoreAction = jest.fn(); mocks.dispatchStoreAction.mockImplementation((actionName) => { diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 895148575..032b42268 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -81,7 +81,7 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "@/constants/store-mutations"; import baseMixin from "@/mixins/base-mixin"; -import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper"; defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); @@ -167,7 +167,7 @@ export default { return store.getters.order.customer.emailAddress; }, getServiceZipFromStore() { - return store.getters.order.serviceLocation.zip; + return store.getters.order.serviceLocation.zipCode; }, async forwardButtonAction() { this.resetWarningsAndErrors(); @@ -302,7 +302,7 @@ export default { store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, this.customerQuestions.addressQuestions.zipCode); store.commit(storeMutations.UPDATE_REGISTRATION_FIRST_NAME, this.customerQuestions.firstName); store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, this.customerQuestions.lastName); - store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.serviceZip); + store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, this.serviceZip); store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.customerQuestions.email); }, diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 0e41b24ed..b46c38801 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -1,13 +1,131 @@ + + \ No newline at end of file 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 533a8e38d..6e6de9349 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -33,7 +33,7 @@ jest.mock("@/store", () => ({ emailAddress: "test@test.com" }, serviceLocation: { - zip: "43443" + zipCode: "43443" } }, vehicle: { diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 59be19cbd..34507bda2 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -5,23 +5,60 @@ ref="theForm" v-slot="{ meta }" > -
+
- +
- +
- + +
- + +
- +
{ + this.pushEventToGA( + this.$route.query[this.queryStrings.FMG_PAGE], + this.GaActions.SUBMITTED, + this.GaLabels.LICENSE_PLATE_LOOKUP, + true + ); + }); }, - getRegistrationZipFromStore(){ - return store.getters.vehicle.registration.zipCode + getLicensePlateFromStore() { + return store.getters.vehicle.registration.licensePlate; }, - getEmailFromStore(){ - return store.getters.order.customer.emailAddress + getRegistrationZipFromStore() { + return store.getters.vehicle.registration.zipCode; + }, + getEmailFromStore() { + return store.getters.order.customer.emailAddress; }, getServiceZipFromStore(){ - return store.getters.order.serviceLocation.zip + return store.getters.order.serviceLocation.zipCode }, backButtonAction() { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - - this.pushEventToGA(this.$route.query[this.queryStrings.FMG_PAGE], this.GaActions.SUBMITTED, this.GaLabels.LICENSE_PLATE_LOOKUP , true); - - const zipValidation = this.serviceZip ? await this.validateZip(this.serviceZip) : await this.validateZip(this.registrationZip); + const zipValidation = this.serviceZip + ? await this.validateZip(this.serviceZip) + : await this.validateZip(this.registrationZip); if (!zipValidation.data.isServiceable) { this.$refs.funnelFooter.removeLoader(); this.isVinValid = true; @@ -186,53 +277,75 @@ export default { return; } - const vinLookup = await this.lookupVin(this.licensePlate, zipValidation.data.state).catch(() => { + const vinLookup = await this.lookupVin( + this.licensePlate, + zipValidation.data.state + ).catch(() => { this.$refs.funnelFooter.removeLoader(); this.isVinValid = false; this.isCarIdDifferent = false; return; }); - this.isCarIdDifferent = vinLookup.data.vehicle.carId !== store.getters.vehicle.carId; + this.isCarIdDifferent = + vinLookup.data.vehicle.carId !== store.getters.vehicle.carId; - if (this.isCarIdDifferent && (vinLookup.data.vehicle.carId !== this.previouslyEnteredCarId)) { + if ( + this.isCarIdDifferent && + vinLookup.data.vehicle.carId !== this.previouslyEnteredCarId + ) { this.previouslyEnteredCarId = vinLookup.data.vehicle.carId; this.customAlertData.vehicleInfo = vinLookup.data.vehicle; - this.$refs.funnelFooter.updateButtonText(`Continue with ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}`); + this.$refs.funnelFooter.updateButtonText( + `Continue with ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}` + ); this.isVinValid = true; - this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.vehicle.carId); + this.isSelectedGlassAvailableForVehicle = + await isGlassAvailableForCarId(vinLookup.data.vehicle.carId); this.$refs.funnelFooter.removeLoader(); return; } - this.updateCustomerInfo(vinLookup.data.vin, vinLookup.data.vehicle, zipValidation.data.state); + this.updateCustomerInfo( + vinLookup.data.vin, + vinLookup.data.vehicle, + zipValidation.data.state + ); const partsData = await baseMixin.methods.dispatchStoreAction( this.storeActions.GET_PARTS_OR_QUESTIONS, { carId: vinLookup.data.vehicle.carId, - glassArray: this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle ? [] : store.getters.damage.glassToReplace, + glassArray: + this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle + ? [] + : store.getters.damage.glassToReplace, zipCode: this.serviceZip ? this.serviceZip : this.registrationZip, - vin: vinLookup.data.vin + vin: vinLookup.data.vin, }, false ); this.navigateForward(partsData); }, - navigateForward(partsData){ - if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ - this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, partsData.data); - return; - } else { - navigateAfterSaveToHeritageFunnel(this.$route); - return; - } + navigateForward(partsData) { + if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) { + this.$router.navigateAfterSave( + this.navigationScenarios.CLICKED_FORWARD, + this.$route, + {}, + { displayVehicleChangeAlert: true }, + partsData.data + ); + return; + } else { + navigateAfterSaveToHeritageFunnel(this.$route); + return; + } }, validateZip(zip) { - return baseMixin.methods.dispatchStoreAction( - storeActions.VALIDATE_ZIP, - { zip } - ); + return baseMixin.methods.dispatchStoreAction(storeActions.VALIDATE_ZIP, { + zip, + }); }, lookupVin(plate, state) { return baseMixin.methods.dispatchStoreAction( @@ -241,8 +354,8 @@ export default { ); }, updateCustomerInfo(vin, vehicleInfo, registrationState) { - if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ - store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) { + store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); } store.commit(storeMutations.UPDATE_VEHICLE_VIN, vin); store.commit(storeMutations.UPDATE_YEAR, vehicleInfo.year); @@ -250,28 +363,34 @@ export default { store.commit(storeMutations.UPDATE_MODEL, vehicleInfo.model); store.commit(storeMutations.UPDATE_STYLE, vehicleInfo.style); store.commit(storeMutations.UPDATE_CAR_ID, vehicleInfo.carId); - store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, vehicleInfo.category); - store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, vehicleInfo.imageUrl); - store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, vehicleInfo.imageVifNumber); - store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, vehicleInfo.imageColor); - store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE, this.licensePlate); + store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY,vehicleInfo.category); + store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL,vehicleInfo.imageUrl); + store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER,vehicleInfo.imageVifNumber); + store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR,vehicleInfo.imageColor); + store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE,this.licensePlate); store.commit(storeMutations.UPDATE_REGISTRATION_STATE, registrationState); store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, this.registrationZip); - store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.serviceZip); + store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, this.serviceZip); store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email); }, }, watch: { - licensePlate() { - this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); - }, - registrationZip(){ - this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); - }, - serviceZip(){ - this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")); - } + licensePlate() { + this.$refs.funnelFooter.updateButtonText( + this.getCmsContent("FunnelFooterWidget", "ForwardButtonText") + ); }, + registrationZip() { + this.$refs.funnelFooter.updateButtonText( + this.getCmsContent("FunnelFooterWidget", "ForwardButtonText") + ); + }, + serviceZip() { + this.$refs.funnelFooter.updateButtonText( + this.getCmsContent("FunnelFooterWidget", "ForwardButtonText") + ); + }, + }, components: { Form, funnelHeader, @@ -282,4 +401,4 @@ export default { funnelFooter, }, }; - \ No newline at end of file + diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index 9a9f7e6d7..b722fccbf 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -182,66 +182,6 @@ describe("vehicle-damage.vue", () => { }); }); -describe("vehicle-damage.vue", () => { - test("Windshield replace with single part on ForwardButtonAction triggers a router.navigate and saves selections to store", async () => { - //Arrange - const partsData = { partsOrQuestions: [ - { - glassLocation: "Windshield", - glassName: "Single", - partQuestions: null, - parts: [ - { - color: "Green Tint, Green Shade", - description: "rain sensor, solar", - partNumber: "FW02728GGYN", - requiresCapabilityQuestions: false, - requiresRecalibration: false - } - ]}]}; - - const { wrapper } = setupMocks({ - pageHeaderWidgetHeaderText: "", - mountOptionsMockData: { - router: { navigate: jest.fn(), }, - actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },], - store: { - getters: { - vehicle: {}, - payment: { insuranceCoverage: { isVerified: false } }, - }, - }, - }, - }); - - wrapper.vm.selectedDamageLocations = ["Windshield"]; - wrapper.vm.selectedWindshieldOptions = { - selectedWindshieldChipCount : null, - selectedWindshieldReplaceOptions : ["Single"], - selectedWindshieldDamageType: ["Replace"] - }; - - const expectedGlassToReplace = [{location: "Windshield", name: "Single"},]; - - //Act - vehicleDamage.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "vehicle-damage" } }, - undefined, - (c) => c(wrapper.vm) - ); - - await wrapper.vm.forwardButtonAction(); - - //Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); - expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace); - expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false); - expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace); - expect(store.commit).toBeCalledWith(storeMutations.UPDATE_PARTS, partsData.partsOrQuestions[0].parts); - }); -}); - describe("vehicle-damage.vue", () => { test("Windshield replace with multiple parts on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => { //Arrange @@ -332,48 +272,6 @@ describe("vehicle-damage.vue", () => { }); }); - -describe("vehicle-damage.vue", () => { - test("Windshield repair on ForwardButtonAction triggers a router.navigate and saves selection to store", async () => { - //Arrange - const partsData = { partsOrQuestions: []}; - const { wrapper } = setupMocks({ - pageHeaderWidgetHeaderText: "", - mountOptionsMockData: { - router: { navigate: jest.fn(), }, - actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },], - store: { - getters: { - vehicle: {}, - payment: { insuranceCoverage: { isVerified: false } }, - }, - }, - }, - }); - - wrapper.vm.selectedDamageLocations = ["Windshield"]; - wrapper.vm.selectedWindshieldOptions = { - selectedWindshieldChipCount : [2], - selectedWindshieldDamageType: ["Repair"] - }; - - //Act - vehicleDamage.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "vehicle-damage" } }, - undefined, - (c) => c(wrapper.vm) - ); - - await wrapper.vm.forwardButtonAction(); - - //Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); - expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, true); - expect(store.commit).toBeCalledWith(storeMutations.UPDATE_NUMBER_OF_CHIPS, 2); - }); -}); - describe("vehicle-damage.vue", () => { test("isWindshieldDamageLocation is true when windshield is selected", async () => { diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 862abaced..b3f89f833 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -134,6 +134,8 @@ export default { vm.$refs.backGlassOptions.initializeComponent( resultMap.damageOptions.backGlassOptions.availableReplacementOptions ); + + }); }, data(){ @@ -149,10 +151,7 @@ export default { } }, mounted(){ - if(this.$store.getters.vehicle.imageVifNumber){ - this.pushEventToGA(this.GaCategories.EVOX, `${this.GaActions.VIF}_${this.$store.getters.vehicle.imageVifNumber}`, - this.$store.getters.vehicle.carId, true); - } + this.attachCustomEvents(); }, methods: { arePagePrerequisitesValid() { @@ -166,6 +165,13 @@ export default { store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }, + attachCustomEvents(){ + if(this.$store.getters.vehicle.imageVifNumber){ + this.pushEventToGA(this.GaCategories.EVOX, `${this.GaActions.VIF}_${this.$store.getters.vehicle.imageVifNumber}`, + this.$store.getters.vehicle.carId, true); + } + }, + backButtonAction() { // route to move backwards this.$router.navigate( @@ -287,55 +293,20 @@ export default { store.commit(this.storeMutations.UPDATE_GLASS_TO_REPLACE, this.selectedGlassToReplace()); - const partsData = await baseMixin.methods.dispatchStoreAction(this.storeActions.GET_PARTS_OR_QUESTIONS, - { carId: store.getters.vehicle.carId, glassArray: this.selectedGlassToReplace()}, false); - - this.navigateForward(partsData); + this.navigateForward(); }, - navigateForward(partsData){ - - // Temporary easter egg to navigate to heritage funnel. - const vehicleYearsToShowHeritageFunnel = [ 2001, 2002, 2010, 2016 ]; - if (vehicleYearsToShowHeritageFunnel.includes(store.getters.vehicle.year)) { - navigateToHeritageFunnel(); - return; - } - - // Temporary easter egg to navigate to address-lookup. - if (store.getters.vehicle.year === 2014) { - this.$router.navigateAfterSave(this.navigationScenarios.TEMPORARY_TO_ADDRESS_LOOKUP, this.$route, {}, {}, partsData.data); - return; - } + navigateForward(){ // If vin already exists, navigate directly to vin-lookup - if(this.$store.getters.vehicle.vin){ - this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_VIN, this.$route); + if(store.getters.vehicle.vin) { + this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD_WITH_VIN, this.$route); + return; + } + else { + this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, this.$route); return; } - - //found problem questions - if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){ - this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data); - return; - } - - //found multiple parts for a single glass location (Windshield, Driver, Passenger, Rear) - if (partsData.data.partsOrQuestions){ - for (var i = 0; i < partsData.data.partsOrQuestions.length; i++){ - if (partsData.data.partsOrQuestions[i].parts != null && partsData.data.partsOrQuestions[i].parts.length > 1){ - this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, this.$route, {}, {}, partsData.data); - return; - } - } - } - - //if not a repair then there should only be 1 part and no problem questions at this point so save the part to the store. - if (!this.isWindshieldRepair){ - store.commit(this.storeMutations.UPDATE_PARTS, partsData.data.partsOrQuestions[0].parts); - } - - this.$router.navigate(this.navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, this.$route); }, selectedGlassToReplace() { diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue index 2a97b05a9..8cc521a4a 100644 --- a/src/layouts/vehicle-year/vehicle-year.vue +++ b/src/layouts/vehicle-year/vehicle-year.vue @@ -29,7 +29,7 @@ import { settleAllPromises } from "@/helpers/layout-helper"; import { storeMutations } from "@/constants/store-mutations"; import { storeActions } from "@/constants/store-actions"; import { experimentUniverses } from "@/constants/experiments"; -import { getDeviceIdValue, getSessionIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; +import { getDeviceIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; import baseMixin from "@/mixins/base-mixin"; import store from "@/store"; @@ -99,7 +99,6 @@ export default { return true; }, resetDependentState() { - // Set store.commit(storeMutations.UPDATE_MAKE, null); store.commit(storeMutations.UPDATE_MODEL, null); @@ -111,7 +110,7 @@ export default { // Invokes store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); store.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); - } + }, }, components: { yearQuestion, diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 36dfaf137..4842a8eb6 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -5,13 +5,26 @@ ref="theForm" v-slot="{ meta }" > -
+
- +
- +
@@ -21,12 +34,27 @@
- +
- +
@@ -109,10 +137,22 @@ import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integratio // DEFINE VALIDATION RULES defineRule("zip-required", required(errorMessages.ZIP_REQUIRED)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); -defineRule("email-address-format", regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+).([a-zA-Z]{2,})$/, errorMessages.EMAIL_ADDRESS_FORMAT)); +defineRule( + "email-address-required", + required(errorMessages.EMAIL_ADDRESS_REQUIRED) +); +defineRule( + "email-address-format", + regex( + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+).([a-zA-Z]{2,})$/, + errorMessages.EMAIL_ADDRESS_FORMAT + ) +); defineRule("vin-required", required(errorMessages.VIN_REQUIRED)); -defineRule("vin-format", regex(/^[A-HJ-NPR-Z0-9]{17}$/, errorMessages.VIN_FORMAT)); +defineRule( + "vin-format", + regex(/^[A-HJ-NPR-Z0-9]{17}$/, errorMessages.VIN_FORMAT) +); export default { name: "vin-lookup", @@ -120,7 +160,6 @@ export default { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); - // Settle promises and get results const promiseResultMap = [ { @@ -211,12 +250,20 @@ export default { getZipFromStore(){ return store.getters.vehicle.registration.zipCode }, + attachCustomEvents() { + this.prependActionToMethod(this, this.forwardButtonAction, () => { + this.pushEventToGA( + this.$route.query[this.queryStrings.FMG_PAGE], + this.GaActions.SUBMITTED, + this.GaLabels.VINLOOKUP, + true + ); + }); + }, backButtonAction() { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - this.pushEventToGA(this.$route.query[this.queryStrings.FMG_PAGE], this.GaActions.SUBMITTED, this.GaLabels.VINLOOKUP , true); - const zipValidation = await this.validateZip(this.zip); if (!zipValidation.data.isServiceable) { this.customAlertData.zip = this.zip; @@ -257,10 +304,9 @@ export default { } }, validateZip(zip) { - return baseMixin.methods.dispatchStoreAction( - storeActions.VALIDATE_ZIP, - { zip } - ); + return baseMixin.methods.dispatchStoreAction(storeActions.VALIDATE_ZIP, { + zip, + }); }, lookupVehicle(vin) { return baseMixin.methods.dispatchStoreAction( @@ -282,7 +328,7 @@ export default { store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl); store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber); store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageVifNumber); - store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.zip); + store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, this.zip); store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email); }, }, diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index c2c86c2dd..36ec73fe4 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -62,7 +62,7 @@ export default { }, pushExperimentsToDataLayer(experiments) { - experiments?.data?.forEach(exp => { + experiments?.forEach(exp => { // Set Google Dimension Index based on experiment settings. let googleDimensionIndex = 99; @@ -72,16 +72,26 @@ export default { } // Create object with dimension index and value. - const experimentWithDimension = {}; - - Object.keys(exp).forEach(key => { - experimentWithDimension[`${key}_${googleDimensionIndex}`] = exp[key]; - }); + const experimentWithDimension = { + [`experimentId_${googleDimensionIndex}`]: exp.universeId, + [`variationId_${googleDimensionIndex}`]: exp.variationId, + [`experimentName_${googleDimensionIndex}`]: exp.universeName, + [`variationName_${googleDimensionIndex}`]: exp.variationName, + [`customDimension_${googleDimensionIndex}`]: `${exp.universeId}_${exp.variationId}_${exp.universeName}_${exp.variationName}` + }; // Push to the data layer with the Google Custom Dimension Index. pushToDataLayerIfDefined(experimentWithDimension); }); - } + }, + + prependActionToMethod(object, method, actionToPrepend) { + const baseMethod = object[method.name]; + object[method.name] = function () { + actionToPrepend.apply(this, arguments); + return baseMethod.apply(object, arguments); + }; + }, }, computed: { analyticsPageEvents() { @@ -96,7 +106,7 @@ export default { GaLabels() { return GaLabels; } - } + }, }; function pushToDataLayerIfDefined(data) { diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index b4ec2a5b5..1e29e35de 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -40,21 +40,27 @@ describe("analyticsMixin.js", () => { // Arrange window.dataLayer = []; - const mockExperimentData = { - data: [ + const mockExperimentData = + [ { settings: {}, variationName: 'test', universeName: 'testUniverse' } ] - } + // Act analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData); // Assert - expect(window.dataLayer).toEqual([ { settings_99: {}, variationName_99: 'test', universeName_99: 'testUniverse' } ]); + expect(window.dataLayer).toEqual([{ + experimentId_99: undefined, + variationId_99: undefined, + experimentName_99: 'testUniverse', + variationName_99: 'test', + customDimension_99: 'undefined_undefined_testUniverse_test' + }]); }); @@ -62,22 +68,27 @@ describe("analyticsMixin.js", () => { // Arrange window.dataLayer = []; - const mockExperimentData = { - data: [ + const mockExperimentData = + [ { - settings: { "Google Custom Dimension Index": "5"}, + settings: { "Google Custom Dimension Index": "5" }, variationName: 'test', universeName: 'testUniverse' } ] - } + // Act analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData); // Assert - expect(window.dataLayer).toEqual([ { settings_5: {"Google Custom Dimension Index": "5"}, variationName_5: 'test', universeName_5: 'testUniverse' } ]); + expect(window.dataLayer).toEqual([{ + experimentId_5: undefined, + variationId_5: undefined, + experimentName_5: 'testUniverse', + variationName_5: 'test', + customDimension_5: 'undefined_undefined_testUniverse_test' + }]); }); - }); \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index 9ffd28522..f11bd4228 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -126,8 +126,12 @@ const router = createRouter({ router.afterEach(async (to, from) => { // Push page view to GA analyticsMixin.methods.pushPageViewToGA(to.query[queryStrings.FMG_PAGE]); - const assignedExperiments = await baseMixin.methods.dispatchStoreAction(storeActions.GET_EXPERIMENTS_BY_USER_FOR_GA, { userId: getDeviceIdValue() }); - analyticsMixin.methods.pushExperimentsToDataLayer(assignedExperiments); + + baseMixin.methods.dispatchStoreAction(storeActions.GET_EXPERIMENTS_BY_USER, { userId: getDeviceIdValue() }) + .then( (response) => { + analyticsMixin.methods.pushExperimentsToDataLayer(response.data); + }); + }); router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 5380a3fa7..b3ce4d6d7 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -8,14 +8,14 @@ const navigationScenarios = { CLICKED_FORWARD: "CLICKED_FORWARD", CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN", SELECTED_PARTS: "SELECTED_PARTS", - SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART", - SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS", - SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS", CONTINUING_WITH_PARTS_QUESTION: "CONTINUING_WITH_PARTS_QUESTION", CONTINUING_WITH_MULTIPLE_PARTS: "CONTINUING_WITH_MULTIPLE_PARTS", CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART", CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES", - TEMPORARY_TO_ADDRESS_LOOKUP: "TEMPORARY_TO_ADDRESS_LOOKUP", + CLICKED_FORWARD_WITHOUT_VIN: "CLICKED_FORWARD_WITHOUT_VIN", + SELECTED_MANUAL_VIN: "SELECTED_MANUAL_VIN", + SELECTED_LICENSE_PLATE: "SELECTED_LICENSE_PLATE", + SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 3290c43eb..2d27efcdf 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -59,23 +59,11 @@ const routingTable = [ }, { scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN, - destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, - }, - { - scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, - destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, - }, - { - scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, }, { - scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP,//This might be temporary - }, - { - scenario: navigationScenarios.TEMPORARY_TO_ADDRESS_LOOKUP, - destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, //This will be temporary + scenario: navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN, + destinationFmgPageValue: fmgPageValues.ESTIMATE, }, ], }, @@ -172,6 +160,26 @@ const routingTable = [ }, ], }, + {fmgPageValue: fmgPageValues.ESTIMATE, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, + }, + { + scenario: navigationScenarios.SELECTED_MANUAL_VIN, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.SELECTED_LICENSE_PLATE, + destinationFmgPageValue: fmgPageValues.LICENSE_PLATE_LOOKUP, + }, + { + scenario: navigationScenarios.SELECTED_HOME_ADDRESS, + destinationFmgPageValue: fmgPageValues.ADDRESS_LOOKUP, + }, + ], + }, ]; export { routingTable }; diff --git a/src/store/index.js b/src/store/index.js index 66005abd5..591bb70c5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -31,7 +31,7 @@ const getDefaultState = () => { }, }, serviceLocation: { - zip: null, + zipCode: null, }, customer: { emailAddress: null, @@ -144,8 +144,8 @@ export const mutations = { updateRegistrationAddress(state, registrationAddress){ state.order.vehicle.registration.address = registrationAddress; }, - updateServiceLocationZip(state, serviceLocationZip){ - state.order.serviceLocation.zip = serviceLocationZip; + updateServiceLocationZipCode(state, serviceLocationZipCode){ + state.order.serviceLocation.zipCode = serviceLocationZipCode; }, updateRegistrationCity(state, serviceCity){ state.order.serviceLocation.city = serviceCity; @@ -459,10 +459,10 @@ export const actions = { }); }, - getExperimentsByUserForGa(context, { userId }){ + GetExperimentsByUser(context, { userId }){ return globalMethods.callHttpClient({ - method: endpoints.GetExperimentsByUserForGa.method, - endpoint: `${endpoints.GetExperimentsByUserForGa.url}/${userId}`, + method: endpoints.GetExperimentsByUser.method, + endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`, payload: {} }); },