import { describe, expect, it, mock } from 'bun:test'; import { BaseHandler } from '../src/base/BaseHandler'; // Test the internal functions by mocking module imports describe('Auto Registration Unit Tests', () => { describe('extractHandlerClasses', () => { it('should extract handler classes from module', () => { // Test handler class class TestHandler extends BaseHandler {} class AnotherHandler extends BaseHandler {} class NotAHandler {} const module = { TestHandler, AnotherHandler, NotAHandler, someFunction: () => {}, someVariable: 42, }; // Access the private function through module internals const autoRegister = require('../src/registry/auto-register'); // Mock the extractHandlerClasses function behavior const handlers = []; for (const key of Object.keys(module)) { const exported = module[key]; if ( typeof exported === 'function' && exported.prototype && exported.prototype instanceof BaseHandler ) { handlers.push(exported); } } expect(handlers).toHaveLength(2); expect(handlers).toContain(TestHandler); expect(handlers).toContain(AnotherHandler); expect(handlers).not.toContain(NotAHandler); }); }); describe('findHandlerFiles', () => { it('should filter files by pattern', () => { const files = [ 'test.handler.ts', 'test.service.ts', 'another.handler.ts', 'test.handler.js', '.hidden.handler.ts', ]; const pattern = '.handler.'; const filtered = files.filter( file => file.includes(pattern) && file.endsWith('.ts') && !file.startsWith('.') ); expect(filtered).toEqual(['test.handler.ts', 'another.handler.ts']); }); it('should handle different patterns', () => { const files = ['test.handler.ts', 'test.custom.ts', 'another.custom.ts']; const customPattern = '.custom.'; const filtered = files.filter(file => file.includes(customPattern) && file.endsWith('.ts')); expect(filtered).toEqual(['test.custom.ts', 'another.custom.ts']); }); }); describe('Handler Registration Logic', () => { it('should skip disabled handlers', () => { class DisabledHandler extends BaseHandler { static __disabled = true; } class EnabledHandler extends BaseHandler {} const handlers = [DisabledHandler, EnabledHandler]; const registered = handlers.filter(h => !(h as any).__disabled); expect(registered).toHaveLength(1); expect(registered).toContain(EnabledHandler); expect(registered).not.toContain(DisabledHandler); }); it('should handle handler with auto-registration flag', () => { class AutoRegisterHandler extends BaseHandler { static __handlerName = 'auto-handler'; static __needsAutoRegistration = true; } expect((AutoRegisterHandler as any).__needsAutoRegistration).toBe(true); expect((AutoRegisterHandler as any).__handlerName).toBe('auto-handler'); }); it('should create handler instance with services', () => { const mockServices = { cache: null, globalCache: null, queueManager: null, proxy: null, browser: null, mongodb: null, postgres: null, questdb: null, } as any; class TestHandler extends BaseHandler {} const instance = new TestHandler(mockServices); expect(instance).toBeInstanceOf(BaseHandler); }); }); describe('Error Handling', () => { it('should handle module import errors gracefully', () => { const errors = []; const modules = ['valid', 'error', 'another']; for (const mod of modules) { try { if (mod === 'error') { throw new Error('Module not found'); } // Process module } catch (error) { errors.push(mod); } } expect(errors).toEqual(['error']); }); it('should handle filesystem errors', () => { let result; try { // Simulate filesystem error throw new Error('EACCES: permission denied'); } catch (error) { // Should handle gracefully result = { registered: [], failed: [] }; } expect(result).toEqual({ registered: [], failed: [] }); }); }); describe('Options Handling', () => { it('should apply exclude patterns', () => { const files = ['test.handler.ts', 'excluded.handler.ts', 'another.handler.ts']; const exclude = ['excluded']; const filtered = files.filter(file => !exclude.some(ex => file.includes(ex))); expect(filtered).toEqual(['test.handler.ts', 'another.handler.ts']); }); it('should handle service name option', () => { const options = { pattern: '.handler.', exclude: [], dryRun: false, serviceName: 'test-service', }; expect(options.serviceName).toBe('test-service'); }); it('should handle dry run mode', () => { const options = { dryRun: true }; const actions = []; if (options.dryRun) { actions.push('[DRY RUN] Would register handler'); } else { actions.push('Registering handler'); } expect(actions).toEqual(['[DRY RUN] Would register handler']); }); }); describe('Registry Methods', () => { it('should handle multiple directories', () => { const directories = ['./dir1', './dir2', './dir3']; const results = { registered: [] as string[], failed: [] as string[], }; for (const dir of directories) { // Simulate processing each directory results.registered.push(`${dir}-handler`); } expect(results.registered).toHaveLength(3); expect(results.registered).toContain('./dir1-handler'); expect(results.registered).toContain('./dir2-handler'); expect(results.registered).toContain('./dir3-handler'); }); }); });