Files
community-rule/tests/unit/hooks/useClickOutside.test.jsx
T
2026-01-28 11:52:42 -07:00

101 lines
2.6 KiB
React

import { renderHook, act } from "@testing-library/react";
import { vi, describe, test, expect, beforeEach, afterEach } from "vitest";
import { useClickOutside } from "../../../app/hooks/useClickOutside";
import { useRef } from "react";
describe("useClickOutside", () => {
let handler;
beforeEach(() => {
handler = vi.fn();
});
afterEach(() => {
vi.clearAllMocks();
});
test("calls handler when clicking outside element", () => {
const { result } = renderHook(() => {
const ref = useRef(null);
useClickOutside([ref], handler, true);
return ref;
});
const div = document.createElement("div");
document.body.appendChild(div);
result.current.current = div;
act(() => {
document.body.dispatchEvent(
new MouseEvent("mousedown", { bubbles: true }),
);
});
expect(handler).toHaveBeenCalledTimes(1);
document.body.removeChild(div);
});
test("does not call handler when clicking inside element", () => {
const { result } = renderHook(() => {
const ref = useRef(null);
useClickOutside([ref], handler, true);
return ref;
});
const div = document.createElement("div");
const innerDiv = document.createElement("div");
div.appendChild(innerDiv);
document.body.appendChild(div);
result.current.current = div;
act(() => {
innerDiv.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
});
expect(handler).not.toHaveBeenCalled();
document.body.removeChild(div);
});
test("does not call handler when disabled", () => {
renderHook(() => {
const ref = useRef(null);
useClickOutside([ref], handler, false);
return ref;
});
act(() => {
document.body.dispatchEvent(
new MouseEvent("mousedown", { bubbles: true }),
);
});
expect(handler).not.toHaveBeenCalled();
});
test("handles multiple refs", () => {
const { result } = renderHook(() => {
const ref1 = useRef(null);
const ref2 = useRef(null);
useClickOutside([ref1, ref2], handler, true);
return { ref1, ref2 };
});
const div1 = document.createElement("div");
const div2 = document.createElement("div");
document.body.appendChild(div1);
document.body.appendChild(div2);
result.current.ref1.current = div1;
result.current.ref2.current = div2;
act(() => {
document.body.dispatchEvent(
new MouseEvent("mousedown", { bubbles: true }),
);
});
expect(handler).toHaveBeenCalledTimes(1);
document.body.removeChild(div1);
document.body.removeChild(div2);
});
});