@@ -1470,49 +1470,69 @@ describe "TreeView", ->
1470
1470
1471
1471
beforeEach ->
1472
1472
LocalStorage .clear ()
1473
+ atom .notifications .clear ()
1473
1474
1474
- describe " when attempting to paste a directory into itself" , ->
1475
- beforeEach ->
1476
- atom .notifications .clear ()
1477
-
1478
- operations =
1479
- " copy" : " copied"
1480
- " cut" : " cut"
1481
-
1482
- for operation, text of operations
1483
- describe " when #{ text} " , ->
1484
- it " shows a warning notification and does not paste" , ->
1485
- # /dir-1/ -> /dir-1/
1486
- LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1487
- newPath = path .join (dirPath, path .basename (dirPath))
1488
- dirView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1489
- expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1490
- expect (fs .existsSync (newPath)).toBe false
1491
- expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot paste a folder into itself'
1492
- atom .notifications .clear ()
1493
-
1494
- nestedPath = path .join (dirPath, ' nested' )
1495
- fs .makeTreeSync (nestedPath)
1496
-
1497
- # /dir-1/ -> /dir-1/nested
1498
- LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1499
- newPath = path .join (nestedPath, path .basename (dirPath))
1500
- dirView .expand ()
1501
- nestedView = dirView .querySelector (' .directory' )
1502
- nestedView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1503
- expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1504
- expect (fs .existsSync (newPath)).toBe false
1505
- expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot paste a folder into itself'
1506
- atom .notifications .clear ()
1507
- dirView .collapse ()
1508
-
1509
- # /dir-1/ -> /dir-2/
1510
- LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1511
- newPath = path .join (dirPath2, path .basename (dirPath))
1512
- dirView2 .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1513
- expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1514
- expect (fs .existsSync (newPath)).toBe true
1515
- expect (atom .notifications .getNotifications ()[0 ]).toBeUndefined ()
1475
+ for operation in [' copy' , ' cut' ]
1476
+ describe " when attempting to #{ operation} and paste a directory into itself" , ->
1477
+ it " shows a warning notification and does not paste" , ->
1478
+ # /dir-1/ -> /dir-1/
1479
+ LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1480
+ newPath = path .join (dirPath, path .basename (dirPath))
1481
+ dirView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1482
+ expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1483
+ expect (fs .existsSync (newPath)).toBe false
1484
+ expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot paste a folder into itself'
1485
+
1486
+ describe " when attempting to #{ operation} and paste a directory into a nested child directory" , ->
1487
+ it " shows a warning notification and does not paste" , ->
1488
+ nestedPath = path .join (dirPath, ' nested' )
1489
+ fs .makeTreeSync (nestedPath)
1490
+
1491
+ # /dir-1/ -> /dir-1/nested/
1492
+ LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1493
+ newPath = path .join (nestedPath, path .basename (dirPath))
1494
+ dirView .reload ()
1495
+ nestedView = dirView .querySelector (' .directory' )
1496
+ nestedView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1497
+ expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1498
+ expect (fs .existsSync (newPath)).toBe false
1499
+ expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot paste a folder into itself'
1500
+
1501
+ describe " when attempting to #{ operation} and paste a directory into a sibling directory that starts with the same letter" , ->
1502
+ it " allows the paste to occur" , ->
1503
+ # /dir-1/ -> /dir-2/
1504
+ LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1505
+ newPath = path .join (dirPath2, path .basename (dirPath))
1506
+ dirView2 .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1507
+ expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1508
+ expect (fs .existsSync (newPath)).toBe true
1509
+ expect (atom .notifications .getNotifications ()[0 ]).toBeUndefined ()
1510
+
1511
+ describe " when attempting to #{ operation} and paste a directory into a symlink of itself" , ->
1512
+ it " shows a warning notification and does not paste" , ->
1513
+ fs .symlinkSync (dirPath, path .join (rootDirPath, ' symdir' ), ' junction' )
1514
+
1515
+ # /dir-1/ -> symlink of /dir-1/
1516
+ LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([dirPath])
1517
+ newPath = path .join (dirPath, path .basename (dirPath))
1518
+ symlinkView = root1 .querySelector (' .directory' )
1519
+ symlinkView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1520
+ expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1521
+ expect (fs .existsSync (newPath)).toBe false
1522
+ expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot paste a folder into itself'
1523
+
1524
+ describe " when attempting to #{ operation} and paste a symlink into its target directory" , ->
1525
+ it " allows the paste to occur" , ->
1526
+ symlinkedPath = path .join (rootDirPath, ' symdir' )
1527
+ fs .symlinkSync (dirPath, symlinkedPath, ' junction' )
1528
+
1529
+ # symlink of /dir-1/ -> /dir-1/
1530
+ LocalStorage[" tree-view:#{ operation} Path" ] = JSON .stringify ([symlinkedPath])
1531
+ newPath = path .join (dirPath, path .basename (symlinkedPath))
1532
+ dirView .dispatchEvent (new MouseEvent (' click' , {bubbles : true , detail : 1 }))
1533
+ expect (-> atom .commands .dispatch (treeView .element , " tree-view:paste" )).not .toThrow ()
1534
+ expect (fs .existsSync (newPath)).toBe true
1535
+ expect (atom .notifications .getNotifications ()[0 ]).toBeUndefined ()
1516
1536
1517
1537
describe " when pasting entries which don't exist anymore" , ->
1518
1538
it " skips the entry which doesn't exist" , ->
@@ -3385,6 +3405,8 @@ describe "TreeView", ->
3385
3405
3386
3406
alpha2DirPath = path .join (rootDirPath, " alpha2" )
3387
3407
3408
+ symlinkToAlphaDirPath = path .join (rootDirPath, " symalpha" )
3409
+
3388
3410
fs .writeFileSync (alphaFilePath, " doesn't matter" )
3389
3411
fs .writeFileSync (zetaFilePath, " doesn't matter" )
3390
3412
@@ -3400,7 +3422,10 @@ describe "TreeView", ->
3400
3422
3401
3423
fs .makeTreeSync (alpha2DirPath)
3402
3424
3425
+ fs .symlinkSync (alphaDirPath, symlinkToAlphaDirPath, ' junction' )
3426
+
3403
3427
atom .project .setPaths ([rootDirPath])
3428
+ atom .notifications .clear ()
3404
3429
3405
3430
describe " when dragging a FileView onto a DirectoryView's header" , ->
3406
3431
it " should add the selected class to the DirectoryView" , ->
@@ -3496,13 +3521,33 @@ describe "TreeView", ->
3496
3521
expect (etaDir .querySelector (' .entries' ).children .length ).toBe 0
3497
3522
3498
3523
expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot move a folder into itself'
3499
- atom .notifications .clear ()
3500
- alphaDir .collapse ()
3501
3524
3525
+ it " shows a warning notification and does not move the directory if it would result in recursive copying (symlink)" , ->
3526
+ # Dragging alphaDir onto symalpha, which is a symlink to alphaDir
3527
+ alphaDir = findDirectoryContainingText (treeView .roots [0 ], ' alpha' )
3528
+ alphaDir .expand ()
3529
+
3530
+ symlinkDir = treeView .roots [0 ].entries .children [3 ]
3531
+ symlinkDir .expand ()
3532
+
3533
+ [dragStartEvent , dragEnterEvent , dropEvent ] =
3534
+ eventHelpers .buildInternalDragEvents (alphaDir, symlinkDir .querySelector (' .header' ), symlinkDir)
3535
+ treeView .onDragStart (dragStartEvent)
3536
+ treeView .onDrop (dropEvent)
3537
+ expect (symlinkDir .children .length ).toBe 2
3538
+ symlinkDir .expand ()
3539
+ expect (symlinkDir .querySelector (' .entries' ).children .length ).toBe 2
3540
+
3541
+ expect (atom .notifications .getNotifications ()[0 ].getMessage ()).toContain ' Cannot move a folder into itself'
3542
+
3543
+ it " moves successfully when dragging a directory onto a sibling directory that starts with the same letter" , ->
3502
3544
# Dragging alpha onto alpha2, which is a sibling of alpha's
3545
+ alphaDir = findDirectoryContainingText (treeView .roots [0 ], ' alpha' )
3546
+ alphaDir .expand ()
3547
+
3503
3548
alpha2Dir = findDirectoryContainingText (treeView .roots [0 ], ' alpha2' )
3504
3549
[dragStartEvent , dragEnterEvent , dropEvent ] =
3505
- eventHelpers .buildInternalDragEvents (alphaDir, etaDir .querySelector (' .header' ), alpha2Dir)
3550
+ eventHelpers .buildInternalDragEvents (alphaDir, alpha2Dir .querySelector (' .header' ), alpha2Dir)
3506
3551
treeView .onDragStart (dragStartEvent)
3507
3552
treeView .onDrop (dropEvent)
3508
3553
expect (alpha2Dir .children .length ).toBe 2
@@ -3511,6 +3556,24 @@ describe "TreeView", ->
3511
3556
3512
3557
expect (atom .notifications .getNotifications ()[0 ]).toBeUndefined ()
3513
3558
3559
+ it " moves successfully when dragging a symlink into its target directory" , ->
3560
+ # Dragging alphaDir onto symalpha, which is a symlink to alphaDir
3561
+ alphaDir = findDirectoryContainingText (treeView .roots [0 ], ' alpha' )
3562
+ alphaDir .expand ()
3563
+
3564
+ symlinkDir = treeView .roots [0 ].entries .children [3 ]
3565
+ symlinkDir .expand ()
3566
+
3567
+ [dragStartEvent , dragEnterEvent , dropEvent ] =
3568
+ eventHelpers .buildInternalDragEvents (symlinkDir, alphaDir .querySelector (' .header' ), alphaDir)
3569
+ treeView .onDragStart (dragStartEvent)
3570
+ treeView .onDrop (dropEvent)
3571
+ expect (alphaDir .children .length ).toBe 2
3572
+ alphaDir .reload ()
3573
+ expect (alphaDir .querySelector (' .entries' ).children .length ).toBe 3
3574
+
3575
+ expect (atom .notifications .getNotifications ()[0 ]).toBeUndefined ()
3576
+
3514
3577
describe " when dragging a file from the OS onto a DirectoryView's header" , ->
3515
3578
it " should move the file to the hovered directory" , ->
3516
3579
# Dragging delta.txt from OS file explorer onto alphaDir
0 commit comments