1
+ import userEvent from '@testing-library/user-event' ;
2
+
1
3
import {
2
4
createPlayground ,
3
5
createSource ,
@@ -29,6 +31,202 @@ describe('getEnvironmentProps', () => {
29
31
) ;
30
32
} ) ;
31
33
34
+ describe ( 'onMouseDown' , ( ) => {
35
+ test ( 'is a noop when panel is not open and status is idle' , ( ) => {
36
+ const onStateChange = jest . fn ( ) ;
37
+ const {
38
+ getEnvironmentProps,
39
+ inputElement,
40
+ formElement,
41
+ } = createPlayground ( createAutocomplete , { onStateChange } ) ;
42
+ const panelElement = document . createElement ( 'div' ) ;
43
+
44
+ const { onMouseDown } = getEnvironmentProps ( {
45
+ inputElement,
46
+ formElement,
47
+ panelElement,
48
+ } ) ;
49
+ window . addEventListener ( 'mousedown' , onMouseDown ) ;
50
+
51
+ // Dispatch MouseDown event on window
52
+ const customEvent = new CustomEvent ( 'mousedown' , { bubbles : true } ) ;
53
+ window . dispatchEvent ( customEvent ) ;
54
+
55
+ expect ( onStateChange ) . not . toHaveBeenCalled ( ) ;
56
+
57
+ window . removeEventListener ( 'mousedown' , onMouseDown ) ;
58
+ } ) ;
59
+
60
+ test ( 'is a noop when the event target is the input element' , async ( ) => {
61
+ const onStateChange = jest . fn ( ) ;
62
+ const {
63
+ getEnvironmentProps,
64
+ inputElement,
65
+ formElement,
66
+ } = createPlayground ( createAutocomplete , {
67
+ onStateChange,
68
+ openOnFocus : true ,
69
+ getSources ( ) {
70
+ return [
71
+ createSource ( {
72
+ getItems : ( ) => [ { label : '1' } ] ,
73
+ } ) ,
74
+ ] ;
75
+ } ,
76
+ } ) ;
77
+ const panelElement = document . createElement ( 'div' ) ;
78
+
79
+ const { onMouseDown } = getEnvironmentProps ( {
80
+ inputElement,
81
+ formElement,
82
+ panelElement,
83
+ } ) ;
84
+ window . addEventListener ( 'mousedown' , onMouseDown ) ;
85
+
86
+ // Click input (focuses it, which opens the panel)
87
+ userEvent . click ( inputElement ) ;
88
+
89
+ await runAllMicroTasks ( ) ;
90
+
91
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
92
+ expect . objectContaining ( {
93
+ state : expect . objectContaining ( {
94
+ isOpen : true ,
95
+ } ) ,
96
+ } )
97
+ ) ;
98
+
99
+ onStateChange . mockClear ( ) ;
100
+
101
+ // Dispatch MouseDown event on the input (bubbles to window)
102
+ const customEvent = new CustomEvent ( 'mousedown' , { bubbles : true } ) ;
103
+ inputElement . dispatchEvent ( customEvent ) ;
104
+
105
+ await runAllMicroTasks ( ) ;
106
+
107
+ expect ( onStateChange ) . not . toHaveBeenCalled ( ) ;
108
+
109
+ window . removeEventListener ( 'mousedown' , onMouseDown ) ;
110
+ } ) ;
111
+
112
+ test ( 'closes panel and resets `activeItemId` if the target is outside Autocomplete' , async ( ) => {
113
+ const onStateChange = jest . fn ( ) ;
114
+ const {
115
+ getEnvironmentProps,
116
+ inputElement,
117
+ formElement,
118
+ } = createPlayground ( createAutocomplete , {
119
+ onStateChange,
120
+ openOnFocus : true ,
121
+ defaultActiveItemId : 1 ,
122
+ getSources ( ) {
123
+ return [
124
+ createSource ( {
125
+ getItems : ( ) => [ { label : '1' } ] ,
126
+ } ) ,
127
+ ] ;
128
+ } ,
129
+ } ) ;
130
+ const panelElement = document . createElement ( 'div' ) ;
131
+
132
+ const { onMouseDown } = getEnvironmentProps ( {
133
+ inputElement,
134
+ formElement,
135
+ panelElement,
136
+ } ) ;
137
+ window . addEventListener ( 'mousedown' , onMouseDown ) ;
138
+
139
+ // Click input (focuses it, which opens the panel)
140
+ userEvent . click ( inputElement ) ;
141
+
142
+ await runAllMicroTasks ( ) ;
143
+
144
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
145
+ expect . objectContaining ( {
146
+ state : expect . objectContaining ( {
147
+ isOpen : true ,
148
+ } ) ,
149
+ } )
150
+ ) ;
151
+
152
+ onStateChange . mockClear ( ) ;
153
+
154
+ // Dispatch MouseDown event on window (so, outside of Autocomplete)
155
+ const customEvent = new CustomEvent ( 'mousedown' , { bubbles : true } ) ;
156
+ window . document . dispatchEvent ( customEvent ) ;
157
+
158
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
159
+ expect . objectContaining ( {
160
+ state : expect . objectContaining ( {
161
+ isOpen : false ,
162
+ activeItemId : null ,
163
+ } ) ,
164
+ } )
165
+ ) ;
166
+
167
+ window . removeEventListener ( 'mousedown' , onMouseDown ) ;
168
+ } ) ;
169
+
170
+ test ( 'does not close panel nor reset `activeItemId` if the target is outside Autocomplete in debug mode' , async ( ) => {
171
+ const onStateChange = jest . fn ( ) ;
172
+ const {
173
+ getEnvironmentProps,
174
+ inputElement,
175
+ formElement,
176
+ } = createPlayground ( createAutocomplete , {
177
+ onStateChange,
178
+ openOnFocus : true ,
179
+ defaultActiveItemId : 1 ,
180
+ debug : true ,
181
+ getSources ( ) {
182
+ return [
183
+ createSource ( {
184
+ getItems : ( ) => [ { label : '1' } ] ,
185
+ } ) ,
186
+ ] ;
187
+ } ,
188
+ } ) ;
189
+ const panelElement = document . createElement ( 'div' ) ;
190
+
191
+ const { onMouseDown } = getEnvironmentProps ( {
192
+ inputElement,
193
+ formElement,
194
+ panelElement,
195
+ } ) ;
196
+ window . addEventListener ( 'mousedown' , onMouseDown ) ;
197
+
198
+ // Click input (focuses it, which opens the panel)
199
+ userEvent . click ( inputElement ) ;
200
+
201
+ await runAllMicroTasks ( ) ;
202
+
203
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
204
+ expect . objectContaining ( {
205
+ state : expect . objectContaining ( {
206
+ isOpen : true ,
207
+ } ) ,
208
+ } )
209
+ ) ;
210
+
211
+ onStateChange . mockClear ( ) ;
212
+
213
+ // Dispatch MouseDown event on window (so, outside of Autocomplete)
214
+ const customEvent = new CustomEvent ( 'mousedown' , { bubbles : true } ) ;
215
+ window . document . dispatchEvent ( customEvent ) ;
216
+
217
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
218
+ expect . objectContaining ( {
219
+ state : expect . objectContaining ( {
220
+ isOpen : true ,
221
+ activeItemId : 1 ,
222
+ } ) ,
223
+ } )
224
+ ) ;
225
+
226
+ window . removeEventListener ( 'mousedown' , onMouseDown ) ;
227
+ } ) ;
228
+ } ) ;
229
+
32
230
describe ( 'onTouchStart' , ( ) => {
33
231
test ( 'is a noop when panel is not open and status is idle' , ( ) => {
34
232
const onStateChange = jest . fn ( ) ;
@@ -107,7 +305,7 @@ describe('getEnvironmentProps', () => {
107
305
window . removeEventListener ( 'touchstart' , onTouchStart ) ;
108
306
} ) ;
109
307
110
- test ( 'closes panel if the target is outside Autocomplete' , async ( ) => {
308
+ test ( 'closes panel and resets `activeItemId` if the target is outside Autocomplete' , async ( ) => {
111
309
const onStateChange = jest . fn ( ) ;
112
310
const {
113
311
getEnvironmentProps,
@@ -116,6 +314,7 @@ describe('getEnvironmentProps', () => {
116
314
} = createPlayground ( createAutocomplete , {
117
315
onStateChange,
118
316
openOnFocus : true ,
317
+ defaultActiveItemId : 1 ,
119
318
getSources ( ) {
120
319
return [
121
320
createSource ( {
@@ -156,6 +355,66 @@ describe('getEnvironmentProps', () => {
156
355
expect . objectContaining ( {
157
356
state : expect . objectContaining ( {
158
357
isOpen : false ,
358
+ activeItemId : null ,
359
+ } ) ,
360
+ } )
361
+ ) ;
362
+
363
+ window . removeEventListener ( 'touchstart' , onTouchStart ) ;
364
+ } ) ;
365
+
366
+ test ( 'does not close panel nor reset `activeItemId` if the target is outside Autocomplete in debug mode' , async ( ) => {
367
+ const onStateChange = jest . fn ( ) ;
368
+ const {
369
+ getEnvironmentProps,
370
+ inputElement,
371
+ formElement,
372
+ } = createPlayground ( createAutocomplete , {
373
+ onStateChange,
374
+ openOnFocus : true ,
375
+ defaultActiveItemId : 1 ,
376
+ debug : true ,
377
+ getSources ( ) {
378
+ return [
379
+ createSource ( {
380
+ getItems : ( ) => [ { label : '1' } ] ,
381
+ } ) ,
382
+ ] ;
383
+ } ,
384
+ } ) ;
385
+ const panelElement = document . createElement ( 'div' ) ;
386
+
387
+ const { onTouchStart } = getEnvironmentProps ( {
388
+ inputElement,
389
+ formElement,
390
+ panelElement,
391
+ } ) ;
392
+ window . addEventListener ( 'touchstart' , onTouchStart ) ;
393
+
394
+ // Focus input (opens the panel)
395
+ inputElement . focus ( ) ;
396
+
397
+ await runAllMicroTasks ( ) ;
398
+
399
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
400
+ expect . objectContaining ( {
401
+ state : expect . objectContaining ( {
402
+ isOpen : true ,
403
+ } ) ,
404
+ } )
405
+ ) ;
406
+
407
+ onStateChange . mockClear ( ) ;
408
+
409
+ // Dispatch TouchStart event on window (so, outside of Autocomplete)
410
+ const customEvent = new CustomEvent ( 'touchstart' , { bubbles : true } ) ;
411
+ window . document . dispatchEvent ( customEvent ) ;
412
+
413
+ expect ( onStateChange ) . toHaveBeenLastCalledWith (
414
+ expect . objectContaining ( {
415
+ state : expect . objectContaining ( {
416
+ isOpen : true ,
417
+ activeItemId : 1 ,
159
418
} ) ,
160
419
} )
161
420
) ;
0 commit comments