Spaces:
Sleeping
Sleeping
CarouselForge Developer
feat: Phase 15 complete — mobile responsiveness, monitoring, Telegram polish, UAT
d0ded63 | import { logger, createAsyncMetricsTracker } from './logger'; | |
| describe('Logger', () => { | |
| const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); | |
| const mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); | |
| const mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation(); | |
| beforeEach(() => { | |
| mockConsoleLog.mockClear(); | |
| mockConsoleError.mockClear(); | |
| mockConsoleWarn.mockClear(); | |
| }); | |
| afterAll(() => { | |
| mockConsoleLog.mockRestore(); | |
| mockConsoleError.mockRestore(); | |
| mockConsoleWarn.mockRestore(); | |
| }); | |
| describe('log methods', () => { | |
| it('should log error messages to console.error', () => { | |
| logger.error('test-component', 'test error message'); | |
| expect(mockConsoleError).toHaveBeenCalledWith( | |
| '[test-component] test error message', | |
| ); | |
| }); | |
| it('should log warning messages to console.warn', () => { | |
| logger.warn('test-component', 'test warning'); | |
| expect(mockConsoleWarn).toHaveBeenCalledWith( | |
| '[test-component] test warning', | |
| ); | |
| }); | |
| it('should include metadata in logs', () => { | |
| const metadata = { userId: '123', action: 'create' }; | |
| logger.error('auth', 'unauthorized access', undefined, metadata); | |
| expect(mockConsoleError).toHaveBeenCalledWith( | |
| '[auth] unauthorized access', | |
| { userId: '123', action: 'create' }, | |
| ); | |
| }); | |
| it('should log error with Error object and extract message/stack', () => { | |
| const error = new Error('test error'); | |
| logger.error('api', 'request failed', error); | |
| expect(mockConsoleError).toHaveBeenCalled(); | |
| const callArgs = mockConsoleError.mock.calls[0]; | |
| expect(callArgs[0]).toContain('[api]'); | |
| expect(callArgs[1]).toHaveProperty('errorMessage', 'test error'); | |
| expect(callArgs[1]).toHaveProperty('errorStack'); | |
| }); | |
| }); | |
| describe('measureAsync', () => { | |
| it('should measure async operation duration and return result', async () => { | |
| const result = await logger.measureAsync('test', 'operation', async () => { | |
| return 'success'; | |
| }); | |
| expect(result).toBe('success'); | |
| }); | |
| it('should measure async operation duration and log failure', async () => { | |
| const testError = new Error('async failure'); | |
| await expect( | |
| logger.measureAsync('test', 'operation', async () => { | |
| throw testError; | |
| }), | |
| ).rejects.toThrow('async failure'); | |
| expect(mockConsoleError).toHaveBeenCalled(); | |
| const callArgs = mockConsoleError.mock.calls[0]; | |
| expect(callArgs[0]).toContain('[test]'); | |
| expect(callArgs[0]).toContain('operation failed'); | |
| }); | |
| }); | |
| describe('measureSync', () => { | |
| it('should measure sync operation duration and return result', () => { | |
| const result = logger.measureSync('test', 'operation', () => { | |
| return 'success'; | |
| }); | |
| expect(result).toBe('success'); | |
| }); | |
| it('should measure sync operation duration and log failure', () => { | |
| expect(() => { | |
| logger.measureSync('test', 'operation', () => { | |
| throw new Error('sync failure'); | |
| }); | |
| }).toThrow('sync failure'); | |
| expect(mockConsoleError).toHaveBeenCalled(); | |
| }); | |
| }); | |
| describe('createAsyncMetricsTracker', () => { | |
| it('should track successful async operation', () => { | |
| const tracker = createAsyncMetricsTracker('api', 'fetch'); | |
| tracker.success({ statusCode: 200 }); | |
| // Logger call succeeds without console verification | |
| }); | |
| it('should track failed async operation', () => { | |
| const tracker = createAsyncMetricsTracker('api', 'fetch'); | |
| const error = new Error('network error'); | |
| tracker.error(error, { attempt: 1 }); | |
| expect(mockConsoleError).toHaveBeenCalled(); | |
| const callArgs = mockConsoleError.mock.calls[0]; | |
| expect(callArgs[0]).toContain('[api]'); | |
| expect(callArgs[0]).toContain('fetch failed'); | |
| }); | |
| }); | |
| }); | |