Skip to content

Commit

Permalink
main 🧊 rework use click outside test
Browse files Browse the repository at this point in the history
  • Loading branch information
debabin committed Jun 4, 2024
1 parent f7f47d8 commit d54e64a
Showing 1 changed file with 51 additions and 74 deletions.
125 changes: 51 additions & 74 deletions src/hooks/useClickOutside/useClickOutside.test.ts
Original file line number Diff line number Diff line change
@@ -1,164 +1,141 @@
import { act, fireEvent, renderHook } from '@testing-library/react';
import { act, renderHook } from '@testing-library/react';

import { useClickOutside } from './useClickOutside';

it('Should return ref when there is no target', () => {
const callback = vi.fn();

const { result } = renderHook(() => useClickOutside(callback));
it('Should use click outside', () => {
const { result } = renderHook(() => useClickOutside(vi.fn()));

expect(result.current).toEqual({ current: null });
});

it('Should call callback on mousedown and touchstart events', () => {
const element = document.createElement('div');
it('Should not call callback when ref connected to the document', () => {
const callback = vi.fn();

renderHook(() => useClickOutside(element, callback));
const element = document.createElement('div');

expect(callback).not.toBeCalled();
const { result } = renderHook(() => useClickOutside(callback));
Object.assign(result.current, { current: element });

act(() => {
fireEvent.mouseDown(document);
fireEvent.touchStart(document);
document.dispatchEvent(new Event('mousedown'));
document.dispatchEvent(new Event('touchstart'));
});

expect(callback).toBeCalledTimes(2);
});

it('Should call callback when clicked outside the element (ref)', () => {
const ref = { current: document.createElement('div') };
it('Should call callback when clicked outside the element', () => {
const callback = vi.fn();
const element = document.createElement('div');

renderHook(() => useClickOutside(ref, callback));
renderHook(() => useClickOutside(element, callback));

expect(callback).not.toBeCalled();

act(() => {
fireEvent.touchStart(document);
document.dispatchEvent(new Event('mousedown'));
document.dispatchEvent(new Event('touchstart'));
});

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledTimes(2);
});

it('Should call callback when clicked outside the element (Element)', () => {
const element = document.createElement('div');
it('Should call callback when clicked outside the ref', () => {
const callback = vi.fn();
const ref = { current: document.createElement('div') };

renderHook(() => useClickOutside(element, callback));
renderHook(() => useClickOutside(ref, callback));

expect(callback).not.toBeCalled();

act(() => {
fireEvent.touchStart(document);
document.dispatchEvent(new Event('mousedown'));
document.dispatchEvent(new Event('touchstart'));
});

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledTimes(2);
});

it('Should call callback when clicked outside the element (function that returns an Element)', () => {
const getElement = () => document.createElement('div');
it('Should call callback when clicked outside the function that returns an element', () => {
const callback = vi.fn();
const getElement = () => document.createElement('div');

renderHook(() => useClickOutside(getElement, callback));

expect(callback).not.toBeCalled();

act(() => {
fireEvent.touchStart(document);
document.dispatchEvent(new Event('mousedown'));
document.dispatchEvent(new Event('touchstart'));
});

expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledTimes(2);
});

it('Should call callback when clicked outside the element (multiple targets)', () => {
const element = document.createElement('div');
const elementForGetElementFunction = document.createElement('div');
const getElement = () => elementForGetElementFunction;
const ref = { current: document.createElement('div') };
it('Should not call callback when clicked inside the ref', () => {
const callback = vi.fn();

renderHook(() => useClickOutside([element, ref, getElement], callback));

act(() => {
document.body.appendChild(element);
document.body.appendChild(elementForGetElementFunction);
document.body.appendChild(ref.current);
fireEvent.touchStart(element);
fireEvent.touchStart(elementForGetElementFunction);
fireEvent.touchStart(ref.current);
});

expect(callback).toBeCalledTimes(6);
});

it('Should not call callback when clicked inside the element (ref)', () => {
const ref = { current: document.createElement('div') };
const callback = vi.fn();
document.body.appendChild(ref.current);

renderHook(() => useClickOutside(ref, callback));

act(() => {
document.body.appendChild(ref.current);
fireEvent.touchStart(ref.current);
ref.current.dispatchEvent(new Event('mousedown'));
ref.current.dispatchEvent(new Event('touchstart'));
});

expect(callback).not.toBeCalled();
});

it('Should not call callback when clicked inside the element (Element)', () => {
it('Should not call callback when clicked inside the element', () => {
const element = document.createElement('div');
document.body.appendChild(element);

const callback = vi.fn();

renderHook(() => useClickOutside(element, callback));

act(() => {
document.body.appendChild(element);
fireEvent.touchStart(element);
element.dispatchEvent(new Event('mousedown'));
element.dispatchEvent(new Event('touchstart'));
});

expect(callback).not.toBeCalled();
});

it('Should not call callback when clicked inside the element (function that returns an Element)', () => {
it('Should not call callback when clicked inside the function that returns an element', () => {
const element = document.createElement('div');
document.body.appendChild(element);

const getElement = () => element;
const callback = vi.fn();

renderHook(() => useClickOutside(getElement, callback));

act(() => {
document.body.appendChild(element);
fireEvent.touchStart(element);
element.dispatchEvent(new Event('mousedown'));
element.dispatchEvent(new Event('touchstart'));
});

expect(callback).not.toBeCalled();
});

it('Should not call callback when clicked a non-connected element', () => {
const ref = { current: document.createElement('div') };
const callback = vi.fn();

renderHook(() => useClickOutside(ref, callback));
it('Should call callback when clicked outside the element (multiple targets)', () => {
const element = document.createElement('div');
document.body.appendChild(element);

act(() => {
const element = document.createElement('div');
document.body.appendChild(element);
document.body.removeChild(element);
fireEvent.touchStart(element);
});
const elementForGetElementFunction = document.createElement('div');
document.body.appendChild(elementForGetElementFunction);
const getElement = () => elementForGetElementFunction;

expect(callback).not.toBeCalled();
});
const ref = { current: document.createElement('div') };
document.body.appendChild(ref.current);

it('Should not call callback when ref does not pass in DOM element', () => {
const callback = vi.fn();

renderHook(() => useClickOutside(callback));
renderHook(() => useClickOutside([element, ref, getElement], callback));

act(() => {
fireEvent.touchStart(document);
});
act(() => document.dispatchEvent(new Event('mousedown')));

expect(callback).not.toBeCalled();
expect(callback).toBeCalledTimes(3);
});

0 comments on commit d54e64a

Please sign in to comment.