Skip to content

Commit

Permalink
test: add unit test for EmojiButton component (#192)
Browse files Browse the repository at this point in the history
  • Loading branch information
heinthetaung-dev authored Oct 11, 2024
1 parent 6aa5057 commit 33b908a
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 1 deletion.
4 changes: 3 additions & 1 deletion __tests__/__mocks__/fileMock.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// __mocks__/fileMock.ts
export const botAvatar = "../../assets/bot_avatar.svg";
export const botAvatar = "../../assets/bot_avatar.svg";
export const actionDisabledIcon = "../../assets/action_disabled_icon.svg";
export const emojiIcon = "../../assets/emoji_icon.svg";
177 changes: 177 additions & 0 deletions __tests__/components/buttons/EmojiButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
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 EmojiButton from "../../../src/components/Buttons/EmojiButton/EmojiButton";
import { useTextAreaInternal } from "../../../src/hooks/internal/useTextAreaInternal";
import { useBotRefsContext } from "../../../src/context/BotRefsContext";
import { useSettingsContext } from "../../../src/context/SettingsContext";
import { DefaultSettings } from "../../../src/constants/internal/DefaultSettings";
import { useStylesContext } from "../../../src/context/StylesContext";
import { actionDisabledIcon, emojiIcon } from "../../__mocks__/fileMock";
jest.mock("../../../src/context/BotRefsContext");
jest.mock("../../../src/context/SettingsContext");
jest.mock("../../../src/hooks/internal/useTextAreaInternal");
jest.mock("../../../src/context/StylesContext");

describe("EmojiButton component", () => {
const mockInputRef = { current: document.createElement("input") };
mockInputRef.current.value = "";

const mockSetTextAreaValue = jest.fn();

beforeEach(() => {
(useTextAreaInternal as jest.Mock).mockReturnValue({
textAreaDisabled: false,
setTextAreaValue: mockSetTextAreaValue
});
(useBotRefsContext as jest.Mock).mockReturnValue({
inputRef: mockInputRef
});
(useSettingsContext as jest.Mock).mockReturnValue({
settings: {
general: {
primaryColor: DefaultSettings.general?.primaryColor,
secondaryColor: DefaultSettings.general?.secondaryColor,
actionDisabledIcon: actionDisabledIcon
},
ariaLabel: {
emojiButton: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker"
},
emoji: {
disabled: false,
icon: emojiIcon,
list: DefaultSettings.emoji?.list ?? ["😀"]
}
}
});

(useStylesContext as jest.Mock).mockReturnValue({
styles: {
emojiButtonStyle: {},
emojiButtonDisabledStyle: {},
emojiIconStyle: {},
emojiIconDisabledStyle: {}
}
});
});

it("renders EmojiButton correctly and displays emoji popup on click", () => {
render(<EmojiButton />);
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });
const icon = button.querySelector("span");

// check if the emoji button is in the document
expect(button).toBeInTheDocument();
expect(button).toHaveClass("rcb-emoji-button-enabled");
expect(icon).toBeInTheDocument();
expect(icon).toHaveClass("rcb-emoji-icon-enabled");

// click the emoji button to open the popup
fireEvent.mouseDown(button);

// check if the emoji popup is in the document
const popup = screen.getByText(DefaultSettings.emoji?.list?.[0] ?? "😀").closest("div");
expect(popup).toBeInTheDocument();

// select the first emoji in the popup and check if it is in the document
const emoji = popup?.querySelector("span");
expect(emoji).toBeInTheDocument();
expect(emoji).toHaveClass("rcb-emoji");
});

it("dismisses emoji popup when clicking outside", () => {
render(<EmojiButton />);
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });

// click the emoji button to open the popup
fireEvent.mouseDown(button);

// click outside the popup to close the emoji popup
fireEvent.mouseDown(document.body);

// check if the emoji popup is dismissed
const popup = screen.queryByText(DefaultSettings.emoji?.list?.[0] ?? "😀")?.closest("div");
expect(popup).toBeUndefined();
});

it("dismisses emoji popup when clicking the emoji button again", () => {
render(<EmojiButton />);
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });

// click the emoji button to open the popup
fireEvent.mouseDown(button);

// check if the emoji popup is in the document
let popup = screen.queryByText(DefaultSettings.emoji?.list?.[0] ?? "😀")?.closest("div");
expect(popup).toBeInTheDocument();

// click the emoji button again to close the popup
fireEvent.mouseDown(button);

// check if the emoji popup is dismissed
popup = screen.queryByText(DefaultSettings.emoji?.list?.[0] ?? "😀")?.closest("div");
expect(popup).toBeUndefined();
});


it("selecting emoji and displays it in the text area", () => {
// allow jest to control useTimeout
jest.useFakeTimers();

render(<EmojiButton />);
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });

// click the emoji button to open the popup
fireEvent.mouseDown(button);

// check if the emoji popup is in the document
const emoji = screen.getByText(DefaultSettings.emoji?.list?.[0] ?? "😀")

// click the emoji to select it
fireEvent.mouseDown(emoji);

// let setTimeout inside handleEmojiClick to run
jest.runAllTimers();

// check if the emoji is selected
expect(mockSetTextAreaValue).toHaveBeenCalledWith(DefaultSettings.emoji?.list?.[0] ?? "😀");
});

it("emoji button is disabled when text area is disabled", () => {
// mock the text area to be disabled
(useTextAreaInternal as jest.Mock).mockReturnValue({
textAreaDisabled: true,
});

render(<EmojiButton />);

// check if the emoji button is disabled when the text area is disabled
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });
expect(button).toHaveClass("rcb-emoji-button-disabled");

fireEvent.mouseDown(button);

// check if the emoji popup is not in the document
const popup = screen.queryByText(DefaultSettings.emoji?.list?.[0] ?? "😀")?.closest("div");
expect(popup).toBeUndefined();
});

it("updates popupRef when window is resized", () => {
render(<EmojiButton />);
const button = screen.getByRole("button", { name: DefaultSettings.ariaLabel?.emojiButton ?? "emoji picker" });

// Open the emoji popup
fireEvent.mouseDown(button);

const popup = screen.queryByText(DefaultSettings.emoji?.list?.[0] ?? "😀")?.closest("div");
expect(popup).toBeInTheDocument();

// Simulate window resize
fireEvent.resize(window);

expect(popup).toHaveAttribute("style");
})
});

0 comments on commit 33b908a

Please sign in to comment.