import analyticsMixin from '@/mixins/analytics-mixin'; import { setupCookies } from '@/helpers/unit-test-helper.js'; import { analyticsPageEvents, GaCategories, GaActions, GaLabels, ValueToLogTypes } from '@/constants/analytics'; import { useMainStore } from '@/store'; import crypto from 'crypto'; global.crypto = crypto; describe('analyticsMixin.js', () => { test('logPageView: calls dispatch with type and payload', async () => { const payload = {}; const testCookieValue = { sid: '10000000-0000-0000-0000-000000000001' }; setupCookies({ ISSCookieValue: JSON.stringify(testCookieValue) }); await analyticsMixin.methods.logPageView(payload); expect(useMainStore().logPageView).toBeCalled(); }); test('logCustomEvent: calls dispatch with type and payload', async () => { await analyticsMixin.methods.logCustomEvent('someCat', 'someAction', 'someLabel', 'someVal'); expect(useMainStore().logCustomEvent).toBeCalled(); }); test('pushEventToGA, should call dataLayer push and logCustomEvent too', async () => { // Arrange window.dataLayer = []; const mockDataLayer = []; mockDataLayer.push({ event: 'event', category: 'category', action: 'action', label: 'label', value: undefined, path: '/iss/?issPage=' }); // Act await analyticsMixin.methods.pushEventToGA('category', 'action', 'label', true); // Assert expect(mockDataLayer).toEqual(expect.arrayContaining(window.dataLayer)); }); test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 only logs last 5 of label', async () => { // Arrange window.dataLayer = []; const expectedDataLayer = []; expectedDataLayer.push({ event: 'event', category: 'category', action: 'action', label: '33333', value: undefined, path: '/iss/?issPage=' }); // Act await analyticsMixin.methods.pushEventToGA( 'category', 'action', '1111122222333333', false, ValueToLogTypes.LAST_5 ); // Assert expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer)); }); test('pushEventToGA, should call dataLayer push and ValueToLogTypes.LAST_5 logs only the last 3 characters for a 3 character string', async () => { // Arrange window.dataLayer = []; const expectedDataLayer = []; expectedDataLayer.push({ event: 'event', category: 'category', action: 'action', label: '111', value: undefined, path: '/iss/?issPage=' }); // Act await analyticsMixin.methods.pushEventToGA( 'category', 'action', '111', false, ValueToLogTypes.LAST_5 ); // Assert expect(expectedDataLayer).toEqual(expect.arrayContaining(window.dataLayer)); }); test('pushIssSessionData: logs session payload to store', () => { // Arrange const store = useMainStore(); const testCookieValue = { sid: '10000000-0000-0000-0000-000000000001', skey: '12345' }; setupCookies({ ISSCookieValue: JSON.stringify(testCookieValue) }); store.bailoutCode = 15; store.applicationUser.savedSessionId = 'saved-session-id'; store.applicationUser.pageData = { quote: { servicePackageSelected: 'BASIC_PACKAGE' } }; store.order.parentAccountNumber = 11111111; store.order.vehicle = { carId: 'CAR123', year: '2020', make: 'Toyota', model: 'Camry', style: 'SE', vin: '1ABCDEFGH12345678' }; store.order.damage = { isRepair: false, glassToReplace: [{ glassLocation: 'Windshield', glassName: 'Front' }] }; store.order.lineItems = { glassParts: [{ partNumber: 'GP1', partType: 'Glass', childParts: [] }], supportingItems: [{ partNumber: 'SUP1', partType: 'Adas' }], vaps: [{ partNumber: 'VAP1', partType: 'Vap' }] }; store.order.schedule = { date: '2026-01-01', startTime: '09:00' }; store.order.serviceLocation = { appointmentType: 'Mobile', provider: { address: { zipCode: '43081', zipCodeCtu: '43081' } }, zipCode: '43081', zipCodeCtu: '43081' }; store.order.contactInfo = { notesForTechnician: 'note', requestTextUpdates: true }; store.order.payment = { paymentMethod: 'Card', nextGenSettledAmount: 100 }; store.order.insuranceCoverage = { coverageStatus: 3, coverageType: 1 }; store.order.eon = 'EON123'; store.order.referralNumber = 'R123'; store.order.referralSequenceNumber = '1'; store.order.referralDate = '2026-01-01'; store.order.workOrderNumber = 'WO123'; store.order.workOrderId = 'WOID123'; store.issConfig.parentAccountNumber = 99999999; store.issConfig.billToAccountNumber = 'BILL123'; store.issConfig.clientName = 'Test Insurance'; store.currentDeductible = 250; store.isVerified = true; store.isNoComp = false; store.isITAC = false; const context = { getPageNameByQueryString: jest.fn().mockReturnValue('duplicate-check') }; // Act analyticsMixin.methods.pushIssSessionData.call(context); // Assert expect(store.logIssSessionData).toHaveBeenCalledTimes(1); expect(store.logIssSessionData).toHaveBeenCalledWith(expect.objectContaining({ currentPage: 'duplicate-check', referralNumber: 'R123', issSessionId: 'saved-session-id', parentAccountNumber: '11111111', hasVin: true, damageType: 'Replace', productType: expect.arrayContaining(['GP1-Glass', 'SUP1-Adas', 'VAP1-Vap', 'BASIC_PACKAGE']) })); }); test('Experiments, should push to dataLayer with default Google Custom Dimension Index', () => { // Arrange const store = useMainStore(); window.dataLayer = []; const mockExperimentData = [ { settings: {}, variationName: 'test', universeName: 'testUniverse' } ]; store.applicationUserObj.experiments = mockExperimentData; // Act analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData); // Assert expect(window.dataLayer).toEqual([ { experimentId_99: undefined, variationId_99: undefined, experimentName_99: 'testUniverse', variationName_99: 'test', customDimension_99: 'undefined_undefined_testUniverse_test' } ]); }); test('Experiments, should push to dataLayer with custom Google Custom Dimension Index', () => { // Arrange const store = useMainStore(); window.dataLayer = []; const mockExperimentData = [ { settings: { 'Google Custom Dimension Index': '5' }, variationName: 'test', universeName: 'testUniverse' } ]; store.applicationUserObj.experiments = mockExperimentData; // Act analyticsMixin.methods.pushExperimentsToDataLayer(mockExperimentData); // Assert expect(window.dataLayer).toEqual([ { experimentId_5: undefined, variationId_5: undefined, experimentName_5: 'testUniverse', variationName_5: 'test', customDimension_5: 'undefined_undefined_testUniverse_test' } ]); }); test('Obj is not null after action prepended', () => { // Arrange const obj = { baseMethodName: 'testMethodName', data: 'testData' }; const method = { name: 'testMethodName', data: 'testData' }; const action = 'testAction'; // Act analyticsMixin.methods.prependActionToMethod(obj, method, action); // Assert expect(obj != null); }); test('Obj method name does not include bound', () => { // Arrange const obj = { baseMethodName: 'testMethodName', data: 'testData' }; const method = { name: 'testMethodName', data: 'testData' }; const action = 'testAction'; // Act analyticsMixin.methods.prependActionToMethod(obj, method, action); // Assert expect(method.name.startsWith('bound ')).toBe(false); }); test('Prepended action does not include bound', () => { // Arrange const obj = { baseMethodName: 'testMethodName', data: 'testData' }; const method = { name: 'testMethodName', data: 'testData' }; const action = 'testAction'; // Act analyticsMixin.methods.prependActionToMethod(obj, method, action); // Assert expect(action.startsWith('bound ')).toBe(false); }); test('analyticsPageEvents returns constants analyticsPageEvents', () => { // Act const analyticsPE = analyticsMixin.computed.analyticsPageEvents(); // Assert expect(analyticsPE).toEqual(analyticsPageEvents); }); test('GaActions returns constants GaActions', () => { // Act const gaActions = analyticsMixin.computed.GaActions(); // Assert expect(gaActions).toEqual(GaActions); }); test('GaCategories returns constants GaCategories', () => { // Act const gaCategories = analyticsMixin.computed.GaCategories(); // Assert expect(gaCategories).toEqual(GaCategories); }); test('GaLabels returns constants GaLabels', () => { // Act const gaLabels = analyticsMixin.computed.GaLabels(); // Assert expect(gaLabels).toEqual(GaLabels); }); });