import Logger from '../../core/logging/logger'; import { ContentsquareModule } from '../../core/nativeModules'; import { Currency } from '../../tracking/constants'; import { trackEvent, trackScreenview, trackTransaction, } from '../../tracking/csqEventTracking'; import { CustomVar } from '../../types/types'; // Mock the currency constants first const mockCurrencyConstants = { CURRENCY_EUR: 978, CURRENCY_ALL: 8, CURRENCY_DZD: 12, CURRENCY_USD: 840, CURRENCY_AFN: 971, // Add other currencies as needed }; // Mock react-native jest.mock('react-native', () => ({ Platform: { OS: 'ios', constants: { reactNativeVersion: { major: 0, minor: 81, patch: 0, }, }, }, NativeModules: { ContentsquareModule: { ...mockCurrencyConstants, trackScreenView: jest.fn(), trackTransaction: jest.fn(), trackTransactionWithStringCurrency: jest.fn(), trackEvent: jest.fn(), }, }, })); // Mock the TurboModule Registry jest.mock('react-native/Libraries/TurboModule/TurboModuleRegistry', () => ({ getEnforcing: jest.fn(name => { if (name === 'ContentsquareModule') { return { getConstants: jest.fn(() => mockCurrencyConstants), trackTransaction: jest.fn(), trackTransactionWithStringCurrency: jest.fn(), trackScreenView: jest.fn(), trackEvent: jest.fn(), }; } throw new Error(`Mock for TurboModule ${name} not found`); }), })); // Mock the NativeContentsquareModule spec jest.mock('../../core/specs/NativeContentsquareModule', () => ({ __esModule: true, default: { getConstants: jest.fn(() => mockCurrencyConstants), trackTransaction: jest.fn(), trackTransactionWithStringCurrency: jest.fn(), trackScreenView: jest.fn(), }, })); jest.mock('../../../package.json', () => ({ version: '5.1.1', })); // Mock the nativeModules jest.mock('../../core/nativeModules', () => ({ ContentsquareModule: { ...mockCurrencyConstants, trackScreenView: jest.fn(), trackTransaction: jest.fn(), trackTransactionWithStringCurrency: jest.fn(), trackEvent: jest.fn(), }, })); jest.mock('../../core/logging/logger', () => ({ error: jest.fn(), warn: jest.fn(), })); jest.mock('../../utils/utils', () => ({ initComponents: jest.fn(), extractReactNativeVersion: jest.fn(() => '0.81.0'), })); describe('Event Tracking Functions', () => { const expectedSourceInfo = { name: 'react_native_bridge', version: '5.1.1', platform: 'React Native 0.81.0', properties: {}, }; beforeEach(() => { jest.clearAllMocks(); }); describe('trackScreenview', () => { it('should call ContentsquareModule.trackScreenView with screen name only', () => { // Given const screenName = 'HomeScreen'; // When trackScreenview(screenName); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, undefined, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackScreenView with screen name and custom variables', () => { // Given const screenName = 'ProductScreen'; const customVars: CustomVar[] = [ { index: 1, key: 'product_type', value: 'electronics' }, { index: 2, key: 'category', value: 'smartphones' }, ]; // When trackScreenview(screenName, customVars); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, customVars, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackScreenView with empty custom variables array', () => { // Given const screenName = 'SettingsScreen'; const customVars: CustomVar[] = []; // When trackScreenview(screenName, customVars); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, customVars, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); }); describe('sendTransaction', () => { it('should call sendTransaction with valid Currency object', () => { const value = 100; const currency = Currency.USD; trackTransaction(value, currency); expect(ContentsquareModule.trackTransaction).toHaveBeenCalledWith( null, value, currency ); expect(Logger.error).not.toHaveBeenCalled(); }); it('should call trackTransactionWithStringCurrency with valid string currency', () => { const value = 200; const currency = 'USD'; const id = 'transaction123'; trackTransaction(value, currency, id); expect( ContentsquareModule.trackTransactionWithStringCurrency ).toHaveBeenCalledWith(id, value, currency); expect(Logger.error).not.toHaveBeenCalled(); }); it('should log an error for invalid value type', () => { trackTransaction('invalidValue' as any, Currency.USD); expect(Logger.error).toHaveBeenCalledWith( 'The value of the transaction is not recognized. It must be a number.', true ); expect(ContentsquareModule.trackTransaction).not.toHaveBeenCalled(); expect( ContentsquareModule.trackTransactionWithStringCurrency ).not.toHaveBeenCalled(); }); it('should log an error for invalid currency type', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore trackTransaction(300, { invalidCurrency: 300 }); expect(Logger.error).toHaveBeenCalledWith( 'The currency value is not recognized. It is neither a string nor a Currency object type.' ); expect(ContentsquareModule.trackTransaction).not.toHaveBeenCalled(); expect( ContentsquareModule.trackTransactionWithStringCurrency ).not.toHaveBeenCalled(); }); }); describe('trackScreenview', () => { it('should call ContentsquareModule.trackScreenView with screen name only', () => { // Given const screenName = 'HomeScreen'; // When trackScreenview(screenName); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, undefined, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackScreenView with screen name and custom variables', () => { // Given const screenName = 'ProductScreen'; const customVars: CustomVar[] = [ { index: 1, key: 'product_type', value: 'electronics' }, { index: 2, key: 'category', value: 'smartphones' }, ]; // When trackScreenview(screenName, customVars); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, customVars, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackScreenView with empty custom variables array', () => { // Given const screenName = 'SettingsScreen'; const customVars: CustomVar[] = []; // When trackScreenview(screenName, customVars); // Then expect(ContentsquareModule.trackScreenView).toHaveBeenCalledWith( screenName, customVars, expectedSourceInfo ); expect(ContentsquareModule.trackScreenView).toHaveBeenCalledTimes(1); }); }); describe('trackEvent', () => { it('should call ContentsquareModule.trackEvent with event name only', () => { const eventName = 'ButtonClick'; trackEvent(eventName); expect(ContentsquareModule.trackEvent).toHaveBeenCalledWith( eventName, undefined, expectedSourceInfo ); expect(ContentsquareModule.trackEvent).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackEvent with event name and properties', () => { const eventName = 'ProductView'; const properties = { productId: 'ABC123', category: 'electronics', price: 299.99, inStock: true, }; trackEvent(eventName, properties); expect(ContentsquareModule.trackEvent).toHaveBeenCalledWith( eventName, properties, expectedSourceInfo ); expect(ContentsquareModule.trackEvent).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackEvent with complex property types', () => { const eventName = 'PurchaseComplete'; const properties = { orderId: 'ORD-456', amount: 149.99, currency: 'USD', itemCount: 3, isFirstPurchase: false, timestamp: new Date().toISOString(), }; trackEvent(eventName, properties); expect(ContentsquareModule.trackEvent).toHaveBeenCalledWith( eventName, properties, expectedSourceInfo ); expect(ContentsquareModule.trackEvent).toHaveBeenCalledTimes(1); }); it('should call ContentsquareModule.trackEvent with all supported PropertyValue types', () => { const eventName = 'AllTypesTest'; const properties = { stringProp: 'test string', numberProp: 42, floatProp: 3.14159, booleanTrue: true, booleanFalse: false, bigintProp: BigInt(9007199254740991), }; trackEvent(eventName, properties); expect(ContentsquareModule.trackEvent).toHaveBeenCalledWith( eventName, properties, expectedSourceInfo ); expect(ContentsquareModule.trackEvent).toHaveBeenCalledTimes(1); }); }); });