From e7c0703eb42607303186a3c88e33577632915d41 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 14 Sep 2023 17:16:21 -0400 Subject: [PATCH 01/14] Add new parameter to pass-down page name --- src/global-methods.js | 8 +++----- src/mixins/base-mixin.js | 13 +++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/global-methods.js b/src/global-methods.js index 44ba07acc..301fded68 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -12,8 +12,8 @@ export default { method, endpoint, payload, - logApiCall = true, - isFormData = false, + logApiCall = false, + pageNameToLog = null, additionalSuccessEventDataHandler, }) { return new Promise((resolve, reject) => { @@ -37,13 +37,11 @@ export default { if (additionalSuccessEventDataHandler) { additionalEventData = "_" + additionalSuccessEventDataHandler(response); } - const pageName = analyticsMixIn.methods.getPageName(); - const nextPageName = router.lastNavigationPage || pageName; const endpointWithoutParams = analyticsMixIn.methods.removeParamsFromEndpoint(endpoint); analyticsMixIn.methods.pushEventToGA( GaCategories.API_RESPONSE, - `${nextPageName}_${endpointWithoutParams}`, + `${pageNameToLog}_${endpointWithoutParams}`, `${GaLabels.SUCCESS}${additionalEventData}`, true ); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 488500639..6ad522fc8 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -31,6 +31,19 @@ export default { return store.dispatch(type, payload); }, + dispatchStoreActionWithLogging(type, payload, pageNameToLog, encodePayload = true) { + // Encode the payload if required + if (encodePayload) { + encodeUriData(payload); + } + + const wrappedParams = { + payload: payload, + pageNameToLog: pageNameToLog, + }; + + return store.dispatch(type, wrappedParams); + }, savePageDataToStore(page, data) { store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data }); }, From 786f785e7978b7733314ff204f6913d7fd3b8530 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 18 Sep 2023 14:16:22 -0400 Subject: [PATCH 02/14] Update vehicle page --- src/layouts/vehicle/vehicle.vue | 75 +++++++++++++++++++++------------ src/store/index.js | 33 ++++++++++++--- src/store/store.spec.js | 45 ++++++++++++++------ 3 files changed, 106 insertions(+), 47 deletions(-) diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 8cc3f8e88..a651a5162 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -127,9 +127,10 @@ export default { const experimentForLogging = store.getters.applicationUser.experiments.find( (e) => e.universeName === experimentUniverses.CONCEPT_FUNNEL ); - const yearQuestionInitialDataPromise = baseMixin.methods.dispatchStoreAction( + const yearQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_YEARS, - {} + {}, + "vehicle" ); var makeQuestionInitialDataPromise = null; var modelQuestionInitialDataPromise = null; @@ -140,35 +141,38 @@ export default { store.getters.order.vehicle.model && store.getters.order.vehicle.style ) { - makeQuestionInitialDataPromise = baseMixin.methods.dispatchStoreAction( + makeQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_MAKES, { year: store.getters.order.vehicle.year, - } + }, + "vehicle" ); - modelQuestionInitialDataPromise = baseMixin.methods.dispatchStoreAction( + modelQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_MODELS, { year: store.getters.order.vehicle.year, make: store.getters.order.vehicle.make, - } + }, + "vehicle" ); - styleQuestionInitialDataPromise = baseMixin.methods.dispatchStoreAction( + styleQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_STYLES, { year: store.getters.order.vehicle.year, make: store.getters.order.vehicle.make, model: store.getters.order.vehicle.model, - } + }, + "vehicle" ); } // If the concept funnel experiment is found, as it should be when coming from safelite.com, then log the experiment exposure. if (experimentForLogging !== undefined) { // Log experiment exposure - baseMixin.methods.dispatchStoreAction( + baseMixin.methods.dispatchStoreActionWithLogging( storeActions.LOG_EXPERIMENT_EXPOSURE, { userId: getDeviceIdValue(), @@ -176,6 +180,7 @@ export default { pageName: to.query.fmgPage, experiment: experimentForLogging, }, + "vehicle", false ); } @@ -304,12 +309,16 @@ export default { }, methods: { getVehicle(year, make, model, style) { - return this.dispatchStoreAction(this.storeActions.GET_VEHICLE, { - year: year, - make: make, - model: model, - style: style, - }); + return this.dispatchStoreActionWithLogging( + this.storeActions.GET_VEHICLE, + { + year: year, + make: make, + model: model, + style: style, + }, + "vehicle" + ); }, arePagePrerequisitesValid() { return true; @@ -354,24 +363,36 @@ export default { return store.getters.vehicle.style; }, async getMakeOptions(year) { - return await baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_MAKES, { - year: year, - }); + return await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_VEHICLE_MAKES, + { + year: year, + }, + "vehicle" + ); }, async getModelOptions(year, make) { - return await baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_MODELS, { - year: year, - make: make, - }); + return await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_VEHICLE_MODELS, + { + year: year, + make: make, + }, + "vehicle" + ); }, async getStyleOptions(year, make, model) { - return await baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_STYLES, { - year: year, - make: make, - model: model, - }); + return await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_VEHICLE_STYLES, + { + year: year, + make: make, + model: model, + }, + "vehicle" + ); }, getImagefromStore() { return store.getters.vehicle.imageUrl; diff --git a/src/store/index.js b/src/store/index.js index 95a028aae..31a8f81be 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -641,19 +641,23 @@ function provisionalTriggersToString(provisionalTriggers) { // Export Actions export const actions = { // Vehicle API Actions - getVehicleYears(context) { + getVehicleYears(context, { pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleYears.method, endpoint: endpoints.GetVehicleYears.url, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - lookupVehicleByYmms(context, { year, make, model, style }) { + lookupVehicleByYmms(context, { payload: { year, make, model, style }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByYmms.method, endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -728,36 +732,44 @@ export const actions = { }); }, - getVehicleMakes(context, { year }) { + getVehicleMakes(context, { payload: { year }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleMakes.method, endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getVehicleModels(context, { year, make }) { + getVehicleModels(context, { payload: { year, make }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleModels.method, endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getVehicleStyles(context, { year, make, model }) { + getVehicleStyles(context, { payload: { year, make, model }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleStyles.method, endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getVehicle(context, { year, make, model, style }) { + getVehicle(context, { payload: { year, make, model, style }, pageNameToLog }) { return globalMethods .callHttpClient({ methods: endpoints.GetVehicle.method, endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }) .then((response) => { return response; @@ -844,11 +856,16 @@ export const actions = { pageName ), payload: {}, + logApiCall: true, + pageNameToLog: pageName, }); }, // Analytics Actions - logExperimentExposure(context, { userId, sessionKey, pageName, experiment }) { + logExperimentExposure( + context, + { payload: { userId, sessionKey, pageName, experiment }, pageNameToLog } + ) { return globalMethods.callHttpClient({ method: endpoints.LogExperimentExposureIfAssigned.method, endpoint: endpoints.LogExperimentExposureIfAssigned.url, @@ -869,6 +886,8 @@ export const actions = { pageName: pageName, }, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 947299ff8..99d3e0cc2 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -370,7 +370,7 @@ describe("Actions", () => { }); // Assert - const response = await actions.getVehicleYears(context); + const response = await actions.getVehicleYears(context, { pageNameToLog: "test" }); expect(response.data).toEqual([2023, 2022, 2021]); }); @@ -385,13 +385,15 @@ describe("Actions", () => { }); // Assert - const response = await actions.lookupVehicleByYmms( - context, - "2019", - "Acura", - "ILX", - "4 DOOR SEDAN" - ); + const response = await actions.lookupVehicleByYmms(context, { + payload: { + year: "2019", + make: "Acura", + model: "ILX", + style: "4 DOOR SEDAN", + }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ carId: "C00000001" }); }); @@ -406,7 +408,12 @@ describe("Actions", () => { }); // Assert - const response = await actions.lookupVehicleByVin(context, "12345678901234567"); + const response = await actions.lookupVehicleByVin(context, { + payload: { + vin: "12345678901234567", + }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ carId: "C0000001" }); }); @@ -471,7 +478,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.getVehicleMakes(context, "2019"); + const response = await actions.getVehicleMakes(context, { + payload: { year: "2019" }, + pageNameToLog: "test", + }); expect(response.data).toEqual(["Acura", "Honda"]); }); @@ -486,7 +496,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.getVehicleModels(context, "2019", "Acura"); + const response = await actions.getVehicleModels(context, { + payload: { year: "2019", make: "Acura" }, + pageNameToLog: "test", + }); expect(response.data).toEqual(["ILX", "RDX"]); }); @@ -501,7 +514,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.getVehicleStyles(context, "2019", "Acura", "ILX"); + const response = await actions.getVehicleStyles(context, { + payload: { year: "2019", make: "Acura", model: "ILX" }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ style: "4 DOOR SEDAN" }); }); @@ -516,7 +532,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.getVehicle(context, "C00000000"); + const response = await actions.getVehicle(context, { + payload: { year: "2019", make: "Acura", model: "IDX", style: "4-door sedan" }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ carId: "C00000000", category: "CAR" }); }); From e4349b3a3dbd1cef4fac83227ce1d1e1cd773df0 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 18 Sep 2023 15:24:38 -0400 Subject: [PATCH 03/14] Vehicle damage changes --- src/layouts/vehicle-damage/vehicle-damage.spec.js | 11 +++++++---- src/layouts/vehicle-damage/vehicle-damage.vue | 11 +++++++---- src/store/index.js | 8 ++++++-- src/store/store.spec.js | 5 ++++- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index b26b5e31c..efe06a350 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -173,9 +173,10 @@ describe("vehicle-damage.vue", () => { //Assert expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace); - expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith( + expect(baseMixin.methods.dispatchStoreActionWithLogging).toBeCalledWith( storeActions.GET_DAMAGE_OPTIONS, - { carId: "C00000000" } + { carId: "C00000000" }, + "vehicle-damage" ); }); @@ -268,9 +269,10 @@ describe("vehicle-damage.vue", () => { //Assert expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace); - expect(baseMixin.methods.dispatchStoreAction).toBeCalledWith( + expect(baseMixin.methods.dispatchStoreActionWithLogging).toBeCalledWith( storeActions.GET_DAMAGE_OPTIONS, - { carId: "C00000000" } + { carId: "C00000000" }, + "vehicle-damage" ); }); }); @@ -789,6 +791,7 @@ function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCo mountOptionsMockData = Object.assign(mountOptionsMockDataDefault, mountOptionsMockData); //Mock api responses baseMixin.methods.dispatchStoreAction = jest.fn(); + baseMixin.methods.dispatchStoreActionWithLogging = jest.fn(); const apiResponses = { cmsContent: { FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index c03fabda1..9144ec66e 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -90,9 +90,10 @@ export default { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); - const damageOptionsPromise = baseMixin.methods.dispatchStoreAction( + const damageOptionsPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_DAMAGE_OPTIONS, - { carId: store.getters.vehicle.carId } + { carId: store.getters.vehicle.carId }, + "vehicle-damage" ); // Settle promises and get results @@ -325,8 +326,10 @@ export default { ); if (this.isWindshieldRepair) { - const supportingItems = await this.dispatchStoreAction( - storeActions.GET_SUPPORTING_ITEMS + const supportingItems = await this.dispatchStoreActionWithLogging( + storeActions.GET_SUPPORTING_ITEMS, + null, + "vehicle-damage" ); this.dispatchStoreAction( this.storeActions.SAVE_SUPPORTING_ITEMS, diff --git a/src/store/index.js b/src/store/index.js index 31a8f81be..26a28b39a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -776,13 +776,15 @@ export const actions = { }); }, - getDamageOptions(context, { carId }) { + getDamageOptions(context, { payload: { carId }, pageNameToLog }) { return globalMethods.callHttpClient({ methods: endpoints.GetDamageOptions.method, endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, payload: {}, additionalSuccessEventDataHandler: (response) => "QueryStringZip: " + getQuerystringParameter(queryStrings.ZIP_CODE), + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -1232,7 +1234,7 @@ export const actions = { }); }, - getSupportingItems(context) { + getSupportingItems(context, { pageNameToLog }) { const glassPartsArray = context.getters.lineItems.glassParts ?? []; const carId = context.getters.vehicle.carId; const isRepair = context.getters.damage.isRepair; @@ -1248,6 +1250,8 @@ export const actions = { parts: glassPartsArray, numberOfRepairChips: isRepair ? numberOfChips : 0, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 99d3e0cc2..75ebacc51 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -549,7 +549,10 @@ describe("Actions", () => { return Promise.resolve({ data: ["Windshield", "DriversFrontDoor"] }); }); - const response = await actions.getDamageOptions(context, "C00000000"); + const response = await actions.getDamageOptions(context, { + payload: { carId: "C00000000" }, + pageNameToLog: "test", + }); // Assert expect(response.data).toEqual(["Windshield", "DriversFrontDoor"]); From 2bec4fa045b0043be1ce7c25464f18f11cdec94a Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Mon, 18 Sep 2023 16:28:01 -0400 Subject: [PATCH 04/14] Estimate --- src/layouts/estimate/estimate.vue | 11 +++++++---- src/mixins/vin-pages-mixin.js | 6 +++++- src/store/index.js | 8 ++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index dff601165..105da110d 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -157,9 +157,10 @@ export default { var vinByAddressPromise; if (zip) { - vinByAddressPromise = baseMixin.methods.dispatchStoreAction( + vinByAddressPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.IS_VIN_BY_ADDRESS_PERMISSIBLE, - zip, + { zip: zip }, + "estimate", false ); } @@ -256,8 +257,10 @@ export default { } else if (this.$store.getters.order.referralNumber?.length === 6) { await this.navigateForwardWithSingleCarMatch(); } else if (this.isRepair) { - const supportingItemsPromise = await this.dispatchStoreAction( - storeActions.GET_SUPPORTING_ITEMS + const supportingItemsPromise = await this.dispatchStoreActionWithLogging( + storeActions.GET_SUPPORTING_ITEMS, + null, + "estimate" ); const promiseResultMap = [ diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index cad998d38..dcf96a59c 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -11,7 +11,11 @@ export default { await saveSession({}); } - const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS); + const pageName = this.$options?.name; + + const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS, { + pageNameToLog: pageName, + }); const partsOrQuestions = result.data.partsOrQuestions; vehicleQuestionsMixin.methods.navigateForward(partsOrQuestions, this); diff --git a/src/store/index.js b/src/store/index.js index 26a28b39a..87c6b95cd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -724,11 +724,13 @@ export const actions = { }); }, - isVinByAddressPermissible(context, zip) { + isVinByAddressPermissible(context, { payload: { zip }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.IsVinByAddressPermissible.method, endpoint: `${endpoints.IsVinByAddressPermissible.url}?zipcode=${zip}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -1097,7 +1099,7 @@ export const actions = { }, // PartsOrQuestions API Actions - async getPartsOrQuestions(context) { + async getPartsOrQuestions(context, { pageNameToLog }) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; @@ -1119,6 +1121,8 @@ export const actions = { zip: zipCode, vin: vin, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); // Flatten location and name properties From 5ff14add7bbaa0a815737b28411ea6fb30dd0179 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:22:56 -0400 Subject: [PATCH 05/14] Lookup Pages --- src/helpers/damage-helper.js | 7 ++--- src/helpers/damage-helper.spec.js | 11 ++++++-- src/helpers/unit-test-helper.js | 21 +++++++++++++++ .../address-lookup/address-lookup.spec.js | 13 +++++++--- src/layouts/address-lookup/address-lookup.vue | 26 +++++++++++++------ .../address-vehicles/address-vehicles.vue | 13 +++++++--- .../license-plate-lookup.spec.js | 14 +++++----- .../license-plate-lookup.vue | 21 ++++++++++----- src/layouts/vin-lookup/vin-lookup.vue | 14 +++++++--- src/mixins/base-mixin.js | 7 +++-- src/store/index.js | 25 ++++++++++++++---- src/store/store.spec.js | 19 +++++++++++--- 12 files changed, 141 insertions(+), 50 deletions(-) diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js index 727825d9d..13defa5df 100644 --- a/src/helpers/damage-helper.js +++ b/src/helpers/damage-helper.js @@ -54,10 +54,11 @@ export function includesWindshieldReplacement() { return windshieldMatches.length > 0; } -export async function isGlassAvailableForCarId(carId) { - const newGlassOptions = await baseMixin.methods.dispatchStoreAction( +export async function isGlassAvailableForCarId(carId, pageNameToLog) { + const newGlassOptions = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_DAMAGE_OPTIONS, - { carId: carId } + { carId: carId }, + pageNameToLog ); const currentGlassOptions = store.getters.damage.glassToReplace; diff --git a/src/helpers/damage-helper.spec.js b/src/helpers/damage-helper.spec.js index 73215b9c7..1b4bd9261 100644 --- a/src/helpers/damage-helper.spec.js +++ b/src/helpers/damage-helper.spec.js @@ -11,6 +11,13 @@ jest.mock("@/mixins/base-mixin.js", () => ({ }, }; }), + dispatchStoreActionWithLogging: jest.fn().mockImplementation(() => { + return { + data: { + windshieldOptions: { availableReplacementOptions: ["windshield"] }, + }, + }; + }), }, })); @@ -77,7 +84,7 @@ describe("damage-helper.js", () => { ]; // Act - const isGlassAvailable = await isGlassAvailableForCarId(); + const isGlassAvailable = await isGlassAvailableForCarId("id", "testName"); // Assert expect(isGlassAvailable).toEqual(true); @@ -91,7 +98,7 @@ describe("damage-helper.js", () => { { glassLocation: "Windshield", glassName: "sideWindow" }, ]; - const isGlassAvailable = await isGlassAvailableForCarId(); + const isGlassAvailable = await isGlassAvailableForCarId("id", "testName"); // Assert expect(isGlassAvailable).toEqual(false); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 1210f119c..467b38c2b 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -44,6 +44,16 @@ export function getMountOptions(mockData) { }); } }); + mocks.dispatchStoreActionWithLogging = jest.fn(); + mocks.dispatchStoreActionWithLogging.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList?.filter((x) => x.actionName == actionName); + + if (actionFilterResult?.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); // Mock const files mocks.storeActions = storeActions; @@ -141,5 +151,16 @@ function setupBaseMixinDispatchStoreAction(mockData) { }); } }); + + baseMixin.methods.dispatchStoreActionWithLogging = jest.fn(); + baseMixin.methods.dispatchStoreActionWithLogging.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList.filter((x) => x.actionName == actionName); + + if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); } } diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js index 63847588b..624fb175b 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -471,7 +471,7 @@ describe("address-lookup.vue", () => { await wrapper.vm.forwardButtonAction(); // Assert - expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith( + expect(wrapper.vm.dispatchStoreActionWithLogging).toHaveBeenCalledWith( "lookupVinByAddress", { licenseLastName: undefined, @@ -479,12 +479,17 @@ describe("address-lookup.vue", () => { licenseStreetAddress: "1234 Main St", licenseZip: "43215", }, + "address-lookup", false ); - expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith("validateZip", { - zip: "43215", - }); + expect(wrapper.vm.dispatchStoreActionWithLogging).toHaveBeenCalledWith( + "validateZip", + { + zip: "43215", + }, + "address-lookup" + ); }); }); diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index f0bf91325..b95be8e83 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -207,7 +207,7 @@ export default { // Vehicle info change in the flow, use a variable to keep track and commit to state at the end. let vehicleInfoToCommit = {}; - const vinLookupResponse = this.dispatchStoreAction( + const vinLookupResponse = this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VIN_BY_ADDRESS, { licenseLastName: this.customerQuestions.lastName, @@ -215,6 +215,7 @@ export default { licenseZip: this.customerQuestions.addressQuestions.zipCode, licenseState: this.customerQuestions.addressQuestions.state, }, + "address-lookup", false ); @@ -227,12 +228,20 @@ export default { { resultKey: "serviceZipValidationResponse", promise: this.serviceZipCode - ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.serviceZipCode, - }) - : this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.customerQuestions.addressQuestions.zipCode, - }), + ? this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.serviceZipCode, + }, + "address-lookup" + ) + : this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.customerQuestions.addressQuestions.zipCode, + }, + "address-lookup" + ), }, ]; @@ -267,7 +276,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - carFound.carId + carFound.carId, + "address-lookup" ); // Update button "Continue with..." diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue index de1fa9999..f7af34ec9 100644 --- a/src/layouts/address-vehicles/address-vehicles.vue +++ b/src/layouts/address-vehicles/address-vehicles.vue @@ -162,9 +162,13 @@ export default { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { - const vinLookup = await this.dispatchStoreAction(storeActions.LOOKUP_VEHICLE_BY_VIN, { - vin: this.selectedVehicle.vin, - }).catch(() => { + const vinLookup = await this.dispatchStoreActionWithLogging( + storeActions.LOOKUP_VEHICLE_BY_VIN, + { + vin: this.selectedVehicle.vin, + }, + "address-vehicles" + ).catch(() => { this.$refs.funnelFooter.removeLoader(); }); @@ -173,7 +177,8 @@ export default { } this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - vinLookup.data.carId + vinLookup.data.carId, + "address-vehicles" ); await this.dispatchStoreAction( 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 bf5751637..2fa11b776 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -120,7 +120,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ""); wrapper.vm.navigateForward = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -157,7 +157,7 @@ describe("license-plate-lookup.vue", () => { }); // Mock store action call - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -201,7 +201,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.navigateForward = jest.fn(); // Mock store action call - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -242,7 +242,7 @@ describe("license-plate-lookup.vue", () => { wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => { return ""; }); - wrapper.vm.dispatchStoreAction = jest.fn(); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(); await wrapper.vm.navigateForward(); @@ -379,7 +379,7 @@ describe("license-plate-lookup.vue", () => { return { data: { vehicle: { carId: "C00000" } } }; }); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -417,7 +417,7 @@ describe("license-plate-lookup.vue", () => { await wrapper.setData({ registrationZip: "00000" }); navigateToHeritage.navigateToHeritageFunnel = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { @@ -449,7 +449,7 @@ describe("license-plate-lookup.vue", () => { await wrapper.setData({ registrationZipCode: "00000" }); navigateToHeritage.navigateToHeritageFunnel = jest.fn(); - wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => + wrapper.vm.dispatchStoreActionWithLogging = jest.fn().mockImplementation(() => Promise.resolve({ data: { vehicle: { diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index 326215243..abd49c91a 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -199,9 +199,10 @@ export default { async forwardButtonAction() { this.resetWarningsAndErrors(); - const registrationZipValidationResponse = this.dispatchStoreAction( + const registrationZipValidationResponse = this.dispatchStoreActionWithLogging( storeActions.VALIDATE_ZIP, - { zip: this.registrationZipCode } + { zip: this.registrationZipCode }, + "license-plate-lookup" ); // Settle promises and get results @@ -214,9 +215,13 @@ export default { // If serviceZipCode is not set, then sets the response to the registrationZipValidationResponse. Calls VALIDATE_ZIP if the serviceZipCode is set. resultKey: "serviceZipValidationResponse", promise: this.serviceZipCode - ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { - zip: this.serviceZipCode, - }) + ? this.dispatchStoreActionWithLogging( + storeActions.VALIDATE_ZIP, + { + zip: this.serviceZipCode, + }, + "license-plate-lookup" + ) : registrationZipValidationResponse, }, ]; @@ -260,7 +265,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - vinLookup.data.vehicle.carId + vinLookup.data.vehicle.carId, + "license-plate-lookup" ); // Update button "Continue with..." @@ -312,9 +318,10 @@ export default { return await this.navigateForward(); }, lookupVin(plate, state) { - return this.dispatchStoreAction( + return this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VIN_BY_PLATE, { licensePlate: plate, licenseState: state }, + "license-plate-lookup", false ); }, diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index c0b1f1788..3103ac4e1 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -255,9 +255,10 @@ export default { // If this is a new VIN Lookup, do both a Vehicle Lookup and a Zip Validation if (!this.vinPopulatedOnPageLoad) { - const vehicleLookupResponse = this.dispatchStoreAction( + const vehicleLookupResponse = this.dispatchStoreActionWithLogging( storeActions.LOOKUP_VEHICLE_BY_VIN, - { vin: this.vin } + { vin: this.vin }, + "vin-lookup" ); // Settle promises and get results @@ -311,7 +312,8 @@ export default { this.displayMatchedDifferentVehicleAlert = true; this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId( - resultMap.vehicleLookupResponse.carId + resultMap.vehicleLookupResponse.carId, + "vin-lookup" ); // Update button "Continue with..." @@ -399,7 +401,11 @@ export default { }, getVinFromImage(image) { return new Promise((resolve, reject) => { - this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_IMAGE, image) + this.dispatchStoreActionWithLogging( + storeActions.LOOKUP_VIN_BY_IMAGE, + image, + "vin-lookup" + ) .then((response) => { if (response.data.length > 0) { resolve(response.data[0]); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 6ad522fc8..c38836dfb 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -64,9 +64,12 @@ export default { return footerInfoBox ? footerInfoBox.offsetHeight : 0; }, async getZipCodeData(zipCode) { - const serviceZipValidationResponse = await this.dispatchStoreAction( + const pageName = this.$options?.name; + + const serviceZipValidationResponse = await this.dispatchStoreActionWithLogging( storeActions.VALIDATE_ZIP, - { zip: zipCode } + { zip: zipCode }, + pageName ); return { diff --git a/src/store/index.js b/src/store/index.js index 87c6b95cd..a8cfe77fd 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -661,17 +661,19 @@ export const actions = { }); }, - lookupVehicleByVin(context, { vin }) { + lookupVehicleByVin(context, { payload: { vin }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByVin.method, endpoint: endpoints.LookupVehicleByVin.url, payload: { vin: vin, // EX "1J4GW58S4XC541166" }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - lookupVinByPlate(context, { licensePlate, licenseState }) { + lookupVinByPlate(context, { payload: { licensePlate, licenseState }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByPlate.method, endpoint: endpoints.LookupVinByPlate.url, @@ -679,12 +681,17 @@ export const actions = { licensePlate: licensePlate, licenseState: licenseState, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, lookupVinByAddress( context, - { licenseLastName, licenseStreetAddress, licenseZip, licenseState } + { + payload: { licenseLastName, licenseStreetAddress, licenseZip, licenseState }, + pageNameToLog, + } ) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByAddress.method, @@ -695,10 +702,14 @@ export const actions = { licenseZip: licenseZip, licenseState: licenseState, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - lookupVinByImage(context, image) { + lookupVinByImage(context, { payload, pageNameToLog }) { + const image = payload; + return new Promise((resolve, reject) => { let reader = new FileReader(); reader.onload = (e) => { @@ -720,6 +731,8 @@ export const actions = { method: endpoints.LookupVinByImage.method, endpoint: endpoints.LookupVinByImage.url, payload: data, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }); }, @@ -790,10 +803,12 @@ export const actions = { }); }, - validateZip(context, { zip }) { + validateZip(context, { payload: { zip }, pageNameToLog }) { return globalMethods.callHttpClient({ methods: endpoints.ValidateZip.method, endpoint: `${endpoints.ValidateZip.url}/${zip}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 75ebacc51..a0491f47c 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -428,7 +428,10 @@ describe("Actions", () => { }); // Assert - const response = await actions.lookupVinByPlate(context, "12345678901234567"); + const response = await actions.lookupVinByPlate(context, { + payload: { licensePlate: "12345678901234567", licenseState: "OH" }, + pageNameToLog: "test", + }); expect(response.data).toEqual({ carId: "C00000001" }); }); @@ -445,7 +448,10 @@ describe("Actions", () => { }); // Act - const response = await actions.lookupVinByImage(context, image); + const response = await actions.lookupVinByImage(context, { + payload: image, + pageNameToLog: "test", + }); // Assert expect(response.data).toEqual(["1C6JJTAG3NL134044"]); @@ -465,7 +471,9 @@ describe("Actions", () => { // Act // Assert - await expect(actions.lookupVinByImage(context, image)).rejects.toEqual("An error occurred"); + await expect( + actions.lookupVinByImage(context, { payload: image, pageNameToLog: "test" }) + ).rejects.toEqual("An error occurred"); }); it("getVehicleMakes action, should return makes list", async () => { @@ -574,7 +582,10 @@ describe("Actions", () => { }); }); - const response = await actions.validateZip(context, "43212"); + const response = await actions.validateZip(context, { + payload: { zip: "43212" }, + pageNameToLog: "test", + }); // Assert expect(response.data).toEqual({ From e4d98521d8cbb9155e0d25e45fb9fb4e470b9d77 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:49:51 -0400 Subject: [PATCH 06/14] Test fix --- src/mixins/base-mixin.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index b768b67d5..2ef76315e 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -101,8 +101,8 @@ describe("baseMixin.js", () => { test("getZipCodeData calls dispatch", () => { const mixIn = getMixInInstance({}); - mixIn.methods.dispatchStoreAction = jest.fn(); - mixIn.methods.dispatchStoreAction.mockReturnValue({ + mixIn.methods.dispatchStoreActionWithLogging = jest.fn(); + mixIn.methods.dispatchStoreActionWithLogging.mockReturnValue({ data: { isValid: true, isServiceable: true, state: "OH" }, }); const type = ""; @@ -118,7 +118,7 @@ describe("baseMixin.js", () => { mixIn.methods.getZipCodeData(type, payload); - expect(mixIn.methods.dispatchStoreAction).toBeCalled(); + expect(mixIn.methods.dispatchStoreActionWithLogging).toBeCalled(); }); }); From 7aa61e89982438931a984e00e8bca2ce8bbe740f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 19 Sep 2023 12:50:09 -0400 Subject: [PATCH 07/14] Runexperiments --- src/router/index.js | 28 ++++++++++++++++++---------- src/store/index.js | 7 ++++++- src/store/store.spec.js | 10 ++++++++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index e8fbf4d26..b49b38d9f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -394,18 +394,26 @@ function arePagePrerequisitesValid(component) { // Run SiteEntry and PageEntry triggers for experiments async function runExperiments(nextPage) { if (!store.getters.applicationUser.triggeredSiteEntry) { - await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, { - userId: getDeviceIdValue(), - triggerEvent: experimentTriggers.SITE_ENTRY, - triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE, - }); + await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, + { + userId: getDeviceIdValue(), + triggerEvent: experimentTriggers.SITE_ENTRY, + triggerValue: applicationConfig.SITE_ENTRY_TRIGGER_VALUE, + }, + nextPage + ); } - await baseMixin.methods.dispatchStoreAction(storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, { - userId: getDeviceIdValue(), - triggerEvent: experimentTriggers.PAGE_ENTRY, - triggerValue: nextPage, - }); + await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.RUN_EXPERIMENTS_FOR_TRIGGER, + { + userId: getDeviceIdValue(), + triggerEvent: experimentTriggers.PAGE_ENTRY, + triggerValue: nextPage, + }, + nextPage + ); } export default router; diff --git a/src/store/index.js b/src/store/index.js index a8cfe77fd..50124bee7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1083,7 +1083,10 @@ export const actions = { }); }, - async runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { + async runExperimentsForTrigger( + context, + { payload: { userId, triggerEvent, triggerValue }, pageNameToLog } + ) { if (triggerEvent == experimentTriggers.SITE_ENTRY) { context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true); } @@ -1100,6 +1103,8 @@ export const actions = { method: endpoints.RunExperimentsForTrigger.method, endpoint: endpoints.RunExperimentsForTrigger.url, payload: payload, + logApiCall: true, + pageNameToLog: pageNameToLog, }); context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments); diff --git a/src/store/store.spec.js b/src/store/store.spec.js index a0491f47c..611341aa7 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1751,7 +1751,10 @@ describe("Actions", () => { // Act await actions.runExperimentsForTrigger(context, { - triggerEvent: experimentTriggers.SITE_ENTRY, + payload: { + triggerEvent: experimentTriggers.SITE_ENTRY, + }, + pageNameToLog: "test", }); // Assert @@ -1785,7 +1788,10 @@ describe("Actions", () => { // Act await actions.runExperimentsForTrigger(context, { - triggerEvent: "NotSiteEntry", + payload: { + triggerEvent: "NotSiteEntry", + }, + pageNameToLog: "test", }); // Assert From fed47a13e9b7e54f6fdc7b712453224579e763e7 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 20 Sep 2023 11:16:45 -0400 Subject: [PATCH 08/14] Save/Load Session --- .../heritage-integration/navigation-helper.js | 4 +-- .../heritage-integration/order-helper.js | 25 ++++++++++++------- .../heritage-integration/order-helper.spec.js | 10 +++++--- src/layouts/estimate/estimate.vue | 3 ++- src/layouts/quote/quote.vue | 1 + src/mixins/vehicle-questions-mixin.js | 2 ++ src/mixins/vin-pages-mixin.js | 6 ++--- src/router/index.js | 5 ++-- src/store/index.js | 21 ++++++++++------ src/store/store.spec.js | 17 ++++++++++--- 10 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 5b421b056..8fdfc40bb 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -45,10 +45,10 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}) { Used to navigate to the heritage funnel with the correct query string and url. */ -export async function navigateToHeritageFunnel({ shouldSaveSession, loadingModal }) { +export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog, loadingModal }) { // Create the order (or save existing order) when navigating to Heritage Funnel. if (shouldSaveSession) { - await saveSession({ shouldAwaitSaveSessionQueue: true }); + await saveSession({ pageNameToLog: pageNameToLog, shouldAwaitSaveSessionQueue: true }); } if (loadingModal && loadingModal.showModal) { diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index 01f5a5d67..addca2d41 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -14,7 +14,7 @@ import { storeMutations } from "@/constants/store-mutations"; it will reset the state and go back to the start of the funnel. */ -export async function loadSessionIfPresent(isConceptInsurance) { +export async function loadSessionIfPresent(isConceptInsurance, pageNameToLog) { const funnelCookie = getFunnelCookie(); // Do nothing if there is no cookie or session to use for loading. @@ -42,7 +42,8 @@ export async function loadSessionIfPresent(isConceptInsurance) { funnelCookie.ReferralDate, funnelCookie.ReferralParentAccountNumber, funnelCookie.ReferralCorrelationId, - isConceptInsurance + isConceptInsurance, + pageNameToLog ) )?.data; } @@ -52,17 +53,17 @@ export async function loadSessionIfPresent(isConceptInsurance) { This will also set Referral information in the store after saving, and then update the cookie. To force synchronous behavior pass in 'true' for shouldAwaitSaveSessionQueue */ -export async function saveSession({ shouldAwaitSaveSessionQueue = false }) { +export async function saveSession({ pageNameToLog, shouldAwaitSaveSessionQueue = false }) { var saveSessionPromise; if (store.getters.applicationUser.saveSessionPromise) { // queue newest request after current saveSessionPromise resolves saveSessionPromise = store.getters.applicationUser.saveSessionPromise.then(() => { // get a new saveSessionPromise - return saveSessionHelper(); + return saveSessionHelper(pageNameToLog); }); } else { // create an initial saveSessionPromise - saveSessionPromise = saveSessionHelper(); + saveSessionPromise = saveSessionHelper(pageNameToLog); } store.commit(storeMutations.UPDATE_SAVE_SESSION_PROMISE, saveSessionPromise); // await here to allow for a caller to await and make the function synchronous @@ -83,12 +84,13 @@ async function loadSession( referralDate, parentAccountNumber, referralCorrelationId, - isConceptInsurance + isConceptInsurance, + pageNameToLog ) { // await the saveSessionPromise in the store to make sure we're loading up to date information await store.getters.applicationUser.saveSessionPromise; - const response = await baseMixin.methods.dispatchStoreAction( + const response = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.LOAD_SESSION, { savedSessionId: savedSessionId?.toString(), @@ -98,6 +100,7 @@ async function loadSession( parentAccountNumber, isConceptInsurance, }, + pageNameToLog, false ); @@ -107,8 +110,12 @@ async function loadSession( /* Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing */ -async function saveSessionHelper() { - const savedSessionInfo = await baseMixin.methods.dispatchStoreAction(storeActions.SAVE_SESSION); +async function saveSessionHelper(pageNameToLog) { + const savedSessionInfo = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.SAVE_SESSION, + null, + pageNameToLog + ); // Update the store with information received from the saveSession response await baseMixin.methods.dispatchStoreAction( storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE, diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index fab4a1532..94e52b1dd 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -170,11 +170,13 @@ describe("saveSession", () => { const mocks = setupMocksForJsFiles(mockData); // Act - await saveSession({}); + await saveSession({ pageNameToLog: "test" }); // Assert - expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith( - storeActions.SAVE_SESSION + expect(mocks.baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith( + storeActions.SAVE_SESSION, + null, + "test" ); expect(mocks.baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith( storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE, @@ -231,7 +233,7 @@ describe("saveSession", () => { setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); // Act - await saveSession({}); + await saveSession({ pageNameToLog: "test" }); // Assert expect(cookieHelper.getFunnelCookie().DidHeritageFunnelUpdateLast).toEqual(false); diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index aaaa26fbf..cdd82b1ae 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -260,6 +260,7 @@ export default { if (vehicleChangedDuringPolicyLookupInHeritage) { navigateToHeritageFunnel({ shouldSaveSession: true, + pageNameToLog: "estimate", loadingModal: this.$refs.loadingModal, }); } else if (this.$store.getters.order.referralNumber?.length === 6) { @@ -287,7 +288,7 @@ export default { ); // call saveSession here - navigateWithSaving saves too late in the flow - await saveSession({}); + await saveSession({ pageNameToLog: "estimate" }); return this.$router.navigateWithSaving( this.navigationScenarios.CLICKED_FORWARD_WITH_NO_QUESTIONS, this.$route diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 46f573144..8a95d36cd 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -236,6 +236,7 @@ export default { if (payment.isInsurance) { navigateToHeritageFunnel({ shouldSaveSession: true, + pageNameToLog: "quote", loadingModal: this.$refs.loadingModal, }); } else { diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index fb54c059f..a1d672cd7 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -449,11 +449,13 @@ export default { if (store.getters.order.referralNumber?.length === 6) { navigateToHeritageFunnel({ shouldSaveSession: true, + pageNameToLog: this.$options.name, loadingModal: self.$refs.loadingModal, }); } else if (payment.isInsurance && payment.insuranceCoverage.isVerified) { navigateToHeritageFunnel({ shouldSaveSession: true, + pageNameToLog: this.$options.name, loadingModal: self.$refs.loadingModal, }); } else { diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index dcf96a59c..a0a435000 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -6,13 +6,13 @@ import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; export default { methods: { async navigateForwardWithSingleCarMatch() { + const pageName = this.$options?.name; + // If we have not already saved a session, we need to save one now before the lengthy call to getPartsOrQuestions if (!store.getters.applicationUser.savedSessionId) { - await saveSession({}); + await saveSession({ pageNameToLog: pageName }); } - const pageName = this.$options?.name; - const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS, { pageNameToLog: pageName, }); diff --git a/src/router/index.js b/src/router/index.js index 5ec48f14f..eadf3b9f6 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -72,7 +72,8 @@ const routes = [ ? to.query.isInsurance == "true" ? true : false - : null + : null, + to.query.fmgPage ); const pageToRedirectTo = await getPageToRouteExistingOrderTo(to); @@ -172,7 +173,7 @@ router.afterEach(async (to, from) => { store.getters.applicationUser.savedSessionId || store.getters.order.customer?.emailAddress ) { - await saveSession({}); + await saveSession({ pageNameToLog: to.query.fmgPage }); } } diff --git a/src/store/index.js b/src/store/index.js index 9fbf83399..0f7b06406 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1460,7 +1460,7 @@ export const actions = { }, // Session API Actions - saveSession(context) { + saveSession(context, { pageNameToLog }) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; @@ -1566,6 +1566,8 @@ export const actions = { eon: order.eon, }, }, + logApiCall: true, + pageNameToLog: pageNameToLog, additionalSuccessEventDataHandler: (response) => "Email provided: " + (order.customer.emailAddress ? "true" : "false"), }); @@ -1574,12 +1576,15 @@ export const actions = { loadSession( context, { - savedSessionId, - referralNumber, - referralDate, - parentAccountNumber, - referralCorrelationId, - isConceptInsurance, + payload: { + savedSessionId, + referralNumber, + referralDate, + parentAccountNumber, + referralCorrelationId, + isConceptInsurance, + }, + pageNameToLog, } ) { const order = context.state.order; @@ -1595,6 +1600,8 @@ export const actions = { parentAccountNumber: parentAccountNumber, referralCorrelationId: referralCorrelationId, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }) .then( async (response) => { diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 611341aa7..bdb81279d 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -763,7 +763,7 @@ describe("Actions", () => { }); // Act - const response = await actions.saveSession(context); + const response = await actions.saveSession(context, { pageNameToLog: "test" }); // Assert expect(response.data).toEqual({ referralNumber: 123 }); @@ -783,7 +783,10 @@ describe("Actions", () => { // Act const response = await actions.loadSession(context, { - savedSessionId: "", + payload: { + savedSessionId: "", + }, + pageNameToLog: "test", }); // Assert @@ -809,7 +812,10 @@ describe("Actions", () => { // Act const response = await actions.loadSession(context, { - savedSessionId: "", + payload: { + savedSessionId: "", + }, + pageNameToLog: "test", }); // Assert @@ -834,7 +840,10 @@ describe("Actions", () => { // Act const response = await actions.loadSession(context, { - savedSessionId: "", + payload: { + savedSessionId: "", + }, + pageNameToLog: "test", }); // Assert From b7f2f060ab7f682c00cbc27f7ce89aa6e588904f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 20 Sep 2023 13:01:31 -0400 Subject: [PATCH 09/14] Misc Questions Pages --- .../capability-questions.spec.js | 25 +++++++++++++-- .../capability-questions.vue | 3 +- .../part-questions/part-questions.spec.js | 32 +++++++++++++++++-- src/layouts/part-questions/part-questions.vue | 6 +++- src/mixins/vehicle-questions-mixin.js | 9 +++--- src/store/index.js | 13 ++++++-- 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/layouts/capability-questions/capability-questions.spec.js b/src/layouts/capability-questions/capability-questions.spec.js index 34fb4be05..b901db0ca 100644 --- a/src/layouts/capability-questions/capability-questions.spec.js +++ b/src/layouts/capability-questions/capability-questions.spec.js @@ -237,6 +237,11 @@ describe("capabilityQuestions.vue", () => { data: [], }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: [], + }; + }); // Act wrapper.vm.forwardButtonAction(); @@ -272,6 +277,11 @@ describe("capabilityQuestions.vue", () => { data: [], }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: [], + }; + }); const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction"); // Act @@ -325,7 +335,12 @@ describe("capabilityQuestions.vue", () => { data: [], }; }); - const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction"); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: [], + }; + }); + const spy = jest.spyOn(wrapper.vm, "dispatchStoreActionWithLogging"); // Act wrapper.vm.forwardButtonAction(); @@ -334,9 +349,10 @@ describe("capabilityQuestions.vue", () => { //Assert expect(spy).toHaveBeenNthCalledWith( - 2, + 1, "getPartFromCapabilityQuestionAnswer", "Windshield", + "capability-questions", false ); @@ -368,6 +384,11 @@ describe("capabilityQuestions.vue", () => { data: [], }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: [], + }; + }); wrapper.vm.navigateForward = jest.fn(); // Act diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 5456b816c..717865e41 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -162,9 +162,10 @@ export default { const partsOrQuestions = this.partsOrQuestionsData; for (let answer of questionAnswersArray) { const partFromCapabilityQuestionAnswer = ( - await this.dispatchStoreAction( + await this.dispatchStoreActionWithLogging( this.storeActions.GET_PART_FROM_CAPABILITY_QUESTION_ANSWER, answer.glassLocation, + "capability-questions", false ) ).data; diff --git a/src/layouts/part-questions/part-questions.spec.js b/src/layouts/part-questions/part-questions.spec.js index 3382ec1dc..a1da5cdef 100644 --- a/src/layouts/part-questions/part-questions.spec.js +++ b/src/layouts/part-questions/part-questions.spec.js @@ -248,6 +248,13 @@ describe("partQuestions.vue...", () => { }, }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: { + glassPieceParts: [], + }, + }; + }); // Act wrapper.vm.forwardButtonAction(); @@ -281,6 +288,13 @@ describe("partQuestions.vue...", () => { }, }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: { + glassPieceParts: [], + }, + }; + }); const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction"); // Act @@ -328,7 +342,14 @@ describe("partQuestions.vue...", () => { }, }; }); - const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction"); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: { + glassPieceParts: [], + }, + }; + }); + const spy = jest.spyOn(wrapper.vm, "dispatchStoreActionWithLogging"); // Act wrapper.vm.forwardButtonAction(); @@ -336,7 +357,7 @@ describe("partQuestions.vue...", () => { await nextTick(); //Assert - expect(spy).toHaveBeenNthCalledWith(2, "getParts"); + expect(spy).toHaveBeenNthCalledWith(1, "getParts", null, "part-questions"); wrapper.unmount(); }); @@ -362,6 +383,13 @@ describe("partQuestions.vue...", () => { }, }; }); + wrapper.vm.dispatchStoreActionWithLogging = jest.fn(() => { + return { + data: { + glassPieceParts: [], + }, + }; + }); wrapper.vm.navigateForward = jest.fn(); // Act diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index b94c92e1d..63e1d9198 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -145,7 +145,11 @@ export default { ); // call API parts method - const partsLookup = await this.dispatchStoreAction(this.storeActions.GET_PARTS); + const partsLookup = await this.dispatchStoreActionWithLogging( + this.storeActions.GET_PARTS, + null, + "part-questions" + ); const glassPartsForStore = partsLookup.data.glassPieceParts; diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index a1d672cd7..43c55e8cf 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -408,12 +408,13 @@ export default { for (let partOrQuestion of partsOrQuestions) { if (this.hasCapabilityQuestions([partOrQuestion])) { let capabilityQuestionsForGlassLocation = ( - await baseMixin.methods.dispatchStoreAction( + await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_CAPABILITY_QUESTIONS, { carId: store.getters.vehicle.carId, partNumber: partOrQuestion.parts[0].partNumber, - } + }, + currentPage ) ).data; @@ -449,13 +450,13 @@ export default { if (store.getters.order.referralNumber?.length === 6) { navigateToHeritageFunnel({ shouldSaveSession: true, - pageNameToLog: this.$options.name, + pageNameToLog: currentPage, loadingModal: self.$refs.loadingModal, }); } else if (payment.isInsurance && payment.insuranceCoverage.isVerified) { navigateToHeritageFunnel({ shouldSaveSession: true, - pageNameToLog: this.$options.name, + pageNameToLog: currentPage, loadingModal: self.$refs.loadingModal, }); } else { diff --git a/src/store/index.js b/src/store/index.js index 0f7b06406..ebee7760e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1171,7 +1171,7 @@ export const actions = { }, // Parts API Actions - async getParts(context) { + async getParts(context, { pageNameToLog }) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; @@ -1196,6 +1196,8 @@ export const actions = { zip: zipCode, vin: vin, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); // Flatten location and name properties @@ -1296,14 +1298,17 @@ export const actions = { }); }, - getCapabilityQuestions(context, { carId, partNumber }) { + getCapabilityQuestions(context, { payload: { carId, partNumber }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetCapabilityQuestions.method, endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getPartFromCapabilityQuestionAnswer(context, glassLocation) { + getPartFromCapabilityQuestionAnswer(context, { payload, pageNameToLog }) { + const glassLocation = payload; const pageData = context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); const part = pageData.partsOrQuestions.find((x) => x.glassLocation === glassLocation) @@ -1320,6 +1325,8 @@ export const actions = { part, capabilityAnswerResults: capabilityQuestionAnswersForPart, }, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, From 6161e8de1249355bc8cc1953aac9ff832b218841 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 21 Sep 2023 09:56:15 -0400 Subject: [PATCH 10/14] GetRouteInfo --- src/store/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/store/index.js b/src/store/index.js index ebee7760e..95ca50f1c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -874,6 +874,8 @@ export const actions = { payload: { pageName: pageName, }, + logApiCall: true, + pageNameToLog: pageName, }); }, From 9a3318b3fd71adc11d101cedd35a8988f64c5e6e Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 21 Sep 2023 10:11:44 -0400 Subject: [PATCH 11/14] Quote --- src/layouts/quote/quote.spec.js | 4 ++++ src/layouts/quote/quote.vue | 21 +++++++++++++++------ src/store/index.js | 12 +++++++++--- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index b4a3df9fb..60948bd52 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -36,6 +36,10 @@ jest.mock("@/mixins/base-mixin", () => ({ if (action === mockPriceOrderStoreAction) return items; else return mockStoreActionResults[action]; }, + dispatchStoreActionWithLogging(action, items, pageName, encode) { + if (action === mockPriceOrderStoreAction) return items; + else return mockStoreActionResults[action]; + }, getTierOnePackagePrice() { return mockTierOnePrice; }, diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 8a95d36cd..f8372a35a 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -86,12 +86,20 @@ export default { async beforeRouteEnter(to, from, next) { // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); - const wipersPromise = baseMixin.methods.dispatchStoreAction(storeActions.GET_WIPERS); - const rainDefensePromise = baseMixin.methods.dispatchStoreAction( - storeActions.GET_RAIN_DEFENSE + const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_WIPERS, + null, + "quote" ); - const supportingItemsPromise = baseMixin.methods.dispatchStoreAction( - storeActions.GET_SUPPORTING_ITEMS + const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_RAIN_DEFENSE, + null, + "quote" + ); + const supportingItemsPromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_SUPPORTING_ITEMS, + null, + "quote" ); const promiseResultMap = [ @@ -124,11 +132,12 @@ export default { ...clonedGlassParts, ]; - const pricingResults = await baseMixin.methods.dispatchStoreAction( + const pricingResults = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA, { availableLineItems: availableLineItems, }, + "quote", false ); diff --git a/src/store/index.js b/src/store/index.js index 95ca50f1c..e468fc224 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1210,13 +1210,15 @@ export const actions = { return response; }, - getWipers(context) { + getWipers(context, { pageNameToLog }) { const carId = context.getters.vehicle.carId; const serviceZipCode = context.getters.order.serviceLocation.zipCode; return globalMethods .callHttpClient({ method: endpoints.GetWipers.method, endpoint: `${endpoints.GetWipers.url}/${carId}/${serviceZipCode}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }) .catch((error) => { // The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow @@ -1224,10 +1226,12 @@ export const actions = { }); }, - getRainDefense(context) { + getRainDefense(context, { pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetRainDefense.method, endpoint: endpoints.GetRainDefense.url, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -1959,7 +1963,7 @@ export const actions = { // Price order actions async priceOrderItemsAndSaveServerData( context, - { availableLineItems, serviceZipCode, serviceZipCodeCtu } + { payload: { availableLineItems, serviceZipCode, serviceZipCodeCtu }, pageNameToLog } ) { const zipCodeToUse = serviceZipCode ? serviceZipCode @@ -1999,6 +2003,8 @@ export const actions = { const response = await globalMethods.callHttpClient({ method: endpoints.PriceOrderItems.method, endpoint: `${endpoints.PriceOrderItems.url}?${queryString}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData); From 964b06744f9b60d2ea77d3c1ca9eb00e9ae31ab3 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 21 Sep 2023 14:08:32 -0400 Subject: [PATCH 12/14] Service Location --- .../service-location-helper.js | 18 ++++---- .../service-location-helper.spec.js | 41 +++++++++++++++++++ .../mobile-location-modal-questions.vue | 14 +++++-- .../service-location/service-location.vue | 10 +++-- .../service-zip-modal-question.vue | 16 ++++++-- .../shop-question/shop-question.vue | 10 +++-- src/mixins/base-mixin.js | 7 +++- src/store/index.js | 19 +++++++-- 8 files changed, 110 insertions(+), 25 deletions(-) diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 19758bd07..2298aa386 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -2,42 +2,45 @@ import { storeActions } from "@/constants/store-actions"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin.js"; -export async function getPricedMobileFeePart(serviceZipCode) { +export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { if (!serviceZipCode) { return Promise.resolve(null); } - const zipCodeData = await baseMixin.methods.getZipCodeData(serviceZipCode); + const zipCodeData = await baseMixin.methods.getZipCodeData(serviceZipCode, pageNameToLog); // Get the Mobile Fee Part - const mobileFeePart = await baseMixin.methods.dispatchStoreAction( + const mobileFeePart = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_MOBILE_FEE_PART, null, + pageNameToLog, false ); // Get the Mobile Fee Part Price - const pricingResults = await baseMixin.methods.dispatchStoreAction( + const pricingResults = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA, { availableLineItems: [mobileFeePart.data], serviceZipCode: serviceZipCode, serviceZipCodeCtu: zipCodeData.zipCodeCtu, }, + pageNameToLog, false ); return Promise.resolve(pricingResults[0]); } -export async function getServiceabilityDetails(serviceZipCode, lineItems) { +export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNameToLog) { // Get the Mobile Fee Part - const serviceabilityDetails = await baseMixin.methods.dispatchStoreAction( + const serviceabilityDetails = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_SERVICEABILITY_DETAILS, { serviceZipCode: serviceZipCode, lineItems: lineItems, }, + pageNameToLog, false ); @@ -51,7 +54,7 @@ export async function getAvailabilityRating( providerNumber ) { // For a given shop provider number and date range, get the appointment time slots available - const shopTimeSlots = await baseMixin.methods.dispatchStoreAction( + const shopTimeSlots = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_SHOP_TIME_SLOTS, { providerNumber: providerNumber, @@ -59,6 +62,7 @@ export async function getAvailabilityRating( endDate: endDate, shopAppointmentType: shopAppointmentType, }, + "service-location", false ); diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js index 6b530fddb..5bb41c657 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js @@ -188,6 +188,47 @@ jest.mock("@/mixins/base-mixin.js", () => ({ }); } + if (actionName === mockStoreActionGetShopTimeSlots) { + if (request.providerNumber == "0000001") { + return Promise.resolve(mockGetShopTimeSlotsGoodAvailability); + } + + return Promise.resolve(mockGetShopTimeSlotsLowAvailability); + } + }), + dispatchStoreActionWithLogging: jest.fn().mockImplementation((actionName, request) => { + if (actionName === mockStoreActionGetMobileFeePart) { + return Promise.resolve({ + data: { + partNumber: "MOBILE FEE", + description: "MOBILE FEE", + partType: "FEE", + }, + }); + } + + if (actionName === mockStoreActionPriceOrderItemsAndSaveServerData) { + return Promise.resolve([ + { + partNumber: "MOBILE FEE", + description: "MOBILE FEE", + partType: "FEE", + laborAmount: 49.99, + sellingPrice: 0, + kitPrice: 0, + }, + ]); + } + + if (actionName === mockStoreActionGetServiceabilityDetails) { + return Promise.resolve({ + isGlassServiceableInshop: true, + isRecalibrationServiceableInshop: true, + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: true, + }); + } + if (actionName === mockStoreActionGetShopTimeSlots) { if (request.providerNumber == "0000001") { return Promise.resolve(mockGetShopTimeSlotsGoodAvailability); diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue index 0fef11cb1..2c63bdf43 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue @@ -229,7 +229,8 @@ export default { ) { // Validate the Zip Code const zipCodeData = await this.getZipCodeData( - this.internalModel.addressQuestions.zipCode + this.internalModel.addressQuestions.zipCode, + "service-location" ); if (!zipCodeData.isValid) { @@ -238,10 +239,17 @@ export default { } else { // retrieve mobile fee part const serviceZipCode = this.internalModel.addressQuestions.zipCode; - const mobileFeePart = await getPricedMobileFeePart(serviceZipCode); + const mobileFeePart = await getPricedMobileFeePart( + serviceZipCode, + "service-location" + ); // retrieve serviceability details - const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode); + const serviceabilityDetails = await getServiceabilityDetails( + serviceZipCode, + null, + "service-location" + ); // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index f93a1d5c8..ea81491ab 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -177,11 +177,15 @@ export default { const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const serviceZipCode = store.getters.order.serviceLocation.zipCode; - const getZipCodeData = baseMixin.methods.getZipCodeData(serviceZipCode); + const getZipCodeData = baseMixin.methods.getZipCodeData(serviceZipCode, "service-location"); - const serviceabilityDetailsPromise = getServiceabilityDetails(serviceZipCode); + const serviceabilityDetailsPromise = getServiceabilityDetails( + serviceZipCode, + null, + "service-location" + ); - const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode); + const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode, "service-location"); const shopQuestionInitialDataPromise = shopQuestion.methods.loadInitialData(serviceZipCode); diff --git a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue index d24bb618a..34a3d23c1 100644 --- a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue +++ b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue @@ -133,7 +133,10 @@ export default { if (this.internalModel.zipCode !== this.modelValue.zipCode) { this.resetAlerts(); - const zipCodeData = await this.getZipCodeData(this.internalModel.zipCode); + const zipCodeData = await this.getZipCodeData( + this.internalModel.zipCode, + "service-location" + ); if (!zipCodeData.isValid) { this.displayInvalidZipAlert = true; @@ -144,10 +147,17 @@ export default { // retrieve mobile fee part const serviceZipCode = this.internalModel.zipCode; - const mobileFeePart = await getPricedMobileFeePart(serviceZipCode); + const mobileFeePart = await getPricedMobileFeePart( + serviceZipCode, + "service-location" + ); // retrieve serviceability details - const serviceabilityDetails = await getServiceabilityDetails(serviceZipCode); + const serviceabilityDetails = await getServiceabilityDetails( + serviceZipCode, + null, + "service-location" + ); // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index f588f6422..17153f9c9 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -126,9 +126,13 @@ export default { return this.loadData(serviceZipCode); }, loadData(serviceZipCode) { - return baseMixin.methods.dispatchStoreAction(storeActions.GET_PROVIDERS, { - serviceZipCode: serviceZipCode, - }); + return baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_PROVIDERS, + { + serviceZipCode: serviceZipCode, + }, + "service-location" + ); }, initializeComponent(shopQuestionInitialData) { this.shopProviders = shopQuestionInitialData.shopProviders; diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 2632b42fb..4c7c07de1 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -63,8 +63,11 @@ export default { const footerInfoBox = document.querySelector(".footer#infoBox"); return footerInfoBox ? footerInfoBox.offsetHeight : 0; }, - async getZipCodeData(zipCode) { - const pageName = this.$options?.name; + async getZipCodeData(zipCode, pageNameToLog = null) { + const pageName = pageNameToLog ?? this.$options?.name; + if (pageName == null) { + console.log("Missed a spot."); + } const serviceZipValidationResponse = await this.dispatchStoreActionWithLogging( storeActions.VALIDATE_ZIP, diff --git a/src/store/index.js b/src/store/index.js index e468fc224..acdbea86d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1235,7 +1235,7 @@ export const actions = { }); }, - getMobileFeePart(context) { + getMobileFeePart(context, { pageNameToLog }) { const damageType = context.getters.damage.isRepair ? "Repair" : "Replace"; const parentAccountNumber = context.getters.payment.parentAccountNumber; const billToAccountNumber = 87291; // TODO: MAKE THIS REAL @@ -1243,10 +1243,12 @@ export const actions = { return globalMethods.callHttpClient({ method: endpoints.GetMobileFeePart.method, endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getServiceabilityDetails(context, { serviceZipCode }) { + getServiceabilityDetails(context, { payload: { serviceZipCode }, pageNameToLog }) { const lineItemsWithOnlyPartNumbers = context.getters.order.lineItems.supportingItems.map( (lineItem) => ({ partNumber: lineItem.partNumber, @@ -1270,16 +1272,20 @@ export const actions = { return globalMethods.callHttpClient({ method: endpoints.GetServiceabilityDetails.method, endpoint: `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&${lineItems}&${glassPieces}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, - getProviders(context, { serviceZipCode }) { + getProviders(context, { payload: { serviceZipCode }, pageNameToLog }) { const damageType = context.getters.damage.isRepair ? "Repair" : "Replace"; const shopRadiusInMiles = 100; return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, endpoint: `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -1336,7 +1342,10 @@ export const actions = { }); }, - getShopTimeSlots(context, { startDate, endDate, shopAppointmentType, providerNumber }) { + getShopTimeSlots( + context, + { payload: { startDate, endDate, shopAppointmentType, providerNumber }, pageNameToLog } + ) { const order = context.state.order; const vehicle = context.state.order.vehicle; @@ -1391,6 +1400,8 @@ export const actions = { method: endpoints.GetShopTimeSlots.method, endpoint: endpoints.GetShopTimeSlots.url, payload: payload, + logApiCall: true, + pageNameToLog: pageNameToLog, additionalSuccessEventDataHandler: (response) => getTimeSlotsAdditionalEventData( response.data.provisionalTriggers, From c2d92379023af50cd563e568dcfa7887888e01f4 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 21 Sep 2023 15:30:59 -0400 Subject: [PATCH 13/14] Schedule --- .../schedule/helpers/schedule-helper.js | 5 +- src/layouts/schedule/schedule.spec.js | 64 ++++++++++++++++++- src/layouts/schedule/schedule.vue | 12 ++-- src/store/index.js | 12 +++- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/layouts/schedule/helpers/schedule-helper.js b/src/layouts/schedule/helpers/schedule-helper.js index 0f595b435..b85572e88 100644 --- a/src/layouts/schedule/helpers/schedule-helper.js +++ b/src/layouts/schedule/helpers/schedule-helper.js @@ -2,11 +2,12 @@ import { storeActions } from "@/constants/store-actions"; import baseMixin from "@/mixins/base-mixin.js"; export async function getAlertReasons(ctu) { - const alertReasons = await baseMixin.methods.dispatchStoreAction( + const alertReasons = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_ALERT_REASONS_BY_CTU, { ctu: ctu, - } + }, + "schedule" ); return Promise.resolve(alertReasons); diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js index 5ce90638c..270da75f0 100644 --- a/src/layouts/schedule/schedule.spec.js +++ b/src/layouts/schedule/schedule.spec.js @@ -70,6 +70,65 @@ jest.mock("@/mixins/base-mixin.js", () => ({ ]); } }), + dispatchStoreActionWithLogging: jest.fn().mockImplementation((storeAction) => { + if (storeAction === "getShopTimeSlots") { + return { + data: { + estimatedServiceMinutesMinimum: 90, + estimatedServiceMinutesMaximum: 120, + days: [ + { + date: "2023-12-01", + timeSlots: [ + { + id: "06747-01820-S-B*20424*7 AM", + startTime: "07:00", + endTime: "08:00", + offerPremium: false, + }, + ], + }, + ], + }, + }; + } + if (storeAction === "getMobilePremiumFee") { + return Promise.resolve({ + data: { + partNumber: "EARLY BIRD", + description: null, + partType: "EARLY BIRD", + laborAmount: 0, + sellingPrice: 14.99, + kitPrice: 0, + }, + }); + } + if (storeAction === "priceOrderItemsAndSaveServerData") { + return Promise.resolve([ + { + partNumber: "EARLY BIRD", + description: null, + partType: "EARLY BIRD", + laborAmount: 0, + sellingPrice: 14.99, + kitPrice: 0, + }, + ]); + } + if (storeAction === "saveSupportingItemsSuppressingStateResetting") { + return Promise.resolve([ + { + partNumber: "EARLY BIRD", + description: null, + partType: "EARLY BIRD", + laborAmount: 0, + sellingPrice: 14.99, + kitPrice: 0, + }, + ]); + } + }), }, })); @@ -226,10 +285,11 @@ describe("schedule.vue...", () => { ); // Assert - expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledTimes(3); - expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith( + expect(baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledTimes(3); + expect(baseMixin.methods.dispatchStoreActionWithLogging).toHaveBeenCalledWith( "getShopTimeSlots", expect.anything(), + expect.anything(), expect.anything() ); }); diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index f276ea1cd..562077d17 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -168,9 +168,10 @@ const getAvailableDates = async ( const makeParallelCalls = async () => { await Promise.all( storeActionConfigs.map(async (storeAction) => { - const timeSlotsResponse = await baseMixin.methods.dispatchStoreAction( + const timeSlotsResponse = await baseMixin.methods.dispatchStoreActionWithLogging( storeAction.storeAction, storeAction.payload, + "schedule", false ); timeSlotsResponsesData.estimatedServiceMinutesMinimum = @@ -218,17 +219,20 @@ export default { preSelectedDate: preSelectedDate, }); - const premiumFeePromise = baseMixin.methods.dispatchStoreAction( - storeActions.GET_MOBILE_PREMIUM_FEE + const premiumFeePromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_MOBILE_PREMIUM_FEE, + null, + "schedule" ); const premiumFeeWithPricePromise = premiumFeePromise.then((result) => { if (result.data) { - return baseMixin.methods.dispatchStoreAction( + return baseMixin.methods.dispatchStoreActionWithLogging( storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA, { availableLineItems: [result.data], }, + "schedule", false ); } else { diff --git a/src/store/index.js b/src/store/index.js index acdbea86d..b1aa7c790 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -930,11 +930,13 @@ export const actions = { }, // Location API Actions - getAlertReasonsByCtu(context, { ctu }) { + getAlertReasonsByCtu(context, { payload: { ctu }, pageNameToLog }) { return globalMethods.callHttpClient({ method: endpoints.GetAlertReasons.method, endpoint: `${endpoints.GetAlertReasons.url}/${ctu}`, payload: {}, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, @@ -1412,7 +1414,7 @@ export const actions = { }); }, - getMobileTimeSlots(context, { startDate, endDate }) { + getMobileTimeSlots(context, { payload: { startDate, endDate }, pageNameToLog }) { const order = context.state.order; const vehicle = context.state.order.vehicle; let lineItems = [ @@ -1464,6 +1466,8 @@ export const actions = { method: endpoints.GetMobileTimeSlots.method, endpoint: endpoints.GetMobileTimeSlots.url, payload: payload, + logApiCall: true, + pageNameToLog: pageNameToLog, additionalSuccessEventDataHandler: (response) => getTimeSlotsAdditionalEventData( response.data.provisionalTriggers, @@ -1473,13 +1477,15 @@ export const actions = { }); }, - getMobilePremiumFee(context) { + getMobilePremiumFee(context, { pageNameToLog }) { const damageType = context.getters.damage.isRepair ? "Repair" : "Replace"; const paymentType = context.getters.order.payment.isInsurance ? "Insurance" : "Cash"; return globalMethods.callHttpClient({ method: endpoints.GetMobilePremiumFee.method, endpoint: `${endpoints.GetMobilePremiumFee.url}/${paymentType}/${damageType}`, + logApiCall: true, + pageNameToLog: pageNameToLog, }); }, From 7bbda0aed87378de6f4dff4b39fa4fc6cc952205 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 21 Sep 2023 15:47:07 -0400 Subject: [PATCH 14/14] Review --- .../service-package-review.vue | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/layouts/review/review-sections/service-package-review/service-package-review.vue b/src/layouts/review/review-sections/service-package-review/service-package-review.vue index c6bdfa491..398e499e2 100644 --- a/src/layouts/review/review-sections/service-package-review/service-package-review.vue +++ b/src/layouts/review/review-sections/service-package-review/service-package-review.vue @@ -31,9 +31,15 @@ export default { }, methods: { loadInitialData() { - const wipersPromise = baseMixin.methods.dispatchStoreAction(storeActions.GET_WIPERS); - const rainDefensePromise = baseMixin.methods.dispatchStoreAction( - storeActions.GET_RAIN_DEFENSE + const wipersPromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_WIPERS, + null, + "review" + ); + const rainDefensePromise = baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_RAIN_DEFENSE, + null, + "review" ); const promiseResultMap = [