From 2d3053b4b62706288d7d3143275c209912e2f291 Mon Sep 17 00:00:00 2001 From: Akanni Modupe Adegoke Date: Mon, 21 Oct 2024 16:36:28 +0100 Subject: [PATCH] test: add unit tests for useMessagesInternal hook (#234) --- .../internal/useMessagesInternal.test.ts | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 __tests__/hooks/internal/useMessagesInternal.test.ts diff --git a/__tests__/hooks/internal/useMessagesInternal.test.ts b/__tests__/hooks/internal/useMessagesInternal.test.ts new file mode 100644 index 00000000..51fa7585 --- /dev/null +++ b/__tests__/hooks/internal/useMessagesInternal.test.ts @@ -0,0 +1,122 @@ +import { renderHook } from "@testing-library/react"; +import { act } from "react"; +import { useMessagesInternal } from "../../../src/hooks/internal/useMessagesInternal"; +import { useSettingsContext } from "../../../src/context/SettingsContext"; +import { useMessagesContext } from "../../../src/context/MessagesContext"; +import { useBotStatesContext } from "../../../src/context/BotStatesContext"; +import { useBotRefsContext } from "../../../src/context/BotRefsContext"; +import { useRcbEventInternal } from "../../../src/hooks/internal/useRcbEventInternal"; +import { Message } from "../../../src/types/Message"; + +jest.mock("../../../src/context/SettingsContext"); +jest.mock("../../../src/context/MessagesContext"); +jest.mock("../../../src/context/BotStatesContext"); +jest.mock("../../../src/context/BotRefsContext"); +jest.mock("../../../src/hooks/internal/useRcbEventInternal"); +jest.mock("../../../src/services/AudioService"); +jest.mock("../../../src/services/ChatHistoryService"); + +describe("useMessagesInternal", () => { + const mockSetMessages = jest.fn(); + const mockSetIsBotTyping = jest.fn(); + const mockSetUnreadCount = jest.fn(); + const mockCallRcbEvent = jest.fn(); + const mockStreamMessageMap = { current: new Map() }; + const mockMessages: Message[] = []; + + beforeEach(() => { + jest.clearAllMocks(); + (useSettingsContext as jest.Mock).mockReturnValue({ + settings: { + botBubble: { dangerouslySetInnerHtml: false, simStream: false }, + userBubble: { dangerouslySetInnerHtml: false, simStream: false }, + event: {}, + }, + }); + (useMessagesContext as jest.Mock).mockReturnValue({ + messages: mockMessages, + setMessages: mockSetMessages, + }); + (useBotStatesContext as jest.Mock).mockReturnValue({ + audioToggledOn: false, + isChatWindowOpen: true, + setIsBotTyping: mockSetIsBotTyping, + setUnreadCount: mockSetUnreadCount, + }); + (useBotRefsContext as jest.Mock).mockReturnValue({ + streamMessageMap: mockStreamMessageMap, + }); + (useRcbEventInternal as jest.Mock).mockReturnValue({ + callRcbEvent: mockCallRcbEvent, + }); + }); + + it("should return expected functions and values", () => { + const { result } = renderHook(() => useMessagesInternal()); + + expect(result.current).toHaveProperty("endStreamMessage"); + expect(result.current).toHaveProperty("injectMessage"); + expect(result.current).toHaveProperty("removeMessage"); + expect(result.current).toHaveProperty("streamMessage"); + expect(result.current).toHaveProperty("messages"); + expect(result.current).toHaveProperty("setMessages"); + }); + + it("should inject a message correctly", async () => { + const { result } = renderHook(() => useMessagesInternal()); + + await act(async () => { + const messageId = await result.current.injectMessage("Test message", "bot"); + expect(messageId).toBeTruthy(); + }); + + expect(mockSetMessages).toHaveBeenCalled(); + expect(mockSetUnreadCount).toHaveBeenCalledWith(expect.any(Function)); + }); + + it("should remove a message correctly", async () => { + const mockMessageId = "test-id"; + const mockMessage: Message = { id: mockMessageId, content: "Test", sender: "bot", type: "text", + timestamp: String(Date.now()) }; + (useMessagesContext as jest.Mock).mockReturnValue({ + messages: [mockMessage], + setMessages: mockSetMessages, + }); + + const { result } = renderHook(() => useMessagesInternal()); + + await act(async () => { + const removedId = await result.current.removeMessage(mockMessageId); + expect(removedId).toBe(mockMessageId); + }); + + expect(mockSetMessages).toHaveBeenCalled(); + expect(mockSetUnreadCount).toHaveBeenCalledWith(expect.any(Function)); + }); + + it("should stream a message correctly", async () => { + const { result } = renderHook(() => useMessagesInternal()); + + await act(async () => { + const messageId = await result.current.streamMessage("Test stream", "bot"); + expect(messageId).toBeTruthy(); + }); + + expect(mockSetMessages).toHaveBeenCalled(); + expect(mockSetUnreadCount).toHaveBeenCalledWith(expect.any(Function)); + expect(mockStreamMessageMap.current.has("bot")).toBeTruthy(); + }); + + it("should end stream message correctly", async () => { + mockStreamMessageMap.current.set("bot", "test-id"); + const { result } = renderHook(() => useMessagesInternal()); + + await act(async () => { + const success = await result.current.endStreamMessage("bot"); + expect(success).toBeTruthy(); + }); + + expect(mockStreamMessageMap.current.has("bot")).toBeFalsy(); + }); + +}); \ No newline at end of file