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

[FEQ]Yaswanth/FEQ-1980 Added test cases for toggle switch component #138

62 changes: 62 additions & 0 deletions src/components/ToggleSwitch/__test__/ToggleSwitch.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from "react";
import { render } from "@testing-library/react";
import { ToggleSwitch } from "..";
import userEvent from "@testing-library/user-event";

describe("ToggleSwitch Component", () => {
it("should renders with correct value passed as prop", () => {
const { getByRole, rerender } = render(<ToggleSwitch value={true} />);
const toggleSwitch = getByRole("checkbox");
expect(toggleSwitch).toBeChecked();
rerender(<ToggleSwitch value={false} />);
expect(toggleSwitch).not.toBeChecked();
});

it("should be set to false when no value prop is provided", () => {
const { getByRole } = render(<ToggleSwitch/>);
const toggleSwitch = getByRole("checkbox");
expect(toggleSwitch).not.toBeChecked();
});
it("should update the value when user clicks on it", async () => {
const { getByRole } = render(<ToggleSwitch/>);
const toggleSwitch = getByRole("checkbox");
expect(toggleSwitch).not.toBeChecked();
await userEvent.click(toggleSwitch);
expect(toggleSwitch).toBeChecked();
});

it("should call the onChange prop when user clicks on it", async () => {
const mockedOnChange = jest.fn();
const { getByRole } = render(<ToggleSwitch onChange={mockedOnChange} />);
const toggleSwitch = getByRole("checkbox");
await userEvent.click(toggleSwitch);
expect(mockedOnChange).toHaveBeenCalled();
});


it("should apply wrapperClassName and className correctly", () => {
const { container } = render(
<ToggleSwitch
wrapperClassName="wrapper-class"
className="custom-class"
/>
);
const wrapper = container.querySelector(".deriv-toggle-switch.wrapper-class");
expect(wrapper).toBeInTheDocument();
const input = wrapper?.querySelector("input");
expect(input).toHaveClass("custom-class");
});

it("applies wrapperStyle and style correctly", () => {
const { container } = render(
<ToggleSwitch
wrapperStyle={{ backgroundColor: "red" }}
style={{ fontSize: "16px" }}
/>
);
const input = container.querySelector(".deriv-toggle-switch input");
expect(input).toHaveStyle({ fontSize: "16px" });
const label = input?.parentElement;
expect(label).toHaveStyle({ backgroundColor: "red" });
});
});
62 changes: 42 additions & 20 deletions src/components/ToggleSwitch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { ChangeEvent, forwardRef } from "react";
import React, { ChangeEvent, forwardRef, useEffect, useState } from "react";
import clsx from "clsx";
import { Input } from "../Input";
import "./ToggleSwitch.scss";

interface ToggleSwitchProps {
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
value: boolean;
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
value?: boolean;
wrapperClassName?: React.ComponentProps<typeof Input>["wrapperClassName"];
className?: React.ComponentProps<typeof Input>["className"];
wrapperStyle?: React.CSSProperties;
Expand All @@ -14,22 +14,44 @@ interface ToggleSwitchProps {

export const ToggleSwitch = forwardRef<HTMLInputElement, ToggleSwitchProps>(
(
{ onChange, value, wrapperClassName, className, wrapperStyle, style },
{
onChange,
value = false,
wrapperClassName,
className,
wrapperStyle,
style,
},
ref,
) => (
<label
className={clsx("deriv-toggle-switch", wrapperClassName)}
style={wrapperStyle}
>
<input
checked={value}
onChange={onChange}
ref={ref}
type="checkbox"
className={clsx(className)}
style={style}
/>
<span className="deriv-toggle-switch__slider" />
</label>
),
) => {
const [isChecked, setIsChecked] = useState<boolean>(value);

useEffect(() => {
if (value !== undefined) {
setIsChecked(value);
}
}, [value]);

const onClickHandler = (event: ChangeEvent<HTMLInputElement>) => {
setIsChecked(!isChecked);
onChange?.(event);
};

return (
<label
className={clsx("deriv-toggle-switch", wrapperClassName)}
style={wrapperStyle}
>
<input
checked={isChecked}
onChange={onClickHandler}
ref={ref}
type="checkbox"
className={clsx(className)}
style={style}
/>
<span className="deriv-toggle-switch__slider" />
</label>
);
},
);
2 changes: 1 addition & 1 deletion stories/Badge.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const ContainedPurpleRounded: Story = {
};

export const ContainedRed: Story = {
name: "Contained (Yellow)",
name: "Contained (Red)",
args: {
...meta.args,
color: "danger",
Expand Down
7 changes: 1 addition & 6 deletions stories/ToggleSwitch.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ToggleSwitch } from "../src/components/ToggleSwitch";
const meta = {
title: "Components/ToggleSwitch",
component: ToggleSwitch,
tags: ["autodocs"],
args: {
onChange: action("ToggleSwitch changed"),
value: false,
Expand All @@ -22,9 +23,3 @@ export const Default: Story = {
},
};

export const Checked: Story = {
args: {
...Default.args,
value: true,
},
};