diff --git a/test/utils/FeatureFlags.spec.ts b/test/utils/FeatureFlags.spec.ts new file mode 100644 index 000000000..7d89f829c --- /dev/null +++ b/test/utils/FeatureFlags.spec.ts @@ -0,0 +1,44 @@ +import { NativeInstabug } from '../../src/native/NativeInstabug'; +import { FeatureFlags, registerW3CFlagsListener } from '../../src/utils/FeatureFlags'; +import { _registerW3CFlagsChangeListener } from '../../src/modules/Instabug'; + +jest.mock('../../src/modules/Instabug', () => ({ + _registerW3CFlagsChangeListener: jest.fn(), +})); + +describe('FeatureFlags', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('calls native methods by default', () => { + (NativeInstabug.isW3ExternalTraceIDEnabled as jest.Mock).mockReturnValue(true); + (NativeInstabug.isW3ExternalGeneratedHeaderEnabled as jest.Mock).mockReturnValue(false); + (NativeInstabug.isW3CaughtHeaderEnabled as jest.Mock).mockReturnValue(true); + + expect(FeatureFlags.isW3ExternalTraceID()).toBe(true); + expect(FeatureFlags.isW3ExternalGeneratedHeader()).toBe(false); + expect(FeatureFlags.isW3CaughtHeader()).toBe(true); + }); + + it('overrides flags after listener is registered', async () => { + const mockListener = jest.fn(); + (_registerW3CFlagsChangeListener as jest.Mock).mockImplementation((cb) => { + mockListener.mockImplementation(cb); + cb({ + isW3ExternalTraceIDEnabled: false, + isW3ExternalGeneratedHeaderEnabled: true, + isW3CaughtHeaderEnabled: false, + }); + }); + + registerW3CFlagsListener(); + + expect(typeof FeatureFlags.isW3ExternalTraceID).toBe('function'); + + // @ts-ignore - these are now async after listener runs + await expect(FeatureFlags.isW3ExternalTraceID()).resolves.toBe(false); + await expect(FeatureFlags.isW3ExternalGeneratedHeader()).resolves.toBe(true); + await expect(FeatureFlags.isW3CaughtHeader()).resolves.toBe(false); + }); +}); diff --git a/test/utils/logger.spec.ts b/test/utils/logger.spec.ts new file mode 100644 index 000000000..04d8bf930 --- /dev/null +++ b/test/utils/logger.spec.ts @@ -0,0 +1,55 @@ +import { InstabugRNConfig } from '../../src/utils/config'; +import { LogLevel } from '../../src'; +import { Logger } from '../../src/utils/logger'; + +describe('Logger', () => { + const consoleMethods = { + error: jest.spyOn(console, 'error').mockImplementation(() => {}), + info: jest.spyOn(console, 'info').mockImplementation(() => {}), + log: jest.spyOn(console, 'log').mockImplementation(() => {}), + warn: jest.spyOn(console, 'warn').mockImplementation(() => {}), + trace: jest.spyOn(console, 'trace').mockImplementation(() => {}), + debug: jest.spyOn(console, 'debug').mockImplementation(() => {}), + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + const allLevels: LogLevel[] = [LogLevel.none, LogLevel.error, LogLevel.debug, LogLevel.verbose]; + + it.each(allLevels)('should respect logging level: %s', (level) => { + InstabugRNConfig.debugLogsLevel = level; + + Logger.error('error'); + Logger.info('info'); + Logger.log('log'); + Logger.warn('warn'); + Logger.trace('trace'); + Logger.debug('debug'); + + const logLevelHierarchy: Record = { + [LogLevel.verbose]: 3, + [LogLevel.debug]: 2, + [LogLevel.error]: 1, + [LogLevel.none]: 0, + }; + + const current = logLevelHierarchy[level]; + + expect(consoleMethods.error).toHaveBeenCalledTimes(current >= 1 ? 1 : 0); + expect(consoleMethods.info).toHaveBeenCalledTimes(current >= 3 ? 1 : 0); + expect(consoleMethods.log).toHaveBeenCalledTimes(current >= 3 ? 1 : 0); + expect(consoleMethods.warn).toHaveBeenCalledTimes(current >= 2 ? 1 : 0); + expect(consoleMethods.trace).toHaveBeenCalledTimes(current >= 2 ? 1 : 0); + expect(consoleMethods.debug).toHaveBeenCalledTimes(current >= 2 ? 1 : 0); + }); + + it('passes message and params correctly', () => { + InstabugRNConfig.debugLogsLevel = LogLevel.verbose; + + Logger.log('test message', 'extra', 123); + + expect(consoleMethods.log).toHaveBeenCalledWith('test message', 'extra', 123); + }); +});