1- import { render , act } from '@testing-library/react' ;
2- import { fireEvent } from '@testing-library/react' ;
3- import { useClickOutside } from '../src/utils/useClickOutside' ; // adjust the import path as needed
4- import React , { useRef } from 'react' ;
5- import { jest , afterEach , beforeEach , describe , expect , test } from "@jest/globals" ;
1+ import { render , act } from "@testing-library/react" ;
2+ import { fireEvent } from "@testing-library/react" ;
3+ import { useClickOutside } from "../src/utils/useClickOutside" ; // adjust the import path as needed
4+ import React , { useRef } from "react" ;
5+ import {
6+ jest ,
7+ afterEach ,
8+ beforeEach ,
9+ describe ,
10+ expect ,
11+ test ,
12+ } from "@jest/globals" ;
613
714// Test component that uses the hook
8- const TestComponent = ( {
9- isActive,
10- onClickOutside,
11- useExcludeRef = false
12- } : {
13- isActive : boolean ;
15+ const TestComponent = ( {
16+ isActive,
17+ onClickOutside,
18+ useExcludeRef = false ,
19+ } : {
20+ isActive : boolean ;
1421 onClickOutside : ( ) => void ;
1522 useExcludeRef ?: boolean ;
1623} ) => {
1724 const ref = useRef < HTMLDivElement > ( null ) ;
1825 const excludeRef = useRef < HTMLButtonElement > ( null ) ;
19-
26+
2027 useClickOutside (
21- ref ,
22- onClickOutside ,
23- isActive ,
24- useExcludeRef ? excludeRef : undefined
28+ ref ,
29+ onClickOutside ,
30+ isActive ,
31+ useExcludeRef ? excludeRef : undefined ,
2532 ) ;
26-
33+
2734 return (
2835 < div >
29- < div data-testid = "inside-element" ref = { ref } > Inside Element</ div >
36+ < div data-testid = "inside-element" ref = { ref } >
37+ Inside Element
38+ </ div >
3039 { useExcludeRef && (
3140 < button data-testid = "excluded-element" ref = { excludeRef } >
3241 Excluded Element
@@ -37,110 +46,124 @@ const TestComponent = ({
3746 ) ;
3847} ;
3948
40- describe ( ' useClickOutside' , ( ) => {
49+ describe ( " useClickOutside" , ( ) => {
4150 // Mock callback function
4251 const mockOnClickOutside = jest . fn ( ) ;
43-
52+
4453 beforeEach ( ( ) => {
4554 // Reset mocks
4655 mockOnClickOutside . mockReset ( ) ;
47-
56+
4857 // Spy on addEventListener and removeEventListener
49- jest . spyOn ( document , ' addEventListener' ) ;
50- jest . spyOn ( document , ' removeEventListener' ) ;
58+ jest . spyOn ( document , " addEventListener" ) ;
59+ jest . spyOn ( document , " removeEventListener" ) ;
5160 } ) ;
52-
61+
5362 afterEach ( ( ) => {
5463 // Restore spies
5564 jest . restoreAllMocks ( ) ;
5665 } ) ;
57-
58- test ( 'should add event listener when isActive is true' , ( ) => {
59- render ( < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ) ;
60-
61- expect ( document . addEventListener ) . toHaveBeenCalledWith ( 'mousedown' , expect . any ( Function ) ) ;
66+
67+ test ( "should add event listener when isActive is true" , ( ) => {
68+ render (
69+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
70+ ) ;
71+
72+ expect ( document . addEventListener ) . toHaveBeenCalledWith (
73+ "mousedown" ,
74+ expect . any ( Function ) ,
75+ ) ;
6276 } ) ;
63-
64- test ( 'should not add event listener when isActive is false' , ( ) => {
65- render ( < TestComponent isActive = { false } onClickOutside = { mockOnClickOutside } /> ) ;
66-
77+
78+ test ( "should not add event listener when isActive is false" , ( ) => {
79+ render (
80+ < TestComponent isActive = { false } onClickOutside = { mockOnClickOutside } /> ,
81+ ) ;
82+
6783 expect ( document . addEventListener ) . not . toHaveBeenCalled ( ) ;
6884 } ) ;
69-
70- test ( ' should remove event listener when isActive changes from true to false' , ( ) => {
85+
86+ test ( " should remove event listener when isActive changes from true to false" , ( ) => {
7187 const { rerender } = render (
72- < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } />
88+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
89+ ) ;
90+
91+ rerender (
92+ < TestComponent isActive = { false } onClickOutside = { mockOnClickOutside } /> ,
93+ ) ;
94+
95+ expect ( document . removeEventListener ) . toHaveBeenCalledWith (
96+ "mousedown" ,
97+ expect . any ( Function ) ,
7398 ) ;
74-
75- rerender ( < TestComponent isActive = { false } onClickOutside = { mockOnClickOutside } /> ) ;
76-
77- expect ( document . removeEventListener ) . toHaveBeenCalledWith ( 'mousedown' , expect . any ( Function ) ) ;
7899 } ) ;
79-
80- test ( ' should call onClickOutside when clicking outside the ref element' , ( ) => {
100+
101+ test ( " should call onClickOutside when clicking outside the ref element" , ( ) => {
81102 const { getByTestId } = render (
82- < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } />
103+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
83104 ) ;
84-
105+
85106 // Simulate clicking outside
86- fireEvent . mouseDown ( getByTestId ( ' outside-element' ) ) ;
87-
107+ fireEvent . mouseDown ( getByTestId ( " outside-element" ) ) ;
108+
88109 expect ( mockOnClickOutside ) . toHaveBeenCalledTimes ( 1 ) ;
89110 } ) ;
90-
91- test ( ' should not call onClickOutside when clicking inside the ref element' , ( ) => {
111+
112+ test ( " should not call onClickOutside when clicking inside the ref element" , ( ) => {
92113 const { getByTestId } = render (
93- < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } />
114+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
94115 ) ;
95-
116+
96117 // Simulate clicking inside
97- fireEvent . mouseDown ( getByTestId ( ' inside-element' ) ) ;
98-
118+ fireEvent . mouseDown ( getByTestId ( " inside-element" ) ) ;
119+
99120 expect ( mockOnClickOutside ) . not . toHaveBeenCalled ( ) ;
100121 } ) ;
101-
102- test ( ' should not call onClickOutside when clicking inside the excluded element' , ( ) => {
122+
123+ test ( " should not call onClickOutside when clicking inside the excluded element" , ( ) => {
103124 const { getByTestId } = render (
104- < TestComponent
105- isActive = { true }
106- onClickOutside = { mockOnClickOutside }
107- useExcludeRef = { true }
108- />
125+ < TestComponent
126+ isActive = { true }
127+ onClickOutside = { mockOnClickOutside }
128+ useExcludeRef = { true }
129+ /> ,
109130 ) ;
110-
131+
111132 // Simulate clicking on the excluded element
112- fireEvent . mouseDown ( getByTestId ( ' excluded-element' ) ) ;
113-
133+ fireEvent . mouseDown ( getByTestId ( " excluded-element" ) ) ;
134+
114135 expect ( mockOnClickOutside ) . not . toHaveBeenCalled ( ) ;
115136 } ) ;
116-
117- test ( ' should clean up event listener when unmounting' , ( ) => {
137+
138+ test ( " should clean up event listener when unmounting" , ( ) => {
118139 const { unmount } = render (
119- < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } />
140+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
120141 ) ;
121-
142+
122143 unmount ( ) ;
123-
144+
124145 expect ( document . removeEventListener ) . toHaveBeenCalled ( ) ;
125146 } ) ;
126-
127- test ( ' should re-attach event listener when dependencies change' , ( ) => {
147+
148+ test ( " should re-attach event listener when dependencies change" , ( ) => {
128149 const newMockCallback = jest . fn ( ) ;
129150 const { rerender } = render (
130- < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } />
151+ < TestComponent isActive = { true } onClickOutside = { mockOnClickOutside } /> ,
131152 ) ;
132-
153+
133154 // First, verify initial setup
134155 expect ( document . addEventListener ) . toHaveBeenCalledTimes ( 1 ) ;
135-
156+
136157 // Reset the spy counts to make verification clearer
137158 jest . clearAllMocks ( ) ;
138-
159+
139160 // Change callback
140- rerender ( < TestComponent isActive = { true } onClickOutside = { newMockCallback } /> ) ;
141-
161+ rerender (
162+ < TestComponent isActive = { true } onClickOutside = { newMockCallback } /> ,
163+ ) ;
164+
142165 // Should remove old listener and add new one
143166 expect ( document . removeEventListener ) . toHaveBeenCalledTimes ( 1 ) ;
144167 expect ( document . addEventListener ) . toHaveBeenCalledTimes ( 1 ) ;
145168 } ) ;
146- } ) ;
169+ } ) ;
0 commit comments