From 1674d5e42a09ff5e727dd00433abc6a080efa1b6 Mon Sep 17 00:00:00 2001 From: Julian Echeverry Date: Mon, 7 Oct 2024 19:16:08 -0500 Subject: [PATCH] test: added test for CloseChatButton #139 (#153) --- .../buttons/CloseChatButton.test.tsx | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 __tests__/components/buttons/CloseChatButton.test.tsx diff --git a/__tests__/components/buttons/CloseChatButton.test.tsx b/__tests__/components/buttons/CloseChatButton.test.tsx new file mode 100644 index 00000000..71bf39c0 --- /dev/null +++ b/__tests__/components/buttons/CloseChatButton.test.tsx @@ -0,0 +1,187 @@ +import React from "react"; + +import { expect } from "@jest/globals"; +import { render, screen, fireEvent } from "@testing-library/react"; +import "@testing-library/jest-dom/jest-globals"; + +import CloseChatButton from "../../../src/components/Buttons/CloseChatButton/CloseChatButton"; +import { DefaultSettings } from "../../../src/constants/internal/DefaultSettings"; + +import { useChatWindowInternal } from "../../../src/hooks/internal/useChatWindowInternal"; +import { useSettingsContext } from "../../../src/context/SettingsContext"; +import { useStylesContext } from "../../../src/context/StylesContext"; + +// Mock the hooks used in the component +jest.mock("../../../src/hooks/internal/useChatWindowInternal"); +jest.mock("../../../src/context/SettingsContext"); +jest.mock("../../../src/context/StylesContext"); + +/** + * Test for CloseChatButton component. + */ +describe("CloseChatButton", () => { + const openChatMock = jest.fn(); + + beforeEach(() => { + // Mock the return value of useChatWindowInternal hook + (useChatWindowInternal as jest.Mock).mockReturnValue({ + openChat: openChatMock, + }); + + // Mock the return value of useSettingsContext hook + (useSettingsContext as jest.Mock).mockReturnValue({ + settings: { + header: { closeChatIcon: DefaultSettings.header?.closeChatIcon }, + ariaLabel: { closeChatButton: DefaultSettings.ariaLabel?.closeChatButton }, + }, + }); + + // Mock the return value of useStylesContext hook + (useStylesContext as jest.Mock).mockReturnValue({ + styles: { + closeChatIconStyle: { color: "red" }, + closeChatButtonStyle: { backgroundColor: "gray" }, + }, + }); + }); + + it("renders the CloseChatButton component", () => { + // Render the CloseChatButton component + render(); + + // Get the button element by its role and name using default settings + const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.closeChatButton }); + + // Assert that the button is in the document + expect(button).toBeInTheDocument(); + }); + + it("displays the correct aria-label", () => { + // Render the CloseChatButton component + render(); + // Get the button element by its role and name using default settings + const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.closeChatButton }); + + // Assert that the button has the correct aria-label attribute + expect(button).toHaveAttribute("aria-label", DefaultSettings.ariaLabel?.closeChatButton); + }); + + it("applies the correct background image to the close chat icon", () => { + // Render the CloseChatButton component + render(); + // Get the button element by its role + const button = screen.getByRole("button"); + // Get the span element inside the button (assumed to be the icon) + const icon = button.querySelector("span"); + + // Check if the background image is set correctly + expect(icon).toHaveStyle(`background-image: url(${DefaultSettings.header?.closeChatIcon})`); + }); + + it("applies the default aria-label when none is provided in settings", () => { + // Mock settings without ariaLabel.closeChatButton + (useSettingsContext as jest.Mock).mockReturnValue({ + settings: { + header: { closeChatIcon: DefaultSettings.header?.closeChatIcon }, + ariaLabel: {}, + }, + }); + + render(); + + // Check if the aria-label falls back to "close chat" + const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.closeChatButton }); + expect(button).toHaveAttribute("aria-label", DefaultSettings.ariaLabel?.closeChatButton); + }); + + it("applies the correct styles to the button and icon", () => { + // Render the CloseChatButton component + render(); + // Get the button element by its role + const button = screen.getByRole("button"); + // Get the span element inside the button (assumed to be the icon) + const icon = button.querySelector("span"); + + // Assert that the button has the correct background color + expect(button).toHaveStyle("background-color: gray"); + // Assert that the icon has the correct color + expect(icon).toHaveStyle("color: red"); + // Assert that the icon has the correct background image + expect(icon).toHaveStyle(`background-image: url(${DefaultSettings.header?.closeChatIcon})`); + }); + + it("calls openChat(false) when the button is clicked", () => { + // Render the CloseChatButton component + render(); + // Get the button element by its role + const button = screen.getByRole("button"); + // Fire the mouseDown event on the button + fireEvent.mouseDown(button); + // Assert that openChatMock was called with false + expect(openChatMock).toHaveBeenCalledWith(false); + }); + + it("stops propagation of mouse down event", () => { + // Render the component + render(); + const button = screen.getByRole("button"); + + // Spy on the stopPropagation method of the event + const stopPropagationSpy = jest.spyOn(MouseEvent.prototype, "stopPropagation"); + + // Fire the mouseDown event + fireEvent.mouseDown(button); + + // Assert that stopPropagation was called + expect(stopPropagationSpy).toHaveBeenCalled(); + + // Clean up the spy + stopPropagationSpy.mockRestore(); + }); + + it("handles undefined settings.header gracefully", () => { + // Mock settings with undefined header + (useSettingsContext as jest.Mock).mockReturnValue({ + settings: { + header: undefined, // Simulate missing header + ariaLabel: { closeChatButton: DefaultSettings.ariaLabel?.closeChatButton }, + }, + }); + + (useStylesContext as jest.Mock).mockReturnValue({ + styles: { + closeChatIconStyle: { color: "red" }, + closeChatButtonStyle: { backgroundColor: "gray" }, + }, + }); + + render(); + + // Check that it renders without crashing + const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.closeChatButton }); + expect(button).toBeInTheDocument(); + }); + + it("handles undefined settings.ariaLabel gracefully", () => { + // Mock settings without ariaLabel + (useSettingsContext as jest.Mock).mockReturnValue({ + settings: { + header: { closeChatIcon: DefaultSettings.header?.closeChatIcon }, + ariaLabel: undefined, // Simulate missing ariaLabel + }, + }); + + (useStylesContext as jest.Mock).mockReturnValue({ + styles: { + closeChatIconStyle: { color: "red" }, + closeChatButtonStyle: { backgroundColor: "gray" }, + }, + }); + + render(); + + // Check that it falls back to the default aria-label + const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.closeChatButton }); + expect(button).toHaveAttribute("aria-label", DefaultSettings.ariaLabel?.closeChatButton); + }); +});