import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { describe, expect, it, vi } from 'vitest';
import { MdClickOutsideWrapper } from '../MdClickOutsideWrapper';
describe('MdClickOutsideWrapper', () => {
describe('rendering', () => {
it('renders children', () => {
render(
{}}>
Content
,
);
expect(screen.getByTestId('content')).toBeInTheDocument();
});
it('renders as div wrapper', () => {
const { container } = render(
{}}>
Content
,
);
expect(container.querySelector('div')).toBeInTheDocument();
});
});
describe('click outside detection', () => {
it('calls onClickOutside when clicking outside', async () => {
const user = userEvent.setup();
const onClickOutside = vi.fn();
render(
Inside
,
);
await user.click(screen.getByTestId('outside'));
expect(onClickOutside).toHaveBeenCalled();
});
it('does not call onClickOutside when clicking inside', async () => {
const user = userEvent.setup();
const onClickOutside = vi.fn();
render(
,
);
await user.click(screen.getByTestId('inside'));
expect(onClickOutside).not.toHaveBeenCalled();
});
it('does not call onClickOutside when clicking on nested child', async () => {
const user = userEvent.setup();
const onClickOutside = vi.fn();
render(
,
);
await user.click(screen.getByTestId('nested'));
expect(onClickOutside).not.toHaveBeenCalled();
});
});
describe('ref forwarding', () => {
it('forwards ref to wrapper div', () => {
const ref = React.createRef();
render(
{}}>
Content
,
);
expect(ref.current).toBeInstanceOf(HTMLDivElement);
});
it('handles function ref', () => {
let refValue: HTMLDivElement | null = null;
render(
{
refValue = el;
}}
onClickOutside={() => {}}
>
Content
,
);
expect(refValue).toBeInstanceOf(HTMLDivElement);
});
});
describe('props forwarding', () => {
it('applies custom className', () => {
const { container } = render(
{}}>
Content
,
);
expect(container.querySelector('.custom-class')).toBeInTheDocument();
});
it('forwards other props', () => {
render(
{}}>
Content
,
);
expect(screen.getByTestId('wrapper')).toBeInTheDocument();
});
});
describe('cleanup', () => {
it('removes event listener on unmount', () => {
const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
const { unmount } = render(
{}}>
Content
,
);
unmount();
expect(removeEventListenerSpy).toHaveBeenCalledWith('click', expect.any(Function), true);
removeEventListenerSpy.mockRestore();
});
});
});