import { ForbiddenException } from "@nestjs/common"; import { Test, TestingModule } from "@nestjs/testing"; import { EventsGateway } from "../realtime/events.gateway"; import { UsersService } from "../users/users.service"; import { MessagesService } from "./messages.service"; import { MessagesRepository } from "./repositories/messages.repository"; describe("MessagesService", () => { let service: MessagesService; let _repository: MessagesRepository; let _eventsGateway: EventsGateway; const mockMessagesRepository = { findConversationBetweenUsers: jest.fn(), createConversation: jest.fn(), addParticipant: jest.fn(), createMessage: jest.fn(), findAllConversations: jest.fn(), isParticipant: jest.fn(), getParticipants: jest.fn(), findMessagesByConversationId: jest.fn(), markAsRead: jest.fn(), countUnreadMessages: jest.fn(), }; const mockEventsGateway = { sendToUser: jest.fn(), }; const mockUsersService = { findOne: jest.fn(), }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ MessagesService, { provide: MessagesRepository, useValue: mockMessagesRepository }, { provide: EventsGateway, useValue: mockEventsGateway }, { provide: UsersService, useValue: mockUsersService }, ], }).compile(); service = module.get(MessagesService); _repository = module.get(MessagesRepository); _eventsGateway = module.get(EventsGateway); }); describe("sendMessage", () => { it("should send message to existing conversation", async () => { const senderId = "s1"; const dto = { recipientId: "r1", text: "hello" }; mockMessagesRepository.findConversationBetweenUsers.mockResolvedValue({ id: "conv1", }); mockMessagesRepository.createMessage.mockResolvedValue({ id: "m1", text: "hello", }); const result = await service.sendMessage(senderId, dto); expect(result.id).toBe("m1"); expect(mockEventsGateway.sendToUser).toHaveBeenCalledWith( "r1", "new_message", expect.anything(), ); }); it("should create new conversation if not exists", async () => { const senderId = "s1"; const dto = { recipientId: "r1", text: "hello" }; mockMessagesRepository.findConversationBetweenUsers.mockResolvedValue(null); mockMessagesRepository.createConversation.mockResolvedValue({ id: "new_conv", }); mockMessagesRepository.createMessage.mockResolvedValue({ id: "m1" }); await service.sendMessage(senderId, dto); expect(mockMessagesRepository.createConversation).toHaveBeenCalled(); expect(mockMessagesRepository.addParticipant).toHaveBeenCalledTimes(2); }); }); describe("getMessages", () => { it("should return messages if user is participant", async () => { mockMessagesRepository.isParticipant.mockResolvedValue(true); mockMessagesRepository.findMessagesByConversationId.mockResolvedValue([ { id: "m1" }, ]); const result = await service.getMessages("u1", "conv1"); expect(result).toHaveLength(1); }); it("should throw ForbiddenException if user is not participant", async () => { mockMessagesRepository.isParticipant.mockResolvedValue(false); await expect(service.getMessages("u1", "conv1")).rejects.toThrow( ForbiddenException, ); }); }); });