Extract custom hooks for reusable logic
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
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: ReturnType<typeof vi.fn>;
|
||||
|
||||
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", () => {
|
||||
const { result } = 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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user