From db9f5f38f70ae484d00690f1c9e9ce883b1b5599 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 09:39:24 -0500 Subject: [PATCH 1/9] Create generic GTM logging method --- src/layouts/confirmation/confirmation.vue | 1 + src/mixins/analytics-mixin.js | 151 ++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 92a86e609..10a10970e 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -136,6 +136,7 @@ export default { vm.lineItems = lineItemsFromSubmittedOrder; vm.vaps = availableVaps; analyticsMixin.methods.pushSubmittedOrderToDataLayer(); + analyticsMixin.methods.pushOrderToDataLayer(); }); }, data() { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index d394190ff..b4e2c786c 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -120,6 +120,157 @@ export default { await this.logPageView(analyticsPageEvents.ENTRY); }, + pushOrderToDataLayer() { + // Get correct order object + const hasSubmittedOrder = store.getters.hasSubmittedOrder; + const order = hasSubmittedOrder ? store.getters.submittedOrder : store.getters.order; + + // Begin assembling payload for data layer + const payload = {}; + + // Service Zip + if ( + order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE && + order.serviceLocation.zipCode + ) { + payload.serviceZipCode = order.serviceLocation.zipCode; + } else if ( + order.serviceLocation.appointmentType && + order.serviceLocation.appointmentType !== AppointmentTypeStrings.MOBILE && + order.serviceLocation.provider.address.zipCode + ) { + payload.serviceZipCode = order.serviceLocation.provider.address.zipCode; + } else { + payload.serviceZipCode = ""; + } + + // Damage Type + if (order.damage.isRepair !== null && order.damage.isRepair !== undefined) { + payload.damageType = order.damage.isRepair ? "repair" : "replace"; + } else { + payload.damageType = ""; + } + + // Account Type + if (order.payment.isInsurance !== null && order.payment.isInsurance !== undefined) { + payload.accountType = order.payment.isInsurance ? "insurance" : "cash"; + } else { + payload.accountType = ""; + } + + // Promo Codes + const promos = order.lineItems.promos ?? []; + if (promos.length === 0) { + payload.promoCodes = ""; + } else { + const promoCodes = promos.map((promo) => promo.promoCode); + const promoString = promoCodes.reduce((prev, next) => `${prev},${next}`); + payload.promoCodes = promoString; + } + + // Vehicle info + if (order.vehicle.year !== null && order.vehicle.year !== undefined) { + // Ensure cast to string. + payload.vehicleYear = `${order.vehicle.year}`; + } else { + payload.vehicleYear = ""; + } + + if (order.vehicle.make) { + payload.vehicleMake = order.vehicle.make; + } else { + payload.vehicleMake = ""; + } + + if (order.vehicle.model) { + payload.vehicleModel = order.vehicle.model; + } else { + payload.vehicleModel = ""; + } + + if (order.vehicle.style) { + payload.vehicleStyle = order.vehicle.style; + } else { + payload.vehicleStyle = ""; + } + + // Glass pieces + const glass = order.damage.glassToReplace ?? []; + if (glass.length === 0) { + payload.glassToReplace = ""; + } else { + const glassNames = glass.map((g) => `${g.glassLocation}/${g.glassName}`); + const glassString = glassNames.reduce((prev, next) => `${prev},${next}`); + + payload.glassToReplace = glassString; + } + + // Work Order Id + if (order.workOrderId) { + payload.workOrderId = parseInt(order.workOrderId); + } else { + payload.workOrderId = ""; + } + + // Provider Ctu + if (order.serviceLocation.zipCodeCtu) { + payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu); + } else { + payload.providerCtu = ""; + } + + // Work Order Number + if (order.workOrderNumber) { + payload.orderNumber = order.workOrderNumber; + } else { + payload.orderNumber = ""; + } + + // Pricing + // Only fire for completed orders? + if (hasSubmittedOrder) { + const lineItems = order.lineItems ?? {}; + const combinedLineItems = [ + ...(lineItems.glassParts ?? []), + ...(lineItems.supportingItems ?? []), + ...(lineItems.vaps ?? []), + ...(lineItems.promos ?? []), + ]; + + const subtotal = baseMixin.methods + .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) + .toFixed(2); + + const total = baseMixin.methods + .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, true) + .toFixed(2); + + payload.priceTotal = parseFloat(total); + payload.priceSubTotal = parseFloat(subtotal); + } else { + payload.priceTotal = ""; + payload.priceSubTotal = ""; + } + + // Recalibration + if (hasSubmittedOrder) { + payload.isRecalibrationOnOrder = store.getters.isRecalibrationOnSubmittedOrder; + } else { + payload.isRecalibrationOnOrder = store.getters.isRecalibrationOnOrder; + } + + // Appointment Type + if (order.serviceLocation.appointmentType) { + payload.appointmentType = order.serviceLocation.appointmentType; + } else { + payload.appointmentType = ""; + } + + payload.isNew = true; + + pushToDataLayerIfDefined(payload); + }, + pushSubmittedOrderToDataLayer() { // check if submitted order exists; exit if not. const hasSubmittedOrder = store.getters.hasSubmittedOrder; From 0514dc33870664c6a41c8c20d462e9731102d098 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 13:01:29 -0500 Subject: [PATCH 2/9] Helper lemma for verifying existence of fields --- src/mixins/analytics-mixin.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index b4e2c786c..b7bc8ab31 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -121,6 +121,9 @@ export default { }, pushOrderToDataLayer() { + // helper check for if an object is defined (but maybe falsey) + const isDefined = (x) => x !== null && x !== undefined; + // Get correct order object const hasSubmittedOrder = store.getters.hasSubmittedOrder; const order = hasSubmittedOrder ? store.getters.submittedOrder : store.getters.order; @@ -131,13 +134,13 @@ export default { // Service Zip if ( order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE && - order.serviceLocation.zipCode + isDefined(order.serviceLocation.zipCode) ) { payload.serviceZipCode = order.serviceLocation.zipCode; } else if ( - order.serviceLocation.appointmentType && + isDefined(order.serviceLocation.appointmentType) && order.serviceLocation.appointmentType !== AppointmentTypeStrings.MOBILE && - order.serviceLocation.provider.address.zipCode + isDefined(order.serviceLocation.provider.address.zipCode) ) { payload.serviceZipCode = order.serviceLocation.provider.address.zipCode; } else { @@ -145,14 +148,14 @@ export default { } // Damage Type - if (order.damage.isRepair !== null && order.damage.isRepair !== undefined) { + if (isDefined(order.damage.isRepair)) { payload.damageType = order.damage.isRepair ? "repair" : "replace"; } else { payload.damageType = ""; } // Account Type - if (order.payment.isInsurance !== null && order.payment.isInsurance !== undefined) { + if (isDefined(order.payment.isInsurance)) { payload.accountType = order.payment.isInsurance ? "insurance" : "cash"; } else { payload.accountType = ""; @@ -169,26 +172,26 @@ export default { } // Vehicle info - if (order.vehicle.year !== null && order.vehicle.year !== undefined) { + if (isDefined(order.vehicle.year)) { // Ensure cast to string. payload.vehicleYear = `${order.vehicle.year}`; } else { payload.vehicleYear = ""; } - if (order.vehicle.make) { + if (isDefined(order.vehicle.make)) { payload.vehicleMake = order.vehicle.make; } else { payload.vehicleMake = ""; } - if (order.vehicle.model) { + if (isDefined(order.vehicle.model)) { payload.vehicleModel = order.vehicle.model; } else { payload.vehicleModel = ""; } - if (order.vehicle.style) { + if (isDefined(order.vehicle.style)) { payload.vehicleStyle = order.vehicle.style; } else { payload.vehicleStyle = ""; @@ -206,21 +209,21 @@ export default { } // Work Order Id - if (order.workOrderId) { + if (isDefined(order.workOrderId)) { payload.workOrderId = parseInt(order.workOrderId); } else { payload.workOrderId = ""; } // Provider Ctu - if (order.serviceLocation.zipCodeCtu) { + if (isDefined(order.serviceLocation.zipCodeCtu)) { payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu); } else { payload.providerCtu = ""; } // Work Order Number - if (order.workOrderNumber) { + if (isDefined(order.workOrderNumber)) { payload.orderNumber = order.workOrderNumber; } else { payload.orderNumber = ""; @@ -260,7 +263,7 @@ export default { } // Appointment Type - if (order.serviceLocation.appointmentType) { + if (isDefined(order.serviceLocation.appointmentType)) { payload.appointmentType = order.serviceLocation.appointmentType; } else { payload.appointmentType = ""; From 808693b443b839e6276434209772b29acbceb511 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 13:59:21 -0500 Subject: [PATCH 3/9] Clarify Falsy checks --- src/mixins/analytics-mixin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index b7bc8ab31..d0155b0d2 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -209,7 +209,7 @@ export default { } // Work Order Id - if (isDefined(order.workOrderId)) { + if (order.workOrderId) { payload.workOrderId = parseInt(order.workOrderId); } else { payload.workOrderId = ""; @@ -223,7 +223,7 @@ export default { } // Work Order Number - if (isDefined(order.workOrderNumber)) { + if (order.workOrderNumber) { payload.orderNumber = order.workOrderNumber; } else { payload.orderNumber = ""; From fbdea3582f1944f909f423e85330f62b5f1fb15f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 13:59:35 -0500 Subject: [PATCH 4/9] Trigger on every navigation --- src/layouts/confirmation/confirmation.vue | 1 - src/router/index.js | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 10a10970e..92a86e609 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -136,7 +136,6 @@ export default { vm.lineItems = lineItemsFromSubmittedOrder; vm.vaps = availableVaps; analyticsMixin.methods.pushSubmittedOrderToDataLayer(); - analyticsMixin.methods.pushOrderToDataLayer(); }); }, data() { diff --git a/src/router/index.js b/src/router/index.js index 4a13a8fc7..d7eee07ea 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -220,6 +220,9 @@ router.afterEach(async (to, from) => { // Push experiments to Data Layer analyticsMixin.methods.pushExperimentsToDataLayer(); + + // Push current order status to Data Layer + analyticsMixin.methods.pushOrderToDataLayer(); }); router.navigateWithoutSaving = ( From 5800d00839829a6e0b453b64ba207850bd3cbb6f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 14:48:50 -0500 Subject: [PATCH 5/9] Calculate total + subtotal as early as available --- src/mixins/analytics-mixin.js | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index d0155b0d2..33fe5b34d 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -231,28 +231,45 @@ export default { // Pricing // Only fire for completed orders? - if (hasSubmittedOrder) { - const lineItems = order.lineItems ?? {}; - const combinedLineItems = [ - ...(lineItems.glassParts ?? []), - ...(lineItems.supportingItems ?? []), - ...(lineItems.vaps ?? []), - ...(lineItems.promos ?? []), - ]; + const lineItems = order.lineItems ?? {}; + const combinedLineItems = [ + ...(lineItems.glassParts ?? []), + ...(lineItems.supportingItems ?? []), + ...(lineItems.vaps ?? []), + ...(lineItems.promos ?? []), + ]; + + const isPricingAvailable = + combinedLineItems.length > 0 && + combinedLineItems.every( + (lineItem) => + isDefined(lineItem.kitPrice) && + isDefined(lineItem.laborAmount) && + isDefined(lineItem.sellingPrice) + ); + const isTaxAvailable = + isPricingAvailable && + combinedLineItems.every((lineItem) => isDefined(lineItem.salesTax)); + + if (isPricingAvailable) { const subtotal = baseMixin.methods .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) .toFixed(2); + payload.priceSubTotal = parseFloat(subtotal); + } else { + payload.priceSubTotal = ""; + } + + if (isTaxAvailable) { const total = baseMixin.methods .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, true) .toFixed(2); payload.priceTotal = parseFloat(total); - payload.priceSubTotal = parseFloat(subtotal); } else { payload.priceTotal = ""; - payload.priceSubTotal = ""; } // Recalibration From a324bba65d2ef06716e3546f7da6905ce4aebd13 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 14 Feb 2024 15:26:23 -0500 Subject: [PATCH 6/9] Remove unneeded code --- src/layouts/confirmation/confirmation.vue | 1 - src/mixins/analytics-mixin.js | 76 ----------------------- 2 files changed, 77 deletions(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 92a86e609..54e40214b 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -135,7 +135,6 @@ export default { vm.setCmsContent(resultMap.cmsContent); vm.lineItems = lineItemsFromSubmittedOrder; vm.vaps = availableVaps; - analyticsMixin.methods.pushSubmittedOrderToDataLayer(); }); }, data() { diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 33fe5b34d..31d17fbb3 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -286,82 +286,6 @@ export default { payload.appointmentType = ""; } - payload.isNew = true; - - pushToDataLayerIfDefined(payload); - }, - - pushSubmittedOrderToDataLayer() { - // check if submitted order exists; exit if not. - const hasSubmittedOrder = store.getters.hasSubmittedOrder; - - if (!hasSubmittedOrder) { - return; - } - - const order = store.getters.submittedOrder; - - // assemble data for payload - // // reduce promocode array - const promos = order.lineItems.promos ?? []; - const promoCodes = promos.map((promo) => promo.promoCode); - const promoString = - promoCodes.length === 0 ? "" : promoCodes.reduce((prev, next) => `${prev},${next}`); - - // // reduce glass array - const glassToReplace = order.damage.glassToReplace ?? []; - const glassToReplaceNames = glassToReplace.map( - (glassPiece) => `${glassPiece.glassLocation}/${glassPiece.glassName}` - ); - const glassString = - glassToReplaceNames.length === 0 - ? "" - : glassToReplaceNames.reduce((prev, next) => `${prev},${next}`); - - // // calculate subtotal - const lineItems = order.lineItems; - const combinedLineItems = [ - ...(lineItems.glassParts ?? []), - ...(lineItems.supportingItems ?? []), - ...(lineItems.vaps ?? []), - ...(lineItems.promos ?? []), - ]; - const subtotal = baseMixin.methods - .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) - .toFixed(2); - - // // get correct zip code - const providerZip = order.serviceLocation.provider.address.zipCode; - const serviceZip = - order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE - ? order.serviceLocation.zipCode - : providerZip; - - // // calculate total - const total = baseMixin.methods - .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, true) - .toFixed(2); - - const payload = { - serviceZipCode: serviceZip, - damageType: order.damage.isRepair ? "repair" : "replace", - accountType: order.payment.isInsurance ? "insurance" : "cash", - promoCodes: promoString, - vehicleYear: `${order.vehicle.year}`, - vehicleMake: order.vehicle.make, - vehicleModel: order.vehicle.model, - vehicleStyle: order.vehicle.style, - glassToReplace: glassString, - workOrderId: parseInt(order.workOrderId), - providerCtu: parseInt(order.serviceLocation.zipCodeCtu), - orderNumber: order.workOrderNumber, - priceTotal: parseFloat(total), - priceSubTotal: parseFloat(subtotal), - isRecalibrationOnOrder: store.getters.isRecalibrationOnSubmittedOrder, - appointmentType: order.serviceLocation.appointmentType, - }; - - // push to data layer. pushToDataLayerIfDefined(payload); }, From 026bb5383f06d908384598cf939efd88763bb3df Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 15 Feb 2024 11:59:01 -0500 Subject: [PATCH 7/9] Ensure parsed numbers are not NaN before logging. --- src/mixins/analytics-mixin.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 31d17fbb3..cbae280d1 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -210,14 +210,24 @@ export default { // Work Order Id if (order.workOrderId) { - payload.workOrderId = parseInt(order.workOrderId); + const parsedId = parseInt(order.workOrderId); + if(!isNaN(parsedId)) { + payload.workOrderId = parsedId; + } else { + payload.workOrderId = ""; + } } else { payload.workOrderId = ""; } // Provider Ctu if (isDefined(order.serviceLocation.zipCodeCtu)) { - payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu); + const parsedCtu = parseInt(order.serviceLocation.zipCodeCtu); + if(!isNaN(parsedCtu)) { + payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu); + } else { + payload.providerCtu = ""; + } } else { payload.providerCtu = ""; } From c0a26b2a95a3f928eac487e593193b5431d0788b Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 15 Feb 2024 12:00:51 -0500 Subject: [PATCH 8/9] Update unit tests --- src/mixins/analytics-mixin.spec.js | 247 ++++++++++++++++++++++++++--- 1 file changed, 225 insertions(+), 22 deletions(-) diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index ff6c30e7e..42aba5f31 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -38,27 +38,38 @@ const parts = { requiresRecalibration: true, salesTax: 63.86, sellingPrice: 791.46, + kitPrice: 0, + laborAmount: 0, }, frontWipers: { name: "front wipers", partNumber: "SBB16", description: "SAFELITE BEAM BLADE 16", partType: "FRONT WIPER", - price: 32.64, + sellingPrice: 32.64, + kitPrice: 0, + laborAmount: 0, + salesTax: 1, }, rearWipers: { name: "rear wipers", partNumber: "SBBR12A", description: "SAFELITE REAR BLADE 12A", partType: "REAR WIPER", - price: 24.48, + sellingPrice: 24.48, + kitPrice: 0, + laborAmount: 0, + salesTax: 2, }, rainDefense: { name: "rain defense", partNumber: "RAIN DEFENSE", description: null, partType: "RAIN DEFENSE", - price: 35.5, + sellingPrice: 35.5, + kitPrice: 0, + laborAmount: 0, + salesTax: 0, }, }; @@ -324,10 +335,10 @@ describe("analyticsMixin.js", () => { ]); }); - describe("pushSubmittedOrderToDataLayer", () => { + describe("pushOrderToDataLayer", () => { beforeEach(() => { - store.getters.hasSubmittedOrder = true; - store.getters.submittedOrder = { + store.getters.hasSubmittedOrder = false; + store.getters.order = { vehicle: { year: "2020", make: "acura", @@ -342,8 +353,8 @@ describe("analyticsMixin.js", () => { address2: "add2", city: "city", state: "state", - zipCode: "zip", - zipCodeCtu: "zipCtu", + zipCode: "11111", + zipCodeCtu: "11110", appointmentType: "IN_SHOP", isVehicleProtected: true, provider: { @@ -352,8 +363,8 @@ describe("analyticsMixin.js", () => { streetAddress: "add3", city: "city2", state: "state2", - zipCode: "zip2", - zipCodeCtu: "zipCtu2", + zipCode: "22222", + zipCodeCtu: "22220", }, }, techNotes: "", @@ -368,13 +379,28 @@ describe("analyticsMixin.js", () => { damage: { isRepair: false, numberOfChips: null, - glassToReplace: [{ glassName: "single", location: "windshield" }], + glassToReplace: [{ glassName: "single", glassLocation: "windshield" }], }, lineItems: { glassParts: [parts.windshield], supportingItems: [], vaps: [parts.frontWipers], - promos: [{ promoCode: "promoTEST" }, { promoCode: "promoTEST2" }], + promos: [ + { + promoCode: "promoTEST", + kitPrice: 0, + sellingPrice: 0, + laborAmount: 0, + salesTax: 0, + }, + { + promoCode: "promoTEST2", + kitPrice: 0, + sellingPrice: 0, + laborAmount: 0, + salesTax: 0, + }, + ], }, payment: { isInsurance: false, @@ -397,6 +423,8 @@ describe("analyticsMixin.js", () => { workOrderNumber: "01820-111111", workOrderId: "222222222222", }; + store.getters.isRecalibrationOnOrder = true; + store.getters.isRecalibrationOnSubmittedOrder = false; }); test("Pushes to data layer if nominal", () => { @@ -408,28 +436,203 @@ describe("analyticsMixin.js", () => { }; // Act - analyticsMixin.methods.pushSubmittedOrderToDataLayer(); + analyticsMixin.methods.pushOrderToDataLayer(); // Assert expect(mockDataLayerFn).toHaveBeenCalled(); }); - test("Does not push to data layer if no submitted order available.", () => { + test("Pushes populated data to data layer", () => { // Arrange - store.getters.hasSubmittedOrder = false; - store.getters.submittedOrder = undefined; + window.dataLayer = []; - const mockDataLayerFn = jest.fn(); + // Act + analyticsMixin.methods.pushOrderToDataLayer(); - window.dataLayer = { - push: mockDataLayerFn, + const result = window.dataLayer[0]; + + // Assert + console.log(result); + const allFieldsPopulated = Object.keys(result).every( + (key) => result[key] === false || !!result[key] + ); + expect(allFieldsPopulated).toBe(true); + }); + + test("Pushes correct data when submitted order is present", () => { + // Arrange + window.dataLayer = []; + store.getters.hasSubmittedOrder = true; + store.getters.submittedOrder = store.getters.order; + store.getters.order = { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + vin: null, + }, + serviceLocation: { + address: null, + address2: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + appointmentType: null, + isVehicleProtected: null, + provider: { + providerNumber: null, + address: { + streetAddress: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + }, + }, + techNotes: null, + }, + customer: { + firstName: null, + lastName: null, + emailAddress: null, + phoneNumber: null, + isSmsOptIn: null, + }, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + }, + lineItems: { + glassParts: null, + supportingItems: null, + vaps: null, + promos: null, + }, + payment: { + isInsurance: null, + insuranceCoverage: { + isVerified: null, + coverageStatus: null, + coverageVerificationType: null, + }, + isPia: null, + piaType: null, + inactivePromos: null, + }, + schedule: { + date: null, + startTime: null, + endTime: null, + jobMinMinutes: null, + jobMaxMinutes: null, + }, + workOrderNumber: null, + workOrderId: null, }; // Act - analyticsMixin.methods.pushSubmittedOrderToDataLayer(); + analyticsMixin.methods.pushOrderToDataLayer(); + + const result = window.dataLayer[0]; // Assert - expect(mockDataLayerFn).not.toHaveBeenCalled(); + console.log(result); + const allFieldsPopulated = Object.keys(result).every( + (key) => result[key] === false || !!result[key] + ); + expect(allFieldsPopulated).toBe(true); + }); + + test("Pushes default values when data is missing", () => { + // Arrange + window.dataLayer = []; + store.getters.order = { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + vin: null, + }, + serviceLocation: { + address: null, + address2: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + appointmentType: null, + isVehicleProtected: null, + provider: { + providerNumber: null, + address: { + streetAddress: null, + city: null, + state: null, + zipCode: null, + zipCodeCtu: null, + }, + }, + techNotes: null, + }, + customer: { + firstName: null, + lastName: null, + emailAddress: null, + phoneNumber: null, + isSmsOptIn: null, + }, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + }, + lineItems: { + glassParts: null, + supportingItems: null, + vaps: null, + promos: null, + }, + payment: { + isInsurance: null, + insuranceCoverage: { + isVerified: null, + coverageStatus: null, + coverageVerificationType: null, + }, + isPia: null, + piaType: null, + inactivePromos: null, + }, + schedule: { + date: null, + startTime: null, + endTime: null, + jobMinMinutes: null, + jobMaxMinutes: null, + }, + workOrderNumber: null, + workOrderId: null, + }; + + // Act + analyticsMixin.methods.pushOrderToDataLayer(); + + const result = window.dataLayer[0]; + + // Assert + console.log(result); + const allFieldsPopulatedOrDefault = Object.keys(result).every( + (key) => result[key] === false || !!result[key] || result[key] === "" + ); + expect(allFieldsPopulatedOrDefault).toBe(true); }); test("Glass and Promo strings correctly formatted", () => { @@ -437,7 +640,7 @@ describe("analyticsMixin.js", () => { window.dataLayer = []; // Act - analyticsMixin.methods.pushSubmittedOrderToDataLayer(); + analyticsMixin.methods.pushOrderToDataLayer(); // Assert const glassString = window.dataLayer[0].glassToReplace; From b9fc0b2c8b5f5ef088e35111d3b6d5eeb8040fe7 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 15 Feb 2024 12:14:17 -0500 Subject: [PATCH 9/9] Formatting --- src/mixins/analytics-mixin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index cbae280d1..cfa68c82c 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -211,7 +211,7 @@ export default { // Work Order Id if (order.workOrderId) { const parsedId = parseInt(order.workOrderId); - if(!isNaN(parsedId)) { + if (!isNaN(parsedId)) { payload.workOrderId = parsedId; } else { payload.workOrderId = ""; @@ -223,7 +223,7 @@ export default { // Provider Ctu if (isDefined(order.serviceLocation.zipCodeCtu)) { const parsedCtu = parseInt(order.serviceLocation.zipCodeCtu); - if(!isNaN(parsedCtu)) { + if (!isNaN(parsedCtu)) { payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu); } else { payload.providerCtu = "";