import { DyNTS_Bot_IO_ControlService } from './bot-io.control-service'; import { DyNTS_Bot_Main_ControlService } from './bot-main.control-service'; import { DyNTS_Bot_Commands_ControlService } from './bot-commands.control-service'; import { DyNTS_Bot_MessageWrapper } from '../_models/bot-message-wrapper.interface'; import { DyNTS_Bot_MessagingProvider_ServiceBase } from './bot-messaging-provider.service-base'; import { DyFM_Error, DyFM_EnvironmentFlag } from '@futdevpro/fsm-dynamo'; import { DyNTS_global_settings } from '../../../_collections/global-settings.const'; class TestBotIOService extends DyNTS_Bot_IO_ControlService { protected declare mainBot_CS: any; protected getMainBotControlService(): any { return { defaultProvider: { botId: 'bot-123', botDisplayName: 'TestBot', }, } as any; } protected getCommandsControlService(): DyNTS_Bot_Commands_ControlService { return { handleCommand: jasmine.createSpy('handleCommand').and.returnValue(Promise.resolve()), } as any; } handleMessage = async (message: any, issuer: string): Promise => { return message; }; static getInstance(): TestBotIOService { return TestBotIOService.getSingletonInstance(); } } xdescribe('| DyNTS_Bot_IO_ControlService', () => { let service: TestBotIOService; beforeAll(() => { if (!DyNTS_global_settings.systemShortCodeName) { (DyNTS_global_settings as { systemShortCodeName?: string }).systemShortCodeName = 'TEST'; } if (!DyNTS_global_settings.env_settings) { (DyNTS_global_settings as { env_settings?: unknown }).env_settings = { environment: DyFM_EnvironmentFlag.local }; } }); beforeEach(() => { service = TestBotIOService.getInstance(); }); it('| should be a singleton instance', () => { const instance1 = TestBotIOService.getInstance(); const instance2 = TestBotIOService.getInstance(); expect(instance1).toBe(instance2); expect(instance1).toBeInstanceOf(TestBotIOService); }); describe('| defaultProvider', () => { it('| should return default provider from main bot service', () => { (service as any).mainBot_CS = (service as any).getMainBotControlService(); expect(service.defaultProvider).toBeDefined(); expect(service.defaultProvider.botId).toBe('bot-123'); }); }); describe('| setup', () => { it('| should setup main bot and commands services', async () => { await service.setup('issuer-123'); expect((service as any).mainBot_CS).toBeDefined(); expect((service as any).commands_CS).toBeDefined(); }); it('| should throw error when main bot service not found', async () => { const serviceWithoutMainBot = new (class extends TestBotIOService { protected override getMainBotControlService(): any { return null; } } as any)(); await expectAsync( serviceWithoutMainBot.setup('issuer-123') ).toBeRejected(); }); it('| should throw error when commands service not found', async () => { const serviceWithoutCommands = new (class extends TestBotIOService { protected override getCommandsControlService(): any { return null; } } as any)(); await expectAsync( serviceWithoutCommands.setup('issuer-123') ).toBeRejected(); }); }); describe('| start', () => { it('| should throw error when default provider not initialized', async () => { const serviceWithoutProvider = new (class extends TestBotIOService { protected override getMainBotControlService(): any { return { defaultProvider: null, }; } } as any)(); await expectAsync( serviceWithoutProvider.start('issuer-123') ).toBeRejected(); }); it('| should succeed when default provider is initialized', async () => { (service as any).mainBot_CS = (service as any).getMainBotControlService(); await expectAsync( service.start('issuer-123') ).toBeResolved(); }); }); describe('| getMessageIsForBotToHandle', () => { it('| should return false when bot not initialized', async () => { const mockMessage = { provider: null, content: 'Test message', } as any; const result = await service.getMessageIsForBotToHandle(mockMessage, 'issuer-123'); expect(result).toBe(false); }); it('| should return false when message has skip flags', async () => { const mockMessage = { provider: { botId: 'bot-123', botDisplayName: 'Bot', }, content: '[BOT-SKIP] Test message', authorId: 'user-123', isBot: false, channelName: 'test-channel', } as any; spyOn(DyNTS_global_settings, 'bot_settings').and.returnValue({ messageSettings: { skipFlags: ['[BOT-SKIP]'], }, channelSettings: { allowedChannels: ['test-channel'], defaultChannels: [], dmIsAllowed: false, }, allowedUsers: 'all', debugLevel: 1, } as any); (service as any).mainBot_CS = (service as any).getMainBotControlService(); const result = await service.getMessageIsForBotToHandle(mockMessage, 'issuer-123'); expect(result).toBe(false); }); it('| should return false when message is from bot and bots not allowed', async () => { const mockMessage = { provider: { botId: 'bot-123', botDisplayName: 'Bot', }, content: 'Test message', authorId: 'bot-456', isBot: true, channelName: 'test-channel', } as any; spyOn(DyNTS_global_settings, 'bot_settings').and.returnValue({ messageSettings: { skipFlags: [], }, channelSettings: { allowedChannels: ['test-channel'], defaultChannels: [], dmIsAllowed: false, }, allowedUsers: 'all', allowBotsInteractEachOther: false, debugLevel: 1, } as any); (service as any).mainBot_CS = (service as any).getMainBotControlService(); const result = await service.getMessageIsForBotToHandle(mockMessage, 'issuer-123'); expect(result).toBe(false); }); }); describe('| handleIfCommand', () => { it('| should handle command when message is a command', async () => { const mockMessage = { content: '!test', provider: { botId: 'bot-123', }, } as any; (service as any).commands_CS = (service as any).getCommandsControlService(); spyOn(service, 'isCommand').and.returnValue(Promise.resolve(true)); const result = await service.handleIfCommand(mockMessage, 'issuer-123'); expect(result).toBe(true); expect((service as any).commands_CS.handleCommand).toHaveBeenCalledWith(mockMessage, 'issuer-123'); }); it('| should return false when message is not a command', async () => { const mockMessage = { content: 'Regular message', } as any; spyOn(service, 'isCommand').and.returnValue(Promise.resolve(false)); const result = await service.handleIfCommand(mockMessage, 'issuer-123'); expect(result).toBe(false); }); }); describe('| isCommand', () => { it('| should return true when message starts with command operator', async () => { const mockMessage = { content: '!test command', } as any; const orig = (DyNTS_global_settings as { bot_settings?: unknown }).bot_settings; (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = { commandSettings: { commandOperator: '!', commands: [{ command: 'test' }], }, }; const result = await service.isCommand(mockMessage, 'issuer-123'); expect(result).toBe(true); (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = orig; }); it('| should return false when message does not start with command operator', async () => { const mockMessage = { content: 'regular message', } as any; const orig = (DyNTS_global_settings as { bot_settings?: unknown }).bot_settings; (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = { commandSettings: { commandOperator: '!', commands: [], }, }; const result = await service.isCommand(mockMessage, 'issuer-123'); expect(result).toBe(false); (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = orig; }); it('| should return true when no command operator is set', async () => { const mockMessage = { content: 'test', } as any; const orig = (DyNTS_global_settings as { bot_settings?: unknown }).bot_settings; (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = { commandSettings: { commandOperator: '', commands: [{ command: 'test' }], }, }; const result = await service.isCommand(mockMessage, 'issuer-123'); expect(result).toBe(true); (DyNTS_global_settings as { bot_settings: unknown }).bot_settings = orig; }); }); });