import { DyNTS_Msg_Main_ControlService } from './msg-main.control-service'; import { DyNTS_Msg_Events_Service } from './msg-events.service'; import { DyNTS_GlobalService } from '../../../_services/core/global.service'; import { DyFM_Msg_Message, DyFM_Msg_Conversation, DyFM_Msg_Status, DyFM_Msg_Type, DyFM_Msg_ConversationType, DyFM_Msg_ParticipantRole, } from '@futdevpro/fsm-dynamo/messaging'; import { DyFM_Error, DyFM_EnvironmentFlag } from '@futdevpro/fsm-dynamo'; import { DyNTS_global_settings } from '../../../_collections/global-settings.const'; describe('| DyNTS_Msg_Main_ControlService', () => { let service: DyNTS_Msg_Main_ControlService; let mockDBService: jasmine.SpyObj; let mockEventsService: jasmine.SpyObj; beforeAll(() => { if (!DyNTS_global_settings.systemShortCodeName) { (DyNTS_global_settings as any).systemShortCodeName = 'TEST'; } if (!DyNTS_global_settings.env_settings) { (DyNTS_global_settings as any).env_settings = { environment: DyFM_EnvironmentFlag.local }; } }); beforeEach(() => { mockDBService = jasmine.createSpyObj('DyNTS_DBService', [ 'getAll', 'getDataById', 'getDataListByIds', 'getDataByDependencyId', 'getDataListByDependencyIds', 'getDataListByDependencyId', 'findOne', 'find', 'updateOne', 'createData', 'modifyData', 'markDeletedById', 'trueDeleteDataById', 'trueDeleteAllData', 'restoreDeletedById', ]); mockEventsService = jasmine.createSpyObj('DyNTS_Msg_Events_Service', [ 'emitMessageSent', 'emitMessageUpdated', 'emitMessageDeleted', 'emitMessageRead', 'emitReactionAdded', 'emitReactionRemoved', 'emitConversationCreated', 'emitConversationUpdated', 'emitConversationDeleted', 'emitParticipantAdded', 'emitParticipantRemoved', ]); spyOn(DyNTS_GlobalService, 'getDBService').and.returnValue(mockDBService); spyOn(DyNTS_GlobalService, 'getDBServiceByKey').and.returnValue(mockDBService); spyOn(DyNTS_Msg_Events_Service, 'getInstance').and.returnValue(mockEventsService); service = DyNTS_Msg_Main_ControlService.getInstance(); (service as any).eventsService = mockEventsService; }); it('| should be a singleton instance', () => { const instance1 = DyNTS_Msg_Main_ControlService.getInstance(); const instance2 = DyNTS_Msg_Main_ControlService.getInstance(); expect(instance1).toBe(instance2); expect(instance1).toBeInstanceOf(DyNTS_Msg_Main_ControlService); }); describe('| deleteMessage', () => { it('| should delete a message successfully', async () => { const mockMessage = new DyFM_Msg_Message({ _id: 'msg-123', conversationId: 'conv-123', senderId: 'user-123', content: 'Test message', type: DyFM_Msg_Type.text, status: DyFM_Msg_Status.sent, }); mockDBService.getDataById.and.returnValue(Promise.resolve(mockMessage)); mockDBService.markDeletedById.and.returnValue(Promise.resolve()); await service.deleteMessage('msg-123', 'user-123', 'issuer-123'); expect(mockDBService.markDeletedById).toHaveBeenCalledWith('msg-123', 'issuer-123'); expect(mockEventsService.emitMessageDeleted).toHaveBeenCalled(); }); it('| should throw error when user is not the sender', async () => { const mockMessage = new DyFM_Msg_Message({ _id: 'msg-123', conversationId: 'conv-123', senderId: 'user-123', content: 'Test message', type: DyFM_Msg_Type.text, status: DyFM_Msg_Status.sent, }); mockDBService.getDataById.and.returnValue(Promise.resolve(mockMessage)); await expectAsync( service.deleteMessage('msg-123', 'user-456', 'issuer-123') ).toBeRejectedWith(jasmine.any(DyFM_Error)); }); }); describe('| deleteConversation', () => { it('| should delete conversation when user is owner', async () => { const mockConversation = new DyFM_Msg_Conversation({ _id: 'conv-123', type: DyFM_Msg_ConversationType.direct, participants: [ { userId: 'user-123', role: DyFM_Msg_ParticipantRole.owner, joinedAt: new Date() }, ], }); mockDBService.getDataById.and.returnValue(Promise.resolve(mockConversation)); mockDBService.markDeletedById.and.returnValue(Promise.resolve()); await service.deleteConversation('conv-123', 'user-123', 'issuer-123'); expect(mockDBService.markDeletedById).toHaveBeenCalledWith('conv-123', 'issuer-123'); expect(mockEventsService.emitConversationDeleted).toHaveBeenCalled(); }); it('| should throw error when user is not owner or admin', async () => { const mockConversation = new DyFM_Msg_Conversation({ _id: 'conv-123', type: DyFM_Msg_ConversationType.direct, participants: [ { userId: 'user-123', role: DyFM_Msg_ParticipantRole.member, joinedAt: new Date() }, ], }); mockDBService.getDataById.and.returnValue(Promise.resolve(mockConversation)); await expectAsync( service.deleteConversation('conv-123', 'user-123', 'issuer-123') ).toBeRejectedWith(jasmine.any(DyFM_Error)); }); }); });