From 2fb672604477c3c54a772a97b8ef9d6e098fee3e Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 19 Sep 2024 16:11:08 +0530 Subject: [PATCH 1/4] CSR-1629 CJ Pixel tracking and product array for CJ conversion tag and eCommerceCart for subTotal --- src/mixins/analytics-mixin.js | 249 ++++++++++++++++++++++++++++++++++ src/router/index.js | 17 +++ 2 files changed, 266 insertions(+) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 9ce6874ae..dc4da7e1b 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -381,6 +381,234 @@ export default { }); }, + pushProductArrayToDataLayer() { + // Get correct order object + const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + + if (hasSubmittedOrder) { + var lineItems = submittedOrder.lineItems ? submittedOrder.lineItems : {}; + + // combine all line items + var combinedLineItems = [ + ...(lineItems.glassParts ?? []), + ...(lineItems.supportingItems ?? []), + ...(lineItems.vaps ?? []), + ...(lineItems.promos ?? []), + ]; + + //Get child parts + combinedLineItems = flattenArray(combinedLineItems); + + var products = []; + var discount = 0; + var coupon = ""; + var subTotal = 0; + for (var i = 0; i < combinedLineItems.length; i++) { + let part = combinedLineItems[i]; + let productSku = part.partNumber; + let productType = part.partType; + let promoCode = part.promoCode; + let productPrice = baseMixin.methods + .getTotalPriceOfAllLineItemsAndChildParts([part], false) + .toFixed(2); + + if (productSku == "DISCOUNT") { + if (coupon) { + coupon += ","; + } + coupon += productSku; + discount = discount + parseFloat(productPrice) * -1; + } else { + products.push({ + productType: productType, + productSku: productSku, + productPrice: productPrice.toString(), + productQuantity: "1", + }); + subTotal += parseFloat(productPrice); + } + } + pushToDataLayerIfDefined({ + productArray: { + coupon: coupon, + discount: discount.toString(), + subTotal: subTotal.toString(), + products: products, + }, + }); + } + }, + + pushECommerceCartToDataLayer() { + const isDefined = (x) => x !== null && x !== undefined; + // Get correct order object + const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + if (hasSubmittedOrder) { + var lineItems = submittedOrder.lineItems ? submittedOrder.lineItems : {}; + var supportingItems = + submittedOrder.lineItems && submittedOrder.lineItems.supportingItems + ? submittedOrder.lineItems.supportingItems + : []; + var insurance = submittedOrder.payment && submittedOrder.payment.isInsurance; + var itac = submittedOrder.policy && submittedOrder.policy.isItac; + var nocomp = submittedOrder.policy && submittedOrder.policy.isNoComp; + + var recalLineItem = supportingItems.filter(function (lineItem) { + return lineItem.partType.indexOf("RECALIBRATION") !== -1; + }); + var disposalFee = supportingItems.filter(function (lineItem) { + return lineItem.partType.indexOf("DISPOSAL FEE") !== -1; + }); + var mobileFee = supportingItems.filter(function (lineItem) { + return lineItem.partType.indexOf("MOBILE FEE") !== -1; + }); + var repairFee = supportingItems.filter(function (lineItem) { + return lineItem.partType.indexOf("REPAIR FEE") !== -1; + }); + + var vaps = + submittedOrder.lineItems && submittedOrder.lineItems.vaps + ? submittedOrder.lineItems.vaps + : []; + var wipers = vaps.filter(function (lineItem) { + return ( + lineItem.partType.indexOf("FRONT WIPER") !== -1 || + lineItem.partType.indexOf("REAR WIPER") !== -1 + ); + }); + var rainDefense = vaps.filter(function (lineItem) { + return lineItem.partType.indexOf("RAIN DEFENSE") !== -1; + }); + + // Combine line items + var combinedLineItems = []; + if (lineItems.glassParts) { + combinedLineItems = combinedLineItems.concat(lineItems.glassParts); + } + if (recalLineItem) { + combinedLineItems = combinedLineItems.concat(recalLineItem); + } + if (disposalFee) { + combinedLineItems = combinedLineItems.concat(disposalFee); + } + if (mobileFee && !(insurance && !itac && !nocomp)) { + combinedLineItems = combinedLineItems.concat(mobileFee); + } + if (repairFee) { + combinedLineItems = combinedLineItems.concat(repairFee); + } + if (wipers) { + combinedLineItems = combinedLineItems.concat(wipers); + } + if (rainDefense) { + combinedLineItems = combinedLineItems.concat(rainDefense); + } + + //Remove child Parts if any + combinedLineItems.forEach((lineItem) => { + lineItem.childParts = []; + }); + + var isPricingAvailable = + combinedLineItems.length > 0 && + combinedLineItems.every(function (lineItem) { + return ( + isDefined(lineItem.kitPrice) && + isDefined(lineItem.laborAmount) && + isDefined(lineItem.sellingPrice) + ); + }); + let subtotal = 0; + if (isPricingAvailable) { + subtotal = baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts( + combinedLineItems, + false + ); + } + pushToDataLayerIfDefined({ + eCommerceCart: { products: combinedLineItems, subTotal: parseInt(subtotal) }, + }); + } + }, + + pushCommissionJunctionGtmDataToDataLayer() { + // helper check for if an object is defined (but maybe falsey) + const isDefined = (x) => x !== null && x !== undefined; + let repairReplace = ""; + let coupons = ""; + let refSequenceNum = ""; + let accountType = ""; + let amount = 0; + let cjEvent = ""; + if (store.getters.applicationUser.affiliateCookies) { + const affiliateCookies = store.getters.applicationUser.affiliateCookies; + var cookieArray = []; + affiliateCookies.forEach((item) => { + let cookieObject = convertCookieStringToObject(item); + cookieArray.push(cookieObject); + }); + const sortedCookies = cookieArray.sort( + (a, b) => + new Date(b.timestamp.replace("/", "T")) - + new Date(a.timestamp.replace("/", "T")) + ); + cjEvent = sortedCookies?.[0]?.tagEvent; + const hasSubmittedOrder = baseMixin.methods.hasSubmittedOrder(); + const submittedOrder = baseMixin.methods.getSubmittedOrder(); + + if (hasSubmittedOrder) { + repairReplace = submittedOrder.damage.isRepair ? "Repair" : "Replace"; + const promos = submittedOrder.lineItems.promos ?? []; + if (promos.length === 0) { + coupons = ""; + } else { + const promoCodes = promos.map((promo) => promo.promoCode); + const promoString = promoCodes.reduce((prev, next) => `${prev}_${next}`); + coupons = promoString; + } + refSequenceNum = submittedOrder.referralSequenceNumber; + } + if (isDefined(submittedOrder.payment.isInsurance)) { + accountType = submittedOrder.payment.isInsurance ? "insurance" : "cash"; + } else { + accountType = ""; + } + const lineItems = submittedOrder.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) + ); + if (accountType == "cash" && isPricingAvailable) { + const quoteAmountWithDiscount = baseMixin.methods + .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) + .toFixed(2); + amount = parseFloat(quoteAmountWithDiscount); + } + } + pushToDataLayerIfDefined({ + commissionJunctionGtmData: { + cj_commission_junction_event: cjEvent, + cj_referral_sequence_number: refSequenceNum, + cj_amount: amount.toString(), + cj_repair_replace: repairReplace, + cj_coupon: coupons, + }, + }); + }, + prependActionToMethod(object, method, actionToPrepend) { const baseMethodName = method.name.startsWith("bound ") ? method.name.substring(6) @@ -493,3 +721,24 @@ function getValueToLog(value, valueToLogType) { } return value; } + +function flattenArray(arr) { + let result = []; + arr.forEach((item) => { + result.push(item); + if (item.childParts) { + result = result.concat(item.childParts); + delete item.childParts; // Remove childParts after flattening + } + }); + return result; +} + +function convertCookieStringToObject(cookieValue) { + const cookieObject = cookieValue.split("&").reduce((acc, pair) => { + const [key, value] = pair.split("="); + acc[key] = value; + return acc; + }, {}); + return cookieObject; +} diff --git a/src/router/index.js b/src/router/index.js index 23b61282c..cbd2d2eab 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -145,6 +145,12 @@ const routes = [ await runExperiments(to.query.fmgPage); + //Affiliate Cookies + const affiliateCookies = getAffiliateCookies(); + if (affiliateCookies != null && affiliateCookies.length > 0) { + store.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies); + } + setupAdvertiserTracking(); // Process funnel cookie. updateOrCreateFunnelCookie(); @@ -307,6 +313,17 @@ router.afterEach(async (to, from) => { // Push current order status to Data Layer analyticsMixin.methods.pushOrderToDataLayer(); + + if (to.query.fmgPage == fmgPageValues.CONFIRMATION) { + //Push Product Array to Data Layer + analyticsMixin.methods.pushProductArrayToDataLayer(); + + //Push Ecommerce Cart to Data Layer + analyticsMixin.methods.pushECommerceCartToDataLayer(); + + //Push Commission Junction Gtm Data To Data Layer + analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer(); + } }); router.navigateWithoutSaving = ( From 315acd49a7e4a6cd3659d379769a5b2228baaaab Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 19 Sep 2024 19:03:59 +0530 Subject: [PATCH 2/4] CSR-1629 unit test cases --- src/mixins/analytics-mixin.js | 55 ++++---- src/mixins/analytics-mixin.spec.js | 196 +++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 27 deletions(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index dc4da7e1b..615e5ecf6 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -546,7 +546,7 @@ export default { const affiliateCookies = store.getters.applicationUser.affiliateCookies; var cookieArray = []; affiliateCookies.forEach((item) => { - let cookieObject = convertCookieStringToObject(item); + let cookieObject = convertCookieStringToObject(item.CookieValue); cookieArray.push(cookieObject); }); const sortedCookies = cookieArray.sort( @@ -569,33 +569,34 @@ export default { coupons = promoString; } refSequenceNum = submittedOrder.referralSequenceNumber; - } - if (isDefined(submittedOrder.payment.isInsurance)) { - accountType = submittedOrder.payment.isInsurance ? "insurance" : "cash"; - } else { - accountType = ""; - } - const lineItems = submittedOrder.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) - ); - if (accountType == "cash" && isPricingAvailable) { - const quoteAmountWithDiscount = baseMixin.methods - .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) - .toFixed(2); - amount = parseFloat(quoteAmountWithDiscount); + if (isDefined(submittedOrder.payment.isInsurance)) { + accountType = submittedOrder.payment.isInsurance ? "insurance" : "cash"; + } else { + accountType = ""; + } + const lineItems = submittedOrder.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) + ); + if (accountType == "cash" && isPricingAvailable) { + const quoteAmountWithDiscount = baseMixin.methods + .getTotalPriceOfAllLineItemsAndChildParts(combinedLineItems, false) + .toFixed(2); + amount = parseFloat(quoteAmountWithDiscount); + } } } pushToDataLayerIfDefined({ diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index e56840c61..6266b97a1 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -1,4 +1,6 @@ import analyticsMixin from "@/mixins/analytics-mixin"; +import baseMixin from "@/mixins/base-mixin"; +import { shallowMount } from "@vue/test-utils"; import { setupMocksForJsFiles, setupCookies, @@ -851,4 +853,198 @@ describe("analyticsMixin.js", () => { expect(mocks.baseMixin.methods.dispatchStoreAction).toBeCalled(); }); }); + describe("push product array and ecommerce cart to data layer", () => { + let wrapper; + + beforeEach(() => { + wrapper = shallowMount(analyticsMixin); + }); + + it("should push product array to data layer correctly", () => { + // Mock the methods + baseMixin.methods.hasSubmittedOrder = jest.fn(); + baseMixin.methods.getSubmittedOrder = jest.fn(); + baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts = jest.fn(); + baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + baseMixin.methods.getSubmittedOrder.mockReturnValue({ + lineItems: { + glassParts: [{ partNumber: "GP1", partType: "glass" }], + supportingItems: [{ partNumber: "SI1", partType: "support" }], + vaps: [{ partNumber: "VAP1", partType: "vap" }], + promos: [{ partNumber: "DISCOUNT", partType: "promo", promoCode: "PROMO4" }], + }, + }); + baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts.mockReturnValue(100); + + // Call the function + wrapper.vm.pushProductArrayToDataLayer(); + + // Assertions + expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); + expect(baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); + expect(baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts).toHaveBeenCalled(); + }); + it("should push eCommerce cart to data layer correctly", () => { + // Mock the methods + (baseMixin.methods.hasSubmittedOrder = jest.fn()), + (baseMixin.methods.getSubmittedOrder = jest.fn()), + baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + baseMixin.methods.getSubmittedOrder.mockReturnValue({ + lineItems: { + supportingItems: [ + { partType: "RECALIBRATION", partNumber: "R1" }, + { partType: "DISPOSAL FEE", partNumber: "D1" }, + { partType: "MOBILE FEE", partNumber: "M1" }, + { partType: "REPAIR FEE", partNumber: "RF1" }, + ], + vaps: [{ partType: "FRONT WIPER", partNumber: "FW1" }], + }, + payment: { isInsurance: true }, + policy: { isItac: true, isNoComp: false }, + }); + + // Call the function + wrapper.vm.pushECommerceCartToDataLayer(); + + // Assertions + expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); + expect(baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); + expect(baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts).toHaveBeenCalled(); + }); + }); + + describe("pushCommissionJunctionGtmDataToDataLayer", () => { + it("should handle empty affiliateCookies", () => { + store.getters = { + applicationUser: { + affiliateCookies: [], + }, + }; + + baseMixin.methods.hasSubmittedOrder = jest.fn(); + baseMixin.methods.hasSubmittedOrder.mockReturnValue(false); + const result = analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer(); + expect(result).toBeUndefined(); + }); + + test("Pushes populated data to data layer", () => { + baseMixin.methods.hasSubmittedOrder = jest.fn(); + baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + baseMixin.methods.getSubmittedOrder = jest.fn(); + baseMixin.methods.getSubmittedOrder.mockReturnValue({ + vehicle: { + year: "2020", + make: "acura", + model: "mdx", + style: "4-door sedan", + carId: "dummyCarId", + category: "dummyCategory", + vin: "dummyVin", + }, + serviceLocation: { + address: "add1", + address2: "add2", + city: "city", + state: "state", + zipCode: "11111", + zipCodeCtu: "11110", + appointmentType: "IN_SHOP", + isVehicleProtected: true, + provider: { + providerNumber: 2, + address: { + streetAddress: "add3", + city: "city2", + state: "state2", + zipCode: "22222", + zipCodeCtu: "22220", + }, + }, + techNotes: "", + }, + customer: { + firstName: "first", + lastName: "last", + emailAddress: "builddigitaltest@safelite.com", + phoneNumber: "555-555-5555", + isSmsOptIn: false, + }, + damage: { + isRepair: false, + numberOfChips: null, + glassToReplace: [{ glassName: "single", glassLocation: "windshield" }], + }, + lineItems: { + glassParts: [parts.windshield], + supportingItems: [], + vaps: [parts.frontWipers], + promos: [ + { + promoCode: "promoTEST", + kitPrice: 0, + sellingPrice: 0, + laborAmount: 0, + salesTax: 0, + }, + { + promoCode: "promoTEST2", + kitPrice: 0, + sellingPrice: 0, + laborAmount: 0, + salesTax: 0, + }, + ], + }, + payment: { + isInsurance: false, + insuranceCoverage: { + isVerified: null, + coverageStatus: null, + coverageVerificationType: null, + }, + isPia: true, + piaType: "Afterpay", + inactivePromos: [], + }, + schedule: { + date: "date", + startTime: "start", + endTime: "end", + jobMinMinutes: "30", + jobMaxMinutes: "45", + }, + workOrderNumber: "01820-111111", + workOrderId: "222222222222", + referralSequenceNumber: "1111111", + }); + store.getters = { + applicationUser: { + affiliateCookies: [ + { + CookieName: "Cookie1", + CookieValue: "timestamp=2023-09-18/12:00:00&tagEvent=event1", + }, + { + CookieName: "Cookie2", + CookieValue: "timestamp=2023-09-19/12:00:00&tagEvent=event2", + }, + ], + }, + }; + // Arrange + window.dataLayer = []; + + // Act + analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer(); + + 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); + }); + }); }); From 7f58966fa5416f3d48de6a5bf31586b314394dca Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 19 Sep 2024 19:31:31 +0530 Subject: [PATCH 3/4] CSR-1629 unit test cases --- src/mixins/analytics-mixin.spec.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index 6266b97a1..9ad38f86d 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -1,6 +1,5 @@ import analyticsMixin from "@/mixins/analytics-mixin"; import baseMixin from "@/mixins/base-mixin"; -import { shallowMount } from "@vue/test-utils"; import { setupMocksForJsFiles, setupCookies, @@ -854,12 +853,6 @@ describe("analyticsMixin.js", () => { }); }); describe("push product array and ecommerce cart to data layer", () => { - let wrapper; - - beforeEach(() => { - wrapper = shallowMount(analyticsMixin); - }); - it("should push product array to data layer correctly", () => { // Mock the methods baseMixin.methods.hasSubmittedOrder = jest.fn(); @@ -877,7 +870,7 @@ describe("analyticsMixin.js", () => { baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts.mockReturnValue(100); // Call the function - wrapper.vm.pushProductArrayToDataLayer(); + analyticsMixin.methods.pushProductArrayToDataLayer(); // Assertions expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); @@ -904,7 +897,7 @@ describe("analyticsMixin.js", () => { }); // Call the function - wrapper.vm.pushECommerceCartToDataLayer(); + analyticsMixin.methods.pushECommerceCartToDataLayer(); // Assertions expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); From 933434adff32957cd82172714291c5d7c764d6c7 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 19 Sep 2024 20:43:12 +0530 Subject: [PATCH 4/4] CSR-1629 unit test case fixes --- src/mixins/analytics-mixin.spec.js | 51 ++++++++++++++++-------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/mixins/analytics-mixin.spec.js b/src/mixins/analytics-mixin.spec.js index 9ad38f86d..8f63854a0 100644 --- a/src/mixins/analytics-mixin.spec.js +++ b/src/mixins/analytics-mixin.spec.js @@ -1,5 +1,4 @@ import analyticsMixin from "@/mixins/analytics-mixin"; -import baseMixin from "@/mixins/base-mixin"; import { setupMocksForJsFiles, setupCookies, @@ -853,13 +852,14 @@ describe("analyticsMixin.js", () => { }); }); describe("push product array and ecommerce cart to data layer", () => { + const mocks = setupMocksForJsFiles(); it("should push product array to data layer correctly", () => { // Mock the methods - baseMixin.methods.hasSubmittedOrder = jest.fn(); - baseMixin.methods.getSubmittedOrder = jest.fn(); - baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts = jest.fn(); - baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); - baseMixin.methods.getSubmittedOrder.mockReturnValue({ + mocks.baseMixin.methods.hasSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.getSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts = jest.fn(); + mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({ lineItems: { glassParts: [{ partNumber: "GP1", partType: "glass" }], supportingItems: [{ partNumber: "SI1", partType: "support" }], @@ -867,22 +867,24 @@ describe("analyticsMixin.js", () => { promos: [{ partNumber: "DISCOUNT", partType: "promo", promoCode: "PROMO4" }], }, }); - baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts.mockReturnValue(100); + mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts.mockReturnValue(100); // Call the function analyticsMixin.methods.pushProductArrayToDataLayer(); // Assertions - expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); - expect(baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); - expect(baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); + expect( + mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts + ).toHaveBeenCalled(); }); it("should push eCommerce cart to data layer correctly", () => { // Mock the methods - (baseMixin.methods.hasSubmittedOrder = jest.fn()), - (baseMixin.methods.getSubmittedOrder = jest.fn()), - baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); - baseMixin.methods.getSubmittedOrder.mockReturnValue({ + mocks.baseMixin.methods.hasSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.getSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({ lineItems: { supportingItems: [ { partType: "RECALIBRATION", partNumber: "R1" }, @@ -900,13 +902,16 @@ describe("analyticsMixin.js", () => { analyticsMixin.methods.pushECommerceCartToDataLayer(); // Assertions - expect(baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); - expect(baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); - expect(baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.hasSubmittedOrder).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.getSubmittedOrder).toHaveBeenCalled(); + expect( + mocks.baseMixin.methods.getTotalPriceOfAllLineItemsAndChildParts + ).toHaveBeenCalled(); }); }); describe("pushCommissionJunctionGtmDataToDataLayer", () => { + const mocks = setupMocksForJsFiles(); it("should handle empty affiliateCookies", () => { store.getters = { applicationUser: { @@ -914,17 +919,17 @@ describe("analyticsMixin.js", () => { }, }; - baseMixin.methods.hasSubmittedOrder = jest.fn(); - baseMixin.methods.hasSubmittedOrder.mockReturnValue(false); + mocks.baseMixin.methods.hasSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(false); const result = analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer(); expect(result).toBeUndefined(); }); test("Pushes populated data to data layer", () => { - baseMixin.methods.hasSubmittedOrder = jest.fn(); - baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); - baseMixin.methods.getSubmittedOrder = jest.fn(); - baseMixin.methods.getSubmittedOrder.mockReturnValue({ + mocks.baseMixin.methods.hasSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.hasSubmittedOrder.mockReturnValue(true); + mocks.baseMixin.methods.getSubmittedOrder = jest.fn(); + mocks.baseMixin.methods.getSubmittedOrder.mockReturnValue({ vehicle: { year: "2020", make: "acura",