UNPKG

falkordb-mcpserver

Version:

Model Context Protocol server for FalkorDB graph databases - enables AI assistants to query and manage graph data using natural language

116 lines (115 loc) 5.77 kB
// Simple test for logger service to avoid import.meta issues // Focus on testing the public interface without requiring complex mocking // Mock platformdirs before importing logger service jest.mock('platformdirs', () => ({ userLogDir: jest.fn().mockReturnValue('/mock/user/logs'), })); import { logger } from './logger.service'; // Mock file system operations jest.mock('fs', () => ({ appendFileSync: jest.fn(), existsSync: jest.fn().mockReturnValue(true), // Directory exists mkdirSync: jest.fn(), })); // Mock path module jest.mock('path', () => ({ join: jest.fn().mockReturnValue('/mock/logs/test.log'), })); describe('Logger Service', () => { // Mock console to avoid actual logging during tests let consoleErrorSpy; beforeEach(() => { jest.clearAllMocks(); consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { }); }); afterEach(() => { consoleErrorSpy.mockRestore(); }); describe('Singleton Instance', () => { it('should export a singleton logger instance', () => { expect(logger).toBeDefined(); expect(typeof logger.info).toBe('function'); expect(typeof logger.warn).toBe('function'); expect(typeof logger.error).toBe('function'); expect(typeof logger.debug).toBe('function'); }); it('should have sync logging methods', () => { expect(typeof logger.infoSync).toBe('function'); expect(typeof logger.warnSync).toBe('function'); expect(typeof logger.errorSync).toBe('function'); expect(typeof logger.debugSync).toBe('function'); }); it('should have setMcpServer method', () => { expect(typeof logger.setMcpServer).toBe('function'); }); }); describe('Async Logging Methods', () => { it('should handle info logging without throwing', async () => { await expect(logger.info('Test info message')).resolves.not.toThrow(); await expect(logger.info('Test with context', { key: 'value' })).resolves.not.toThrow(); }); it('should handle warn logging without throwing', async () => { await expect(logger.warn('Test warning')).resolves.not.toThrow(); await expect(logger.warn('Test with context', { code: 123 })).resolves.not.toThrow(); }); it('should handle error logging without throwing', async () => { const error = new Error('Test error'); await expect(logger.error('Error occurred')).resolves.not.toThrow(); await expect(logger.error('Error with object', error)).resolves.not.toThrow(); await expect(logger.error('Error with context', error, { extra: 'data' })).resolves.not.toThrow(); }); it('should handle debug logging without throwing', async () => { await expect(logger.debug('Debug message')).resolves.not.toThrow(); await expect(logger.debug('Debug with context', { debug: true })).resolves.not.toThrow(); }); }); describe('Sync Logging Methods', () => { it('should handle sync info logging without throwing', () => { expect(() => logger.infoSync('Sync info')).not.toThrow(); expect(() => logger.infoSync('Sync info with context', { sync: true })).not.toThrow(); }); it('should handle sync warn logging without throwing', () => { expect(() => logger.warnSync('Sync warning')).not.toThrow(); expect(() => logger.warnSync('Sync warning with context', { level: 'warn' })).not.toThrow(); }); it('should handle sync error logging without throwing', () => { const error = new Error('Sync error'); expect(() => logger.errorSync('Sync error occurred')).not.toThrow(); expect(() => logger.errorSync('Sync error with object', error)).not.toThrow(); expect(() => logger.errorSync('Sync error with context', error, { extra: 'data' })).not.toThrow(); }); it('should handle sync debug logging without throwing', () => { expect(() => logger.debugSync('Sync debug')).not.toThrow(); expect(() => logger.debugSync('Sync debug with context', { debug: true })).not.toThrow(); }); }); describe('MCP Server Integration', () => { it('should accept MCP server instance without throwing', () => { const mockMcpServer = { server: { notification: jest.fn().mockResolvedValue(undefined), }, }; expect(() => logger.setMcpServer(mockMcpServer)).not.toThrow(); }); }); describe('Error Resilience', () => { it('should handle file system errors gracefully', async () => { // The logger should not throw even if file operations fail // This tests the try-catch blocks in the logging methods await expect(logger.info('Test message during potential file error')).resolves.not.toThrow(); await expect(logger.error('Test error during potential file error', new Error('Test'))).resolves.not.toThrow(); }); it('should handle MCP notification errors gracefully', async () => { // Set up a mock server that throws errors const failingMcpServer = { server: { notification: jest.fn().mockRejectedValue(new Error('MCP notification failed')), }, }; logger.setMcpServer(failingMcpServer); // Logger should not throw even if MCP notifications fail await expect(logger.info('Test with failing MCP')).resolves.not.toThrow(); }); }); });