Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests for Voice Button component #287

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions __tests__/__mocks__/fileMock.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// __mocks__/fileMock.ts
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a reordering to have constants in alphabetical order plus added to constants: voiceIcon and voiceIconDisabled

export const botAvatar = "../../assets/bot_avatar.svg";
export const audioIcon = "../../assets/audio_icon.svg";
export const audioIconDisabled = "../../assets/audio_icon_disabled.svg";
export const actionDisabledIcon = "../../assets/action_disabled_icon.svg";
export const emojiIcon = "../../assets/emoji_icon.svg";
export const botAvatar = "../../assets/bot_avatar.svg";
export const closeChatIcon = "../../assets/close_chat_icon.svg";
export const emojiIcon = "../../assets/emoji_icon.svg";
export const notificationIcon = "../../assets/notification_icon.svg";
export const notificationIconDisabled = "../../assets/notification_icon_disabled.svg";
export const audioIcon = "../../assets/audio_icon.svg";
export const audioIconDisabled = "../../assets/audio_icon_disabled.svg";
export const sendIcon = "../../assets/send_icon.svg";
export const sendIcon = "../../assets/send_icon.svg";
export const voiceIcon = "../../assets/voice_icon.svg";
export const voiceIconDisabled = "../../assets/voice_icon_disabled.svg";
110 changes: 110 additions & 0 deletions __tests__/components/buttons/VoiceButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
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 VoiceButton from "../../../src/components/Buttons/VoiceButton/VoiceButton";
import { DefaultSettings } from "../../../src/constants/internal/DefaultSettings";
import { useTextAreaInternal } from "../../../src/hooks/internal/useTextAreaInternal";
import { TestChatBotProvider } from "../../__mocks__/TestChatBotContext";
import { voiceIcon, voiceIconDisabled } from "../../__mocks__/fileMock";

jest.mock("../../../src/hooks/internal/useTextAreaInternal");

/**
* Helper function to render VoiceButton with different settings.
*
* @param disabled boolean indicating if voice option is disabled
* @param defaultToggledOn boolean indicating if voice option is toggled on by default
*/
const renderVoiceButton = (disabled: boolean, defaultToggledOn: boolean) => {
const initialSettings = {
voice: {
disabled: disabled,
defaultToggledOn: defaultToggledOn,
icon: voiceIcon,
iconDisabled: voiceIconDisabled,
},
};
return render(
<TestChatBotProvider initialSettings={initialSettings}>
<VoiceButton />
</TestChatBotProvider>
);
};

/**
* Tests for VoiceButton component.
*/

describe("VoiceButton Component", () => {
const voiceIconTestId = "rcb-voice-icon";

beforeEach(() => {
(useTextAreaInternal as jest.Mock).mockReturnValue({
textAreaDisabled: false,
});
});

it("renders with aria-label and initial state when defaultToggledOn is false and not disabled", () => {
renderVoiceButton(false, false);

const button = screen.getByRole("button", {
name: DefaultSettings.ariaLabel?.voiceButton,
});
const icon = screen.getByTestId(voiceIconTestId);

expect(button).toBeInTheDocument();

expect(icon).toHaveStyle("fill: #9aa0a6");
expect(icon.style.backgroundImage).toBe(`url(${voiceIconDisabled})`);
});

it("toggles voice state when clicked (initially off)", () => {
renderVoiceButton(false, false);

const button = screen.getByRole("button", {
name: DefaultSettings.ariaLabel?.voiceButton,
});
const icon = screen.getByTestId(voiceIconTestId);

expect(icon.style.backgroundImage).toBe(`url(${voiceIconDisabled})`);

fireEvent.mouseDown(button);

expect(icon.style.backgroundImage).toBe(`url(${voiceIcon})`);
});

it("renders with voice toggled on initially and toggles to off when clicked", () => {
renderVoiceButton(false, true);

const button = screen.getByRole("button", {
name: DefaultSettings.ariaLabel?.voiceButton,
});
const icon = screen.getByTestId(voiceIconTestId);
expect(icon.style.backgroundImage).toBe(`url(${voiceIcon})`);

fireEvent.mouseDown(button);

expect(icon.style.backgroundImage).toBe(`url(${voiceIconDisabled})`);
});

it("toggles notification back to on after being toggled off", () => {
renderVoiceButton(false, true);

const button = screen.getByRole("button", {
name: DefaultSettings.ariaLabel?.voiceButton,
});
const icon = screen.getByTestId(voiceIconTestId);
expect(icon.style.backgroundImage).toBe(`url(${voiceIcon})`);

fireEvent.mouseDown(button);

expect(icon.style.backgroundImage).toBe(`url(${voiceIconDisabled})`);

fireEvent.mouseDown(button);

expect(icon.style.backgroundImage).toBe(`url(${voiceIcon})`);
});
});
1 change: 1 addition & 0 deletions src/components/Buttons/VoiceButton/VoiceButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const VoiceButton = () => {
return (
<span
className={`rcb-voice-icon${voiceToggledOn && !textAreaDisabled ? "-on" : ""}`}
data-testid="rcb-voice-icon"
style={voiceToggledOn && !textAreaDisabled ? voiceIconStyle : voiceIconDisabledStyle}
/>
)
Expand Down
Loading