@@ -2,7 +2,9 @@ import React from 'react';
2
2
import { cleanup , fireEvent , render , waitFor } from '@testing-library/react' ;
3
3
import '@testing-library/jest-dom' ;
4
4
import TreeView , { ITreeNodeItemProps } from '../index' ;
5
- import { dragToTargetNode } from '@test/utils' ;
5
+ import { dragToTargetNode , expectFnCalled , sleep } from '@test/utils' ;
6
+ import { act } from 'react-test-renderer' ;
7
+ import { unexpandTreeNodeClassName , expandTreeNodeClassName } from '../base' ;
6
8
7
9
const mockData : ITreeNodeItemProps [ ] = [
8
10
{
@@ -23,6 +25,15 @@ const mockData: ITreeNodeItemProps[] = [
23
25
} ,
24
26
] ;
25
27
28
+ // mock Scrollable component
29
+ jest . mock ( 'lodash' , ( ) => {
30
+ const originalModule = jest . requireActual ( 'lodash' ) ;
31
+ return {
32
+ ...originalModule ,
33
+ debounce : ( fn ) => fn ,
34
+ } ;
35
+ } ) ;
36
+
26
37
describe ( 'Test the Tree component' , ( ) => {
27
38
afterEach ( cleanup ) ;
28
39
@@ -85,7 +96,7 @@ describe('Test the Tree component', () => {
85
96
86
97
const parentIcon = container
87
98
. querySelector < HTMLDivElement > ( 'div[data-id="mo_treeNode_1"]' )
88
- ?. querySelector ( 'span.codicon-chevron-right ' ) ;
99
+ ?. querySelector ( 'span.codicon-chevron-down ' ) ;
89
100
90
101
const childNode = await waitFor ( ( ) =>
91
102
container . querySelector < HTMLDivElement > (
@@ -191,6 +202,25 @@ describe('Test the Tree component', () => {
191
202
expect ( await findByTitle ( 'test2' ) ) . toBeInTheDocument ( ) ;
192
203
} ) ;
193
204
205
+ test ( 'Should support to drag into children' , async ( ) => {
206
+ const data = [
207
+ {
208
+ id : '1' ,
209
+ name : 'test1' ,
210
+ children : [
211
+ {
212
+ id : '2' ,
213
+ name : 'test2' ,
214
+ isEditable : true ,
215
+ } ,
216
+ ] ,
217
+ } ,
218
+ ] ;
219
+ const { findByTitle } = render ( < TreeView data = { data } /> ) ;
220
+
221
+ expect ( await findByTitle ( 'test2' ) ) . toBeInTheDocument ( ) ;
222
+ } ) ;
223
+
194
224
test ( 'Should NOT support to sort via drag' , async ( ) => {
195
225
const data = [
196
226
{ id : '1' , name : 'test1' , isLeaf : true } ,
@@ -220,15 +250,12 @@ describe('Test the Tree component', () => {
220
250
} ,
221
251
] ;
222
252
const mockFn = jest . fn ( ) ;
223
- const { findByTitle } = render (
224
- < TreeView
225
- draggable
226
- onDropTree = { mockFn }
227
- defaultExpandAll
228
- data = { data }
229
- />
253
+ const { findByTitle, getByTitle } = render (
254
+ < TreeView draggable onDropTree = { mockFn } data = { data } />
230
255
) ;
231
256
257
+ fireEvent . click ( getByTitle ( 'test1' ) ) ;
258
+
232
259
dragToTargetNode (
233
260
await findByTitle ( 'test1-1' ) ,
234
261
await findByTitle ( 'test1' )
@@ -250,15 +277,12 @@ describe('Test the Tree component', () => {
250
277
source ,
251
278
] ;
252
279
const mockFn = jest . fn ( ) ;
253
- const { findByTitle } = render (
254
- < TreeView
255
- draggable
256
- onDropTree = { mockFn }
257
- defaultExpandAll
258
- data = { data }
259
- />
280
+ const { findByTitle, getByTitle } = render (
281
+ < TreeView draggable onDropTree = { mockFn } data = { data } />
260
282
) ;
261
283
284
+ fireEvent . click ( getByTitle ( 'test1' ) ) ;
285
+
262
286
dragToTargetNode (
263
287
await findByTitle ( source . name ) ,
264
288
await findByTitle ( target . name )
@@ -287,15 +311,13 @@ describe('Test the Tree component', () => {
287
311
} ,
288
312
] ;
289
313
const mockFn = jest . fn ( ) ;
290
- const { findByTitle } = render (
291
- < TreeView
292
- draggable
293
- onDropTree = { mockFn }
294
- defaultExpandAll
295
- data = { data }
296
- />
314
+ const { findByTitle, getByTitle } = render (
315
+ < TreeView draggable onDropTree = { mockFn } data = { data } />
297
316
) ;
298
317
318
+ fireEvent . click ( getByTitle ( 'test1' ) ) ;
319
+ fireEvent . click ( getByTitle ( 'test2' ) ) ;
320
+
299
321
dragToTargetNode (
300
322
await findByTitle ( source . name ) ,
301
323
await findByTitle ( target . name )
@@ -310,4 +332,185 @@ describe('Test the Tree component', () => {
310
332
children : [ target ] ,
311
333
} ) ;
312
334
} ) ;
335
+
336
+ test ( 'Should NOT drag node to its parent node or drag node to its siblings or drag node to itself' , async ( ) => {
337
+ const data = [
338
+ {
339
+ id : '1' ,
340
+ name : 'test1' ,
341
+ children : [
342
+ { id : '1-1' , isLeaf : true , name : 'test1-1' } ,
343
+ { id : '1-2' , isLeaf : true , name : 'test1-2' } ,
344
+ ] ,
345
+ } ,
346
+ {
347
+ id : '2' ,
348
+ name : 'test2' ,
349
+ isLeaf : true ,
350
+ } ,
351
+ ] ;
352
+ const mockFn = jest . fn ( ) ;
353
+ const { findByTitle } = render (
354
+ < TreeView draggable onDropTree = { mockFn } data = { data } />
355
+ ) ;
356
+
357
+ fireEvent . click ( await findByTitle ( 'test1' ) ) ;
358
+
359
+ dragToTargetNode (
360
+ await findByTitle ( 'test1-1' ) ,
361
+ await findByTitle ( 'test1' )
362
+ ) ;
363
+
364
+ expect ( mockFn ) . not . toBeCalled ( ) ;
365
+
366
+ dragToTargetNode (
367
+ await findByTitle ( 'test1-2' ) ,
368
+ await findByTitle ( 'test1-1' )
369
+ ) ;
370
+ expect ( mockFn ) . not . toBeCalled ( ) ;
371
+
372
+ dragToTargetNode (
373
+ await findByTitle ( 'test1' ) ,
374
+ await findByTitle ( 'test1' )
375
+ ) ;
376
+ expect ( mockFn ) . not . toBeCalled ( ) ;
377
+ } ) ;
378
+
379
+ test ( 'Should end drop when drag node out of tree' , async ( ) => {
380
+ const data = [
381
+ {
382
+ id : '1' ,
383
+ name : 'test1' ,
384
+ children : [
385
+ { id : '1-1' , isLeaf : true , name : 'test1-1' } ,
386
+ { id : '1-2' , isLeaf : true , name : 'test1-2' } ,
387
+ ] ,
388
+ } ,
389
+ ] ;
390
+ const mockFn = jest . fn ( ) ;
391
+ const { findByTitle, container, getByTestId } = render (
392
+ < TreeView draggable onDropTree = { mockFn } data = { data } />
393
+ ) ;
394
+
395
+ // creat a dom insert into body as the drop node
396
+ const outOfTree = document . createElement ( 'div' ) ;
397
+ outOfTree . dataset . testid = 'outOfTree' ;
398
+ outOfTree . style . width = '100px' ;
399
+ outOfTree . style . height = '100px' ;
400
+ container . appendChild ( outOfTree ) ;
401
+
402
+ // expand the parent node
403
+ fireEvent . click ( await findByTitle ( 'test1' ) ) ;
404
+ fireEvent . dragStart ( await findByTitle ( 'test1' ) ) ;
405
+ fireEvent . dragOver ( await findByTitle ( 'test1' ) ) ;
406
+
407
+ expect ( container . querySelectorAll ( '.drag-over' ) . length ) . not . toBe ( 0 ) ;
408
+
409
+ // drag node out of tree and drop it
410
+ fireEvent . dragOver ( getByTestId ( 'outOfTree' ) ) ;
411
+ fireEvent . dragEnd ( getByTestId ( 'outOfTree' ) ) ;
412
+
413
+ expect ( container . querySelectorAll ( '.drag-over' ) . length ) . toBe ( 0 ) ;
414
+ } ) ;
415
+
416
+ test ( 'Should expand the drop node if this node is a folder' , async ( ) => {
417
+ const data = [
418
+ {
419
+ id : '1' ,
420
+ name : 'test1' ,
421
+ children : [ { id : '1-1' , isLeaf : true , name : 'test1-1' } ] ,
422
+ } ,
423
+ { id : '2' , isLeaf : true , name : 'test2' } ,
424
+ ] ;
425
+ const { getByText } = render ( < TreeView draggable data = { data } /> ) ;
426
+
427
+ expect ( getByText ( 'test1' ) . parentElement ! . classList ) . toContain (
428
+ unexpandTreeNodeClassName
429
+ ) ;
430
+ dragToTargetNode ( getByText ( 'test2' ) , getByText ( 'test1' ) ) ;
431
+
432
+ expect ( getByText ( 'test1' ) . parentElement ! . classList ) . toContain (
433
+ expandTreeNodeClassName
434
+ ) ;
435
+
436
+ // drag to itself won't expand
437
+ dragToTargetNode ( getByText ( 'test1' ) , getByText ( 'test1' ) ) ;
438
+ expect ( getByText ( 'test1' ) . parentElement ! . classList ) . toContain (
439
+ unexpandTreeNodeClassName
440
+ ) ;
441
+ } ) ;
442
+
443
+ test ( 'Should support to loadData in sync' , async ( ) => {
444
+ const data = [
445
+ {
446
+ id : '1' ,
447
+ name : 'test1' ,
448
+ isLeaf : false ,
449
+ children : [ ] ,
450
+ } ,
451
+ ] ;
452
+ const mockFn = jest . fn ( ) . mockImplementation ( ( ) => sleep ( 1000 ) ) ;
453
+ const { getByText, container } = render (
454
+ < TreeView data = { data } onLoadData = { mockFn } />
455
+ ) ;
456
+
457
+ act ( ( ) => {
458
+ fireEvent . click ( getByText ( 'test1' ) ) ;
459
+ } ) ;
460
+
461
+ expect ( mockFn ) . toBeCalledTimes ( 1 ) ;
462
+ expect ( container . querySelector ( '.codicon-spin' ) ) . toBeInTheDocument ( ) ;
463
+ await sleep ( 1000 ) ;
464
+ expect ( container . querySelector ( '.codicon-spin' ) ) . toBeNull ( ) ;
465
+
466
+ act ( ( ) => {
467
+ // unfold it and open it again
468
+ fireEvent . click ( getByText ( 'test1' ) ) ;
469
+ fireEvent . click ( getByText ( 'test1' ) ) ;
470
+ } ) ;
471
+
472
+ // didn't trigger onLoadData this time
473
+ expect ( mockFn ) . toBeCalledTimes ( 1 ) ;
474
+ } ) ;
475
+
476
+ test ( 'Should support to be controlled' , ( ) => {
477
+ const mockFn = jest . fn ( ) ;
478
+ const { getByText, rerender } = render (
479
+ < TreeView data = { mockData } expandKeys = { [ ] } onExpand = { mockFn } />
480
+ ) ;
481
+
482
+ expect ( getByText ( 'test1' ) . parentElement ?. classList ) . toContain (
483
+ unexpandTreeNodeClassName
484
+ ) ;
485
+
486
+ fireEvent . click ( getByText ( 'test1' ) ) ;
487
+
488
+ expect ( getByText ( 'test1' ) . parentElement ?. classList ) . toContain (
489
+ unexpandTreeNodeClassName
490
+ ) ;
491
+ expect ( mockFn ) . toBeCalled ( ) ;
492
+
493
+ rerender (
494
+ < TreeView
495
+ data = { mockData }
496
+ expandKeys = { [ mockData [ 0 ] . key ! ] }
497
+ onExpand = { mockFn }
498
+ />
499
+ ) ;
500
+
501
+ expect ( getByText ( 'test1' ) . parentElement ?. classList ) . toContain (
502
+ expandTreeNodeClassName
503
+ ) ;
504
+ } ) ;
505
+
506
+ test ( 'Should support to trigger tree click event' , ( ) => {
507
+ expectFnCalled ( ( fn ) => {
508
+ const { getByRole } = render (
509
+ < TreeView data = { mockData } onTreeClick = { fn } />
510
+ ) ;
511
+
512
+ const wrapper = getByRole ( 'tree' ) ;
513
+ fireEvent . click ( wrapper ) ;
514
+ } ) ;
515
+ } ) ;
313
516
} ) ;
0 commit comments