import Logger from '../../core/logging/logger'; import { ContentsquareModule } from '../../core/nativeModules'; import { Currency } from '../../tracking/constants'; import { resumeTracking, send, sendDynamicVar, sendTransaction, stopTracking, } from '../../tracking/tracking'; 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', () => ({ NativeModules: { ContentsquareModule: { ...mockCurrencyConstants, resumeTracking: jest.fn(), stopTracking: jest.fn(), send: jest.fn(), sendTransaction: jest.fn(), sendTransactionWithStringCurrency: jest.fn(), sendDynamicStringVar: jest.fn(), sendDynamicIntVar: 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), resumeTracking: jest.fn(), stopTracking: jest.fn(), send: jest.fn(), sendTransaction: jest.fn(), sendTransactionWithStringCurrency: jest.fn(), sendDynamicStringVar: jest.fn(), sendDynamicIntVar: 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), resumeTracking: jest.fn(), stopTracking: jest.fn(), send: jest.fn(), sendTransaction: jest.fn(), sendTransactionWithStringCurrency: jest.fn(), sendDynamicStringVar: jest.fn(), sendDynamicIntVar: jest.fn(), }, })); // Mock the nativeModules jest.mock('../../core/nativeModules', () => ({ ContentsquareModule: { ...mockCurrencyConstants, resumeTracking: jest.fn(), stopTracking: jest.fn(), send: jest.fn(), sendTransaction: jest.fn(), sendTransactionWithStringCurrency: jest.fn(), sendDynamicStringVar: jest.fn(), sendDynamicIntVar: jest.fn(), }, })); jest.mock('../../core/logging/logger', () => ({ error: jest.fn(), warn: jest.fn(), })); describe('Tracking Functions', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('resumeTracking', () => { it('should call ContentsquareModule.resumeTracking', () => { resumeTracking(); expect(ContentsquareModule.resumeTracking).toHaveBeenCalledTimes(1); }); }); describe('stopTracking', () => { it('should call ContentsquareModule.stopTracking', () => { stopTracking(); expect(ContentsquareModule.stopTracking).toHaveBeenCalledTimes(1); }); }); describe('send', () => { it('should call ContentsquareModule.send', () => { const screenName = 'HomeScreen'; const cvars: CustomVar[] = [ { index: 1, key: 'testVar', value: 'testValue' }, ]; send(screenName, cvars); expect(ContentsquareModule.send).toHaveBeenCalledWith(screenName, cvars); }); }); describe('sendTransaction', () => { it('should call sendTransaction with valid Currency object', () => { const value = 100; const currency = Currency.USD; sendTransaction(value, currency); expect(ContentsquareModule.sendTransaction).toHaveBeenCalledWith( null, value, currency ); expect(Logger.error).not.toHaveBeenCalled(); }); it('should call sendTransactionWithStringCurrency with valid string currency', () => { const value = 200; const currency = 'USD'; const id = 'transaction123'; sendTransaction(value, currency, id); expect( ContentsquareModule.sendTransactionWithStringCurrency ).toHaveBeenCalledWith(id, value, currency); expect(Logger.error).not.toHaveBeenCalled(); }); it('should log an error for invalid value type', () => { sendTransaction('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.sendTransaction).not.toHaveBeenCalled(); expect( ContentsquareModule.sendTransactionWithStringCurrency ).not.toHaveBeenCalled(); }); it('should log an error for invalid currency type', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore sendTransaction(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.sendTransaction).not.toHaveBeenCalled(); expect( ContentsquareModule.sendTransactionWithStringCurrency ).not.toHaveBeenCalled(); }); }); describe('sendDynamicVar', () => { it('should call sendDynamicStringVar for a valid string value', () => { const key = 'key1'; const value = 'stringValue'; sendDynamicVar(key, value); expect(ContentsquareModule.sendDynamicStringVar).toHaveBeenCalledWith( key, value ); expect(ContentsquareModule.sendDynamicIntVar).not.toHaveBeenCalled(); }); it('should call sendDynamicIntVar for a valid integer value', () => { const key = 'key2'; const value = 42; sendDynamicVar(key, value); expect(ContentsquareModule.sendDynamicIntVar).toHaveBeenCalledWith( key, value ); expect(ContentsquareModule.sendDynamicStringVar).not.toHaveBeenCalled(); }); it('should call onError callback for invalid value type', () => { const key = 'key3'; const value = -1; // Invalid integer value const onError = jest.fn(); sendDynamicVar(key, value, onError); expect(onError).toHaveBeenCalledWith( new TypeError( 'The value of the DynamicVar should be either a string or an unsigned integer' ) ); expect(ContentsquareModule.sendDynamicStringVar).not.toHaveBeenCalled(); expect(ContentsquareModule.sendDynamicIntVar).not.toHaveBeenCalled(); }); it('should log an error for invalid value type if no onError callback is provided', () => { const key = 'key4'; const value = -10; // Invalid integer value console.log = jest.fn(); sendDynamicVar(key, value); expect(console.log).toHaveBeenCalledWith( 'The value of the DynamicVar should be either a string or an unsigned integer' ); expect(ContentsquareModule.sendDynamicStringVar).not.toHaveBeenCalled(); expect(ContentsquareModule.sendDynamicIntVar).not.toHaveBeenCalled(); }); }); });