2019-09-17 20:57:53 +02:00
/ *
* Copyright Elasticsearch B . V . and / or licensed to Elasticsearch B . V . under one
2021-02-04 03:12:39 +01:00
* or more contributor license agreements . Licensed under the Elastic License
* 2.0 ; you may not use this file except in compliance with the Elastic License
* 2.0 .
2019-09-17 20:57:53 +02:00
* /
import React from 'react' ;
2021-03-29 14:07:39 +02:00
import { render , mount , ReactWrapper } from 'enzyme' ;
2021-02-05 18:17:03 +01:00
import { DragDrop } from './drag_drop' ;
2021-02-01 11:54:16 +01:00
import {
ChildDragDropProvider ,
DragContextState ,
ReorderProvider ,
DragDropIdentifier ,
2021-02-15 12:48:06 +01:00
DraggingIdentifier ,
2021-02-21 10:02:04 +01:00
DropIdentifier ,
2021-02-01 11:54:16 +01:00
} from './providers' ;
import { act } from 'react-dom/test-utils' ;
2021-02-05 18:17:03 +01:00
import { DropType } from '../types' ;
2019-09-17 20:57:53 +02:00
jest . useFakeTimers ( ) ;
2021-02-01 11:54:16 +01:00
const dataTransfer = {
setData : jest.fn ( ) ,
getData : jest.fn ( ) ,
} ;
2019-09-17 20:57:53 +02:00
describe ( 'DragDrop' , ( ) = > {
2021-02-05 18:17:03 +01:00
const defaultContext = {
dragging : undefined ,
setDragging : jest.fn ( ) ,
setActiveDropTarget : jest.fn ( ) ,
activeDropTarget : undefined ,
2021-02-21 10:02:04 +01:00
dropTargetsByOrder : undefined ,
2021-02-05 18:17:03 +01:00
keyboardMode : false ,
setKeyboardMode : ( ) = > { } ,
setA11yMessage : jest.fn ( ) ,
registerDropTarget : jest.fn ( ) ,
} ;
2021-03-29 14:07:39 +02:00
const value = {
id : '1' ,
humanData : { label : 'hello' , groupLabel : 'X' , position : 1 , canSwap : true , canDuplicate : true } ,
} ;
2019-09-17 20:57:53 +02:00
test ( 'renders if nothing is being dragged' , ( ) = > {
const component = render (
2021-02-05 18:17:03 +01:00
< DragDrop value = { value } draggable order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2019-09-17 20:57:53 +02:00
< / DragDrop >
) ;
expect ( component ) . toMatchSnapshot ( ) ;
} ) ;
2021-02-05 18:17:03 +01:00
test ( 'dragover calls preventDefault if dropType is defined' , ( ) = > {
2019-09-17 20:57:53 +02:00
const preventDefault = jest . fn ( ) ;
2020-10-01 17:58:23 +02:00
const component = mount (
2021-03-29 14:07:39 +02:00
< DragDrop dropTypes = { [ 'field_add' ] } value = { value } order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
< / DragDrop >
) ;
2019-09-17 20:57:53 +02:00
2021-03-29 14:07:39 +02:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) . simulate ( 'dragover' , { preventDefault } ) ;
2019-09-17 20:57:53 +02:00
expect ( preventDefault ) . toBeCalled ( ) ;
} ) ;
2021-03-29 14:07:39 +02:00
test ( 'dragover does not call preventDefault if dropTypes is undefined' , ( ) = > {
2019-09-17 20:57:53 +02:00
const preventDefault = jest . fn ( ) ;
2020-10-01 17:58:23 +02:00
const component = mount (
2021-02-05 18:17:03 +01:00
< DragDrop value = { value } order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
< / DragDrop >
) ;
2019-09-17 20:57:53 +02:00
2021-03-29 14:07:39 +02:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) . simulate ( 'dragover' , { preventDefault } ) ;
2019-09-17 20:57:53 +02:00
expect ( preventDefault ) . not . toBeCalled ( ) ;
} ) ;
2021-03-02 11:08:18 +01:00
test ( 'removes selection on mouse down before dragging' , async ( ) = > {
const removeAllRanges = jest . fn ( ) ;
global . getSelection = jest . fn ( ( ) = > ( ( { removeAllRanges } as unknown ) as Selection ) ) ;
const component = mount (
< DragDrop value = { value } draggable = { true } order = { [ 2 , 0 , 1 , 0 ] } >
< button > Hi ! < / button >
< / DragDrop >
) ;
2021-03-29 14:07:39 +02:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) . simulate ( 'mousedown' ) ;
2021-03-02 11:08:18 +01:00
expect ( global . getSelection ) . toBeCalled ( ) ;
expect ( removeAllRanges ) . toBeCalled ( ) ;
} ) ;
2021-02-15 12:48:06 +01:00
test ( 'dragstart sets dragging in the context and calls it with proper params' , async ( ) = > {
2019-09-17 20:57:53 +02:00
const setDragging = jest . fn ( ) ;
2021-02-05 18:17:03 +01:00
const setA11yMessage = jest . fn ( ) ;
2019-09-17 20:57:53 +02:00
const component = mount (
2021-02-05 18:17:03 +01:00
< ChildDragDropProvider
{ . . . defaultContext }
2021-02-15 12:48:06 +01:00
dragging = { undefined }
2021-02-05 18:17:03 +01:00
setDragging = { setDragging }
setA11yMessage = { setA11yMessage }
>
< DragDrop value = { value } draggable = { true } order = { [ 2 , 0 , 1 , 0 ] } >
2021-02-15 12:48:06 +01:00
< button > Hi ! < / button >
2020-03-03 17:48:54 +01:00
< / DragDrop >
2019-09-17 20:57:53 +02:00
< / ChildDragDropProvider >
) ;
2021-03-29 14:07:39 +02:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) . simulate ( 'dragstart' , { dataTransfer } ) ;
2019-09-17 20:57:53 +02:00
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2019-09-17 20:57:53 +02:00
2021-02-05 18:17:03 +01:00
expect ( dataTransfer . setData ) . toBeCalledWith ( 'text' , 'hello' ) ;
2021-02-15 12:48:06 +01:00
expect ( setDragging ) . toBeCalledWith ( { . . . value } ) ;
2021-02-05 18:17:03 +01:00
expect ( setA11yMessage ) . toBeCalledWith ( 'Lifted hello' ) ;
2019-09-17 20:57:53 +02:00
} ) ;
test ( 'drop resets all the things' , async ( ) = > {
const preventDefault = jest . fn ( ) ;
const stopPropagation = jest . fn ( ) ;
const setDragging = jest . fn ( ) ;
const onDrop = jest . fn ( ) ;
const component = mount (
2021-02-01 11:54:16 +01:00
< ChildDragDropProvider
{ . . . defaultContext }
2021-02-17 16:48:26 +01:00
dragging = { { id : '2' , humanData : { label : 'Label1' } } }
2021-02-01 11:54:16 +01:00
setDragging = { setDragging }
>
2021-03-29 14:07:39 +02:00
< DragDrop onDrop = { onDrop } dropTypes = { [ 'field_add' ] } value = { value } order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2019-09-17 20:57:53 +02:00
< / DragDrop >
< / ChildDragDropProvider >
) ;
2021-03-29 14:07:39 +02:00
const dragDrop = component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) ;
dragDrop . simulate ( 'dragOver' ) ;
dragDrop . simulate ( 'drop' , { preventDefault , stopPropagation } ) ;
2019-09-17 20:57:53 +02:00
expect ( preventDefault ) . toBeCalled ( ) ;
expect ( stopPropagation ) . toBeCalled ( ) ;
expect ( setDragging ) . toBeCalledWith ( undefined ) ;
2021-02-17 16:48:26 +01:00
expect ( onDrop ) . toBeCalledWith ( { id : '2' , humanData : { label : 'Label1' } } , 'field_add' ) ;
2019-09-17 20:57:53 +02:00
} ) ;
2021-03-29 14:07:39 +02:00
test ( 'drop function is not called on dropTypes undefined' , async ( ) = > {
2019-10-16 05:01:43 +02:00
const preventDefault = jest . fn ( ) ;
const stopPropagation = jest . fn ( ) ;
const setDragging = jest . fn ( ) ;
const onDrop = jest . fn ( ) ;
const component = mount (
2021-02-05 18:17:03 +01:00
< ChildDragDropProvider
{ . . . defaultContext }
2021-02-17 16:48:26 +01:00
dragging = { { id : 'hi' , humanData : { label : 'Label1' } } }
2021-02-05 18:17:03 +01:00
setDragging = { setDragging }
>
2021-03-29 14:07:39 +02:00
< DragDrop onDrop = { onDrop } dropTypes = { undefined } value = { value } order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2019-10-16 05:01:43 +02:00
< / DragDrop >
< / ChildDragDropProvider >
) ;
2021-03-29 14:07:39 +02:00
const dragDrop = component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 0 ) ;
dragDrop . simulate ( 'dragover' ) ;
dragDrop . simulate ( 'drop' , { preventDefault , stopPropagation } ) ;
2019-10-16 05:01:43 +02:00
2021-03-29 14:07:39 +02:00
expect ( preventDefault ) . not . toHaveBeenCalled ( ) ;
expect ( stopPropagation ) . not . toHaveBeenCalled ( ) ;
expect ( setDragging ) . not . toHaveBeenCalled ( ) ;
2019-10-16 05:01:43 +02:00
expect ( onDrop ) . not . toHaveBeenCalled ( ) ;
} ) ;
2021-03-29 14:07:39 +02:00
test ( 'defined dropTypes is reflected in the className' , ( ) = > {
2019-09-17 20:57:53 +02:00
const component = render (
< DragDrop
onDrop = { ( x : unknown ) = > {
throw x ;
} }
2021-03-29 14:07:39 +02:00
dropTypes = { [ 'field_add' ] }
2021-02-01 11:54:16 +01:00
value = { value }
2021-02-05 18:17:03 +01:00
order = { [ 2 , 0 , 1 , 0 ] }
2019-09-17 20:57:53 +02:00
>
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2019-09-17 20:57:53 +02:00
< / DragDrop >
) ;
expect ( component ) . toMatchSnapshot ( ) ;
} ) ;
2020-09-04 16:11:41 +02:00
2021-03-29 14:07:39 +02:00
test ( 'items that has dropTypes=undefined get special styling when another item is dragged' , ( ) = > {
2020-09-04 16:11:41 +02:00
const component = mount (
2021-02-15 12:48:06 +01:00
< ChildDragDropProvider { ...defaultContext } dragging = { { . . . value } } >
2021-02-05 18:17:03 +01:00
< DragDrop value = { value } draggable = { true } order = { [ 2 , 0 , 1 , 0 ] } >
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2020-09-04 16:11:41 +02:00
< / DragDrop >
2021-02-05 18:17:03 +01:00
< DragDrop
order = { [ 2 , 0 , 1 , 0 ] }
onDrop = { ( x : unknown ) = > { } }
2021-03-29 14:07:39 +02:00
dropTypes = { undefined }
2021-02-05 18:17:03 +01:00
value = { { id : '2' , humanData : { label : 'label2' } } }
>
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2020-09-04 16:11:41 +02:00
< / DragDrop >
< / ChildDragDropProvider >
) ;
expect ( component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 1 ) ) . toMatchSnapshot ( ) ;
} ) ;
test ( 'additional styles are reflected in the className until drop' , ( ) = > {
2021-02-17 16:48:26 +01:00
let dragging : { id : '1' ; humanData : { label : 'Label1' } } | undefined ;
2021-02-05 18:17:03 +01:00
const getAdditionalClassesOnEnter = jest . fn ( ) . mockReturnValue ( 'additional' ) ;
const getAdditionalClassesOnDroppable = jest . fn ( ) . mockReturnValue ( 'droppable' ) ;
const setA11yMessage = jest . fn ( ) ;
2021-02-01 11:54:16 +01:00
2020-09-04 16:11:41 +02:00
const component = mount (
< ChildDragDropProvider
2021-02-01 11:54:16 +01:00
{ . . . defaultContext }
2020-09-04 16:11:41 +02:00
dragging = { dragging }
2021-02-05 18:17:03 +01:00
setA11yMessage = { setA11yMessage }
2020-09-04 16:11:41 +02:00
setDragging = { ( ) = > {
2021-02-17 16:48:26 +01:00
dragging = { id : '1' , humanData : { label : 'Label1' } } ;
2020-09-04 16:11:41 +02:00
} }
>
2021-02-05 18:17:03 +01:00
< DragDrop
value = { { id : '3' , humanData : { label : 'ignored' } } }
draggable = { true }
order = { [ 2 , 0 , 1 , 0 ] }
>
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2020-09-04 16:11:41 +02:00
< / DragDrop >
< DragDrop
2021-02-05 18:17:03 +01:00
order = { [ 2 , 0 , 1 , 0 ] }
2021-02-01 11:54:16 +01:00
value = { value }
2020-09-04 16:11:41 +02:00
onDrop = { ( x : unknown ) = > { } }
2021-03-29 14:07:39 +02:00
dropTypes = { [ 'field_add' ] }
2021-02-05 18:17:03 +01:00
getAdditionalClassesOnEnter = { getAdditionalClassesOnEnter }
getAdditionalClassesOnDroppable = { getAdditionalClassesOnDroppable }
2020-09-04 16:11:41 +02:00
>
2020-10-01 17:58:23 +02:00
< button > Hello ! < / button >
2020-09-04 16:11:41 +02:00
< / DragDrop >
< / ChildDragDropProvider >
) ;
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2021-02-05 18:17:03 +01:00
expect ( setA11yMessage ) . toBeCalledWith ( 'Lifted ignored' ) ;
2020-09-04 16:11:41 +02:00
2021-03-29 14:07:39 +02:00
const dragDrop = component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 1 ) ;
dragDrop . simulate ( 'dragOver' ) ;
dragDrop . simulate ( 'drop' ) ;
2020-09-04 16:11:41 +02:00
expect ( component . find ( '.additional' ) ) . toHaveLength ( 0 ) ;
2021-02-01 11:54:16 +01:00
} ) ;
test ( 'additional enter styles are reflected in the className until dragleave' , ( ) = > {
2021-02-17 16:48:26 +01:00
let dragging : { id : '1' ; humanData : { label : 'Label1' } } | undefined ;
2021-02-01 11:54:16 +01:00
const getAdditionalClasses = jest . fn ( ) . mockReturnValue ( 'additional' ) ;
2021-02-05 18:17:03 +01:00
const getAdditionalClassesOnDroppable = jest . fn ( ) . mockReturnValue ( 'droppable' ) ;
2021-02-01 11:54:16 +01:00
const setActiveDropTarget = jest . fn ( ) ;
const component = mount (
< ChildDragDropProvider
setA11yMessage = { jest . fn ( ) }
dragging = { dragging }
setDragging = { ( ) = > {
2021-02-17 16:48:26 +01:00
dragging = { id : '1' , humanData : { label : 'Label1' } } ;
2021-02-01 11:54:16 +01:00
} }
setActiveDropTarget = { setActiveDropTarget }
2021-02-21 10:02:04 +01:00
activeDropTarget = { value as DragContextState [ 'activeDropTarget' ] }
2021-02-01 11:54:16 +01:00
keyboardMode = { false }
setKeyboardMode = { ( keyboardMode ) = > true }
2021-02-21 10:02:04 +01:00
dropTargetsByOrder = { undefined }
2021-02-05 18:17:03 +01:00
registerDropTarget = { jest . fn ( ) }
2021-02-01 11:54:16 +01:00
>
2021-02-05 18:17:03 +01:00
< DragDrop
value = { { id : '3' , humanData : { label : 'ignored' } } }
draggable = { true }
order = { [ 2 , 0 , 1 , 0 ] }
>
2021-02-01 11:54:16 +01:00
< button > Hello ! < / button >
< / DragDrop >
< DragDrop
2021-02-05 18:17:03 +01:00
order = { [ 2 , 0 , 1 , 0 ] }
2021-02-01 11:54:16 +01:00
value = { value }
onDrop = { ( x : unknown ) = > { } }
2021-03-29 14:07:39 +02:00
dropTypes = { [ 'field_add' ] }
2021-02-01 11:54:16 +01:00
getAdditionalClassesOnEnter = { getAdditionalClasses }
2021-02-05 18:17:03 +01:00
getAdditionalClassesOnDroppable = { getAdditionalClassesOnDroppable }
2021-02-01 11:54:16 +01:00
>
< button > Hello ! < / button >
< / DragDrop >
< / ChildDragDropProvider >
) ;
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2020-09-04 16:11:41 +02:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 1 ) . simulate ( 'dragover' ) ;
2021-03-29 14:07:39 +02:00
expect ( component . find ( '.additional' ) ) . toHaveLength ( 2 ) ;
2021-02-01 11:54:16 +01:00
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 1 ) . simulate ( 'dragleave' ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( undefined ) ;
2020-09-04 16:11:41 +02:00
} ) ;
2020-11-03 21:18:44 +01:00
2021-03-29 14:07:39 +02:00
describe ( 'Keyboard navigation' , ( ) = > {
test ( 'User receives proper drop Targets highlighted when pressing arrow keys' , ( ) = > {
const onDrop = jest . fn ( ) ;
const setActiveDropTarget = jest . fn ( ) ;
const setA11yMessage = jest . fn ( ) ;
const items = [
{
draggable : true ,
value : {
id : '1' ,
humanData : { label : 'Label1' , position : 1 } ,
} ,
children : '1' ,
order : [ 2 , 0 , 0 , 0 ] ,
2021-02-05 18:17:03 +01:00
} ,
2021-03-29 14:07:39 +02:00
{
draggable : true ,
dragType : 'move' as 'copy' | 'move' ,
2021-02-05 18:17:03 +01:00
2021-03-29 14:07:39 +02:00
value : {
id : '2' ,
2021-02-05 18:17:03 +01:00
2021-03-29 14:07:39 +02:00
humanData : { label : 'label2' , position : 1 } ,
} ,
onDrop ,
dropTypes : [ 'move_compatible' ] as DropType [ ] ,
order : [ 2 , 0 , 1 , 0 ] ,
2021-02-05 18:17:03 +01:00
} ,
2021-03-29 14:07:39 +02:00
{
draggable : true ,
dragType : 'move' as 'copy' | 'move' ,
value : {
id : '3' ,
humanData : {
label : 'label3' ,
position : 1 ,
groupLabel : 'Y' ,
canSwap : true ,
canDuplicate : true ,
} ,
} ,
onDrop ,
dropTypes : [
'replace_compatible' ,
'duplicate_compatible' ,
'swap_compatible' ,
] as DropType [ ] ,
order : [ 2 , 0 , 2 , 0 ] ,
2021-02-05 18:17:03 +01:00
} ,
2021-03-29 14:07:39 +02:00
{
draggable : true ,
dragType : 'move' as 'copy' | 'move' ,
value : {
id : '4' ,
humanData : { label : 'label4' , position : 2 , groupLabel : 'Y' } ,
2021-02-05 18:17:03 +01:00
} ,
2021-03-29 14:07:39 +02:00
order : [ 2 , 0 , 2 , 1 ] ,
} ,
] ;
const component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div / > , style : { } } } ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget : { . . . items [ 1 ] . value , onDrop , dropType : 'move_compatible' } ,
dropTargetsByOrder : {
'2,0,1,0' : { . . . items [ 1 ] . value , onDrop , dropType : 'move_compatible' } ,
'2,0,2,0,0' : { . . . items [ 2 ] . value , onDrop , dropType : 'replace_compatible' } ,
'2,0,1,0,1' : { . . . items [ 1 ] . value , onDrop , dropType : 'duplicate_compatible' } ,
'2,0,1,0,2' : { . . . items [ 1 ] . value , onDrop , dropType : 'swap_compatible' } ,
} ,
keyboardMode : true ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
const keyboardHandler = component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'focus' ) ;
2021-02-05 18:17:03 +01:00
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowRight' } ) ;
2021-03-29 14:07:39 +02:00
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 2 ] . value ,
onDrop ,
dropType : items [ 2 ] . dropTypes ! [ 0 ] ,
} ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Enter' } ) ;
expect ( setA11yMessage ) . toBeCalledWith (
` You're dragging Label1 from at position 1 over label3 from Y group at position 1. Press space or enter to replace label3 with Label1. Hold alt or option to duplicate. Hold shift to swap. `
) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( undefined ) ;
expect ( onDrop ) . toBeCalledWith (
{ humanData : { label : 'Label1' , position : 1 } , id : '1' } ,
'move_compatible'
) ;
2021-02-05 18:17:03 +01:00
} ) ;
2021-03-29 14:07:39 +02:00
test ( 'dragstart sets dragging in the context and calls it with proper params' , async ( ) = > {
const setDragging = jest . fn ( ) ;
const setA11yMessage = jest . fn ( ) ;
const component = mount (
< ChildDragDropProvider
{ . . . defaultContext }
dragging = { undefined }
setDragging = { setDragging }
setA11yMessage = { setA11yMessage }
keyboardMode = { false }
>
< DragDrop value = { value } draggable = { true } order = { [ 2 , 0 , 1 , 0 ] } >
< button > Hi ! < / button >
< / DragDrop >
< / ChildDragDropProvider >
) ;
const keyboardHandler = component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'focus' ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Enter' } ) ;
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
expect ( setDragging ) . toBeCalledWith ( {
. . . value ,
ghost : {
children : < button > Hi ! < / button > ,
style : {
height : 0 ,
width : 0 ,
} ,
} ,
} ) ;
expect ( setA11yMessage ) . toBeCalledWith ( 'Lifted hello' ) ;
2021-02-15 12:48:06 +01:00
} ) ;
2021-03-29 14:07:39 +02:00
test ( 'ActiveDropTarget gets ghost image' , ( ) = > {
const onDrop = jest . fn ( ) ;
const setActiveDropTarget = jest . fn ( ) ;
const setA11yMessage = jest . fn ( ) ;
const items = [
{
draggable : true ,
value : {
id : '1' ,
humanData : { label : 'Label1' , position : 1 } ,
} ,
children : '1' ,
order : [ 2 , 0 , 0 , 0 ] ,
} ,
{
draggable : true ,
dragType : 'move' as 'copy' | 'move' ,
2021-02-15 12:48:06 +01:00
2021-03-29 14:07:39 +02:00
value : {
id : '2' ,
2021-02-15 12:48:06 +01:00
2021-03-29 14:07:39 +02:00
humanData : { label : 'label2' , position : 1 } ,
} ,
onDrop ,
dropTypes : [ 'move_compatible' ] as DropType [ ] ,
order : [ 2 , 0 , 1 , 0 ] ,
2021-02-15 12:48:06 +01:00
} ,
2021-03-29 14:07:39 +02:00
] ;
const component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div > Hello < / div > , style : { } } } ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget : { . . . items [ 1 ] . value , onDrop , dropType : 'move_compatible' } ,
dropTargetsByOrder : {
'2,0,1,0' : { . . . items [ 1 ] . value , onDrop , dropType : 'move_compatible' } ,
} ,
keyboardMode : true ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
expect ( component . find ( DragDrop ) . at ( 1 ) . find ( '.lnsDragDrop_ghost' ) . text ( ) ) . toEqual ( 'Hello' ) ;
2021-02-15 12:48:06 +01:00
} ) ;
} ) ;
2021-03-29 14:07:39 +02:00
describe ( 'multiple drop targets' , ( ) = > {
let activeDropTarget : DragContextState [ 'activeDropTarget' ] ;
2021-02-15 12:48:06 +01:00
const onDrop = jest . fn ( ) ;
2021-03-29 14:07:39 +02:00
let setActiveDropTarget = jest . fn ( ) ;
2021-02-15 12:48:06 +01:00
const setA11yMessage = jest . fn ( ) ;
2021-03-29 14:07:39 +02:00
let component : ReactWrapper ;
beforeEach ( ( ) = > {
activeDropTarget = undefined ;
setActiveDropTarget = jest . fn ( ( val ) = > {
activeDropTarget = value as DragContextState [ 'activeDropTarget' ] ;
} ) ;
component = mount (
< ChildDragDropProvider
setA11yMessage = { jest . fn ( ) }
dragging = { { id : '1' , humanData : { label : 'Label1' } } }
setDragging = { jest . fn ( ) }
setActiveDropTarget = { setActiveDropTarget }
activeDropTarget = { activeDropTarget }
keyboardMode = { false }
setKeyboardMode = { ( keyboardMode ) = > true }
dropTargetsByOrder = { undefined }
registerDropTarget = { jest . fn ( ) }
>
< DragDrop
value = { { id : '3' , humanData : { label : 'ignored' } } }
draggable = { true }
order = { [ 2 , 0 , 1 , 0 ] }
>
< button > Drag this < / button >
< / DragDrop >
< DragDrop
order = { [ 2 , 0 , 1 , 0 ] }
value = { value }
onDrop = { onDrop }
dropTypes = { [ 'move_compatible' , 'duplicate_compatible' , 'swap_compatible' ] }
getCustomDropTarget = { ( dropType ) = > < div className = "extraDrop" > { dropType } < / div > }
>
< button > Drop here < / button >
< / DragDrop >
< / ChildDragDropProvider >
) ;
} ) ;
test ( 'extra drop targets render correctly' , ( ) = > {
expect ( component . find ( '.extraDrop' ) . hostNodes ( ) ) . toHaveLength ( 2 ) ;
} ) ;
2021-02-15 12:48:06 +01:00
2021-03-29 14:07:39 +02:00
test ( 'extra drop targets appear when dragging over and disappear when activeDropTarget changes' , ( ) = > {
component . find ( '[data-test-subj="lnsDragDropContainer"]' ) . first ( ) . simulate ( 'dragenter' ) ;
2021-02-15 12:48:06 +01:00
2021-03-29 14:07:39 +02:00
// customDropTargets are visible
expect ( component . find ( '[data-test-subj="lnsDragDropContainer"]' ) . prop ( 'className' ) ) . toEqual (
'lnsDragDrop__container lnsDragDrop__container-active'
) ;
expect (
component . find ( '[data-test-subj="lnsDragDropExtraDrops"]' ) . first ( ) . prop ( 'className' )
) . toEqual ( 'lnsDragDrop__extraDrops lnsDragDrop__extraDrops-visible' ) ;
// set activeDropTarget as undefined
component . find ( '[data-test-subj="lnsDragDrop"]' ) . at ( 1 ) . simulate ( 'dragleave' ) ;
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
component . update ( ) ;
// customDropTargets are invisible
expect (
component . find ( '[data-test-subj="lnsDragDropExtraDrops"]' ) . first ( ) . prop ( 'className' )
) . toEqual ( 'lnsDragDrop__extraDrops' ) ;
} ) ;
test ( 'dragging over different drop types of the same value assigns correct activeDropTarget' , ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
component . find ( 'SingleDropInner' ) . at ( 0 ) . simulate ( 'dragover' ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . value ,
dropType : 'move_compatible' ,
2021-02-15 12:48:06 +01:00
onDrop ,
2021-03-29 14:07:39 +02:00
} ) ;
component . find ( 'SingleDropInner' ) . at ( 1 ) . simulate ( 'dragover' ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . value ,
dropType : 'duplicate_compatible' ,
onDrop ,
} ) ;
component . find ( 'SingleDropInner' ) . at ( 2 ) . simulate ( 'dragover' ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . value ,
dropType : 'swap_compatible' ,
onDrop ,
} ) ;
component . find ( 'SingleDropInner' ) . at ( 2 ) . simulate ( 'dragleave' ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( undefined ) ;
} ) ;
test ( 'drop on extra drop target passes correct dropType to onDrop' , ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
component . find ( 'SingleDropInner' ) . at ( 0 ) . simulate ( 'dragover' ) ;
component . find ( 'SingleDropInner' ) . at ( 0 ) . simulate ( 'drop' ) ;
expect ( onDrop ) . toBeCalledWith ( { humanData : { label : 'Label1' } , id : '1' } , 'move_compatible' ) ;
component . find ( 'SingleDropInner' ) . at ( 1 ) . simulate ( 'dragover' ) ;
component . find ( 'SingleDropInner' ) . at ( 1 ) . simulate ( 'drop' ) ;
expect ( onDrop ) . toBeCalledWith (
{ humanData : { label : 'Label1' } , id : '1' } ,
'duplicate_compatible'
) ;
component . find ( 'SingleDropInner' ) . at ( 2 ) . simulate ( 'dragover' ) ;
component . find ( 'SingleDropInner' ) . at ( 2 ) . simulate ( 'drop' ) ;
expect ( onDrop ) . toBeCalledWith ( { humanData : { label : 'Label1' } , id : '1' } , 'swap_compatible' ) ;
} ) ;
test ( 'pressing Alt or Shift when dragging over the main drop target sets extra drop target as active' , ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
// needed to setup activeDropType
component
. find ( 'SingleDropInner' )
. at ( 0 )
. simulate ( 'dragover' , { altKey : true } )
. simulate ( 'dragover' , { altKey : true } ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . value ,
dropType : 'duplicate_compatible' ,
onDrop ,
} ) ;
component
. find ( 'SingleDropInner' )
. at ( 0 )
. simulate ( 'dragover' , { shiftKey : true } )
. simulate ( 'dragover' , { shiftKey : true } ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . value ,
dropType : 'swap_compatible' ,
onDrop ,
} ) ;
} ) ;
test ( 'pressing Alt or Shift when dragging over the extra drop target does nothing' , ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
const extraDrop = component . find ( 'SingleDropInner' ) . at ( 1 ) ;
extraDrop . simulate ( 'dragover' , { altKey : true } ) ;
extraDrop . simulate ( 'dragover' , { shiftKey : true } ) ;
extraDrop . simulate ( 'dragover' ) ;
expect (
setActiveDropTarget . mock . calls . every ( ( call ) = > call [ 0 ] . dropType === 'duplicate_compatible' )
) ;
} ) ;
describe ( 'keyboard navigation' , ( ) = > {
const items = [
{
draggable : true ,
value : {
id : '1' ,
humanData : { label : 'Label1' , position : 1 } ,
2021-02-15 12:48:06 +01:00
} ,
2021-03-29 14:07:39 +02:00
children : '1' ,
order : [ 2 , 0 , 0 , 0 ] ,
} ,
{
draggable : true ,
dragType : 'move' as const ,
2021-02-15 12:48:06 +01:00
2021-03-29 14:07:39 +02:00
value : {
id : '2' ,
humanData : { label : 'label2' , position : 1 } ,
} ,
onDrop ,
dropTypes : [ 'move_compatible' , 'duplicate_compatible' , 'swap_compatible' ] as DropType [ ] ,
order : [ 2 , 0 , 1 , 0 ] ,
} ,
{
draggable : true ,
dragType : 'move' as const ,
value : {
id : '3' ,
humanData : { label : 'label3' , position : 1 , groupLabel : 'Y' } ,
} ,
onDrop ,
dropTypes : [ 'replace_compatible' ] as DropType [ ] ,
order : [ 2 , 0 , 2 , 0 ] ,
} ,
] ;
const assignedDropTargetsByOrder : DragContextState [ 'dropTargetsByOrder' ] = {
'2,0,1,0,0' : {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'move_compatible' ,
} ,
'2,0,1,0,1' : {
dropType : 'duplicate_compatible' ,
humanData : {
label : 'label2' ,
position : 1 ,
} ,
id : '2' ,
onDrop ,
} ,
'2,0,1,0,2' : {
dropType : 'swap_compatible' ,
humanData : {
label : 'label2' ,
position : 1 ,
} ,
id : '2' ,
onDrop ,
} ,
'2,0,2,0,0' : {
dropType : 'replace_compatible' ,
humanData : {
groupLabel : 'Y' ,
label : 'label3' ,
position : 1 ,
} ,
id : '3' ,
onDrop ,
} ,
} ;
test ( 'when pressing enter key, context receives the proper dropTargetsByOrder' , ( ) = > {
let dropTargetsByOrder : DragContextState [ 'dropTargetsByOrder' ] = { } ;
const setKeyboardMode = jest . fn ( ) ;
component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div / > , style : { } } } ,
setDragging : jest.fn ( ) ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget ,
dropTargetsByOrder ,
keyboardMode : true ,
setKeyboardMode ,
registerDropTarget : jest.fn ( ( order , dropTarget ) = > {
dropTargetsByOrder = {
. . . dropTargetsByOrder ,
[ order . join ( ',' ) ] : dropTarget ,
} ;
} ) ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
component . find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' ) . first ( ) . simulate ( 'focus' ) ;
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
component . update ( ) ;
expect ( dropTargetsByOrder ) . toEqual ( assignedDropTargetsByOrder ) ;
} ) ;
test ( 'when pressing ArrowRight key with modifier key pressed in, the extra drop target is selected' , ( ) = > {
component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div / > , style : { } } } ,
setDragging : jest.fn ( ) ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget : undefined ,
dropTargetsByOrder : assignedDropTargetsByOrder ,
keyboardMode : true ,
setKeyboardMode : jest.fn ( ) ,
registerDropTarget : jest.fn ( ) ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keydown' , { key : 'ArrowRight' , altKey : true } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'duplicate_compatible' ,
} ) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keydown' , { key : 'ArrowRight' , shiftKey : true } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'swap_compatible' ,
} ) ;
} ) ;
test ( 'when having a main target selected and pressing alt, the first extra drop target is selected' , ( ) = > {
component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div / > , style : { } } } ,
setDragging : jest.fn ( ) ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget : assignedDropTargetsByOrder [ '2,0,1,0,0' ] ,
dropTargetsByOrder : assignedDropTargetsByOrder ,
keyboardMode : true ,
setKeyboardMode : jest.fn ( ) ,
registerDropTarget : jest.fn ( ) ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keydown' , { key : 'Alt' } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'duplicate_compatible' ,
} ) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keyup' , { key : 'Alt' } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'move_compatible' ,
} ) ;
} ) ;
test ( 'when having a main target selected and pressing shift, the second extra drop target is selected' , ( ) = > {
component = mount (
< ChildDragDropProvider
{ . . . {
. . . defaultContext ,
dragging : { . . . items [ 0 ] . value , ghost : { children : < div / > , style : { } } } ,
setDragging : jest.fn ( ) ,
setActiveDropTarget ,
setA11yMessage ,
activeDropTarget : assignedDropTargetsByOrder [ '2,0,1,0,0' ] ,
dropTargetsByOrder : assignedDropTargetsByOrder ,
keyboardMode : true ,
setKeyboardMode : jest.fn ( ) ,
registerDropTarget : jest.fn ( ) ,
} }
>
{ items . map ( ( props ) = > (
< DragDrop { ...props } key = { props . value . id } >
< div / >
< / DragDrop >
) ) }
< / ChildDragDropProvider >
) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keydown' , { key : 'Shift' } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'swap_compatible' ,
} ) ;
act ( ( ) = > {
component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( )
. simulate ( 'keyup' , { key : 'Shift' } ) ;
} ) ;
expect ( setActiveDropTarget ) . toBeCalledWith ( {
. . . items [ 1 ] . value ,
onDrop ,
dropType : 'move_compatible' ,
} ) ;
} ) ;
} ) ;
2021-02-05 18:17:03 +01:00
} ) ;
2021-03-29 14:07:39 +02:00
describe ( 'Reordering' , ( ) = > {
2021-02-05 18:17:03 +01:00
const onDrop = jest . fn ( ) ;
const items = [
{
id : '1' ,
2021-02-17 16:48:26 +01:00
humanData : { label : 'Label1' , position : 1 , groupLabel : 'X' } ,
2021-02-05 18:17:03 +01:00
onDrop ,
2021-03-29 14:07:39 +02:00
draggable : true ,
2021-02-05 18:17:03 +01:00
} ,
{
id : '2' ,
2021-02-17 16:48:26 +01:00
humanData : { label : 'label2' , position : 2 , groupLabel : 'X' } ,
2021-02-05 18:17:03 +01:00
onDrop ,
} ,
{
id : '3' ,
2021-02-17 16:48:26 +01:00
humanData : { label : 'label3' , position : 3 , groupLabel : 'X' } ,
2021-02-05 18:17:03 +01:00
onDrop ,
} ,
] ;
2020-11-03 21:18:44 +01:00
const mountComponent = (
2021-02-01 11:54:16 +01:00
dragContext : Partial < DragContextState > | undefined ,
2021-02-05 18:17:03 +01:00
onDropHandler ? : ( ) = > void
2021-02-01 11:54:16 +01:00
) = > {
let dragging = dragContext ? . dragging ;
let keyboardMode = ! ! dragContext ? . keyboardMode ;
let activeDropTarget = dragContext ? . activeDropTarget ;
2021-02-05 18:17:03 +01:00
const setA11yMessage = jest . fn ( ) ;
const registerDropTarget = jest . fn ( ) ;
2021-02-01 11:54:16 +01:00
const baseContext = {
dragging ,
2021-02-15 12:48:06 +01:00
setDragging : ( val? : DraggingIdentifier ) = > {
2021-02-01 11:54:16 +01:00
dragging = val ;
} ,
keyboardMode ,
setKeyboardMode : jest.fn ( ( mode ) = > {
keyboardMode = mode ;
} ) ,
setActiveDropTarget : ( target? : DragDropIdentifier ) = > {
2021-02-21 10:02:04 +01:00
activeDropTarget = target as DropIdentifier ;
2021-02-01 11:54:16 +01:00
} ,
activeDropTarget ,
2021-02-05 18:17:03 +01:00
setA11yMessage ,
registerDropTarget ,
2021-02-21 10:02:04 +01:00
dropTargetsByOrder : undefined ,
2021-02-05 18:17:03 +01:00
} ;
const dragDropSharedProps = {
draggable : true ,
dragType : 'move' as 'copy' | 'move' ,
reorderableGroup : items.map ( ( { id } ) = > ( { id } ) ) ,
onDrop : onDropHandler || onDrop ,
2021-02-01 11:54:16 +01:00
} ;
2021-02-05 18:17:03 +01:00
2021-02-01 11:54:16 +01:00
return mount (
< ChildDragDropProvider { ...baseContext } { ...dragContext } >
2020-11-03 21:18:44 +01:00
< ReorderProvider id = "groupId" >
< DragDrop
2021-02-05 18:17:03 +01:00
{ . . . dragDropSharedProps }
value = { items [ 0 ] }
2021-03-29 14:07:39 +02:00
dropTypes = { undefined }
2021-02-05 18:17:03 +01:00
order = { [ 2 , 0 , 0 ] }
2020-11-03 21:18:44 +01:00
>
< span > 1 < / span >
< / DragDrop >
2021-03-29 14:07:39 +02:00
< DragDrop
{ . . . dragDropSharedProps }
value = { items [ 1 ] }
order = { [ 2 , 0 , 1 ] }
dropTypes = { [ 'reorder' ] }
>
2020-11-03 21:18:44 +01:00
< span > 2 < / span >
< / DragDrop >
2021-03-29 14:07:39 +02:00
< DragDrop
{ . . . dragDropSharedProps }
value = { items [ 2 ] }
order = { [ 2 , 0 , 2 ] }
dropTypes = { [ 'reorder' ] }
>
2020-11-03 21:18:44 +01:00
< span > 3 < / span >
< / DragDrop >
< / ReorderProvider >
< / ChildDragDropProvider >
) ;
2021-02-01 11:54:16 +01:00
} ;
2021-02-05 18:17:03 +01:00
test ( ` Inactive group renders properly ` , ( ) = > {
const component = mountComponent ( undefined ) ;
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
expect ( component . find ( '[data-test-subj="lnsDragDrop"]' ) ) . toHaveLength ( 5 ) ;
2020-11-03 21:18:44 +01:00
} ) ;
2021-02-01 11:54:16 +01:00
test ( ` Reorderable group with lifted element renders properly ` , ( ) = > {
const setA11yMessage = jest . fn ( ) ;
2021-02-05 18:17:03 +01:00
const setDragging = jest . fn ( ) ;
2021-02-15 12:48:06 +01:00
const component = mountComponent ( {
dragging : { . . . items [ 0 ] } ,
setDragging ,
setA11yMessage ,
} ) ;
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
2021-02-01 11:54:16 +01:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2021-02-15 12:48:06 +01:00
expect ( setDragging ) . toBeCalledWith ( { . . . items [ 0 ] } ) ;
2021-02-17 16:48:26 +01:00
expect ( setA11yMessage ) . toBeCalledWith ( 'Lifted Label1' ) ;
2021-02-01 11:54:16 +01:00
} ) ;
test ( ` Reordered elements get extra styles to show the reorder effect when dragging ` , ( ) = > {
2021-02-15 12:48:06 +01:00
const component = mountComponent ( { dragging : { . . . items [ 0 ] } } ) ;
2021-02-01 11:54:16 +01:00
2021-03-29 14:07:39 +02:00
component
. find ( '[data-test-subj="lnsDragDrop"]' )
. first ( )
. simulate ( 'dragstart' , { dataTransfer } ) ;
2021-02-01 11:54:16 +01:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
component
. find ( '[data-test-subj="lnsDragDrop-reorderableDropLayer"]' )
. at ( 1 )
. simulate ( 'dragover' ) ;
2020-11-11 12:36:04 +01:00
expect (
component . find ( '[data-test-subj="lnsDragDrop-reorderableDrag"]' ) . at ( 0 ) . prop ( 'style' )
2021-02-01 11:54:16 +01:00
) . toEqual ( undefined ) ;
2020-11-11 12:36:04 +01:00
expect (
2021-02-01 11:54:16 +01:00
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 0 ) . prop ( 'style' )
2020-11-11 12:36:04 +01:00
) . toEqual ( {
2021-02-01 11:54:16 +01:00
transform : 'translateY(-8px)' ,
2020-11-03 21:18:44 +01:00
} ) ;
2020-11-11 12:36:04 +01:00
expect (
2021-02-01 11:54:16 +01:00
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 1 ) . prop ( 'style' )
2020-11-11 12:36:04 +01:00
) . toEqual ( {
2021-02-01 11:54:16 +01:00
transform : 'translateY(-8px)' ,
2020-11-03 21:18:44 +01:00
} ) ;
2021-02-01 11:54:16 +01:00
component
. find ( '[data-test-subj="lnsDragDrop-reorderableDropLayer"]' )
. at ( 1 )
. simulate ( 'dragleave' ) ;
2020-11-11 12:36:04 +01:00
expect (
2021-02-01 11:54:16 +01:00
component . find ( '[data-test-subj="lnsDragDrop-reorderableDrag"]' ) . at ( 0 ) . prop ( 'style' )
) . toEqual ( undefined ) ;
2020-11-11 12:36:04 +01:00
expect (
2021-02-01 11:54:16 +01:00
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 1 ) . prop ( 'style' )
) . toEqual ( undefined ) ;
2020-11-03 21:18:44 +01:00
} ) ;
2021-02-01 11:54:16 +01:00
2020-11-03 21:18:44 +01:00
test ( ` Dropping an item runs onDrop function ` , ( ) = > {
const preventDefault = jest . fn ( ) ;
const stopPropagation = jest . fn ( ) ;
2021-02-05 18:17:03 +01:00
const setA11yMessage = jest . fn ( ) ;
const setDragging = jest . fn ( ) ;
2021-02-15 12:48:06 +01:00
const component = mountComponent ( {
dragging : { . . . items [ 0 ] } ,
setDragging ,
setA11yMessage ,
} ) ;
2020-11-03 21:18:44 +01:00
2021-03-29 14:07:39 +02:00
const dragDrop = component . find ( '[data-test-subj="lnsDragDrop-reorderableDropLayer"]' ) . at ( 1 ) ;
dragDrop . simulate ( 'dragOver' ) ;
dragDrop . simulate ( 'drop' , { preventDefault , stopPropagation } ) ;
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2021-02-01 11:54:16 +01:00
expect ( setA11yMessage ) . toBeCalledWith (
2021-03-29 14:07:39 +02:00
'Reordered Label1 in X group from position 1 to position 3'
2021-02-01 11:54:16 +01:00
) ;
2020-11-03 21:18:44 +01:00
expect ( preventDefault ) . toBeCalled ( ) ;
expect ( stopPropagation ) . toBeCalled ( ) ;
2021-02-15 12:48:06 +01:00
expect ( onDrop ) . toBeCalledWith ( { . . . items [ 0 ] } , 'reorder' ) ;
2020-11-03 21:18:44 +01:00
} ) ;
2021-02-01 11:54:16 +01:00
2021-02-05 18:17:03 +01:00
test ( ` Keyboard Navigation: User cannot move an element outside of the group ` , ( ) = > {
const setA11yMessage = jest . fn ( ) ;
const setActiveDropTarget = jest . fn ( ) ;
const component = mountComponent ( {
2021-02-15 12:48:06 +01:00
dragging : { . . . items [ 0 ] } ,
2021-02-05 18:17:03 +01:00
keyboardMode : true ,
2021-02-21 10:02:04 +01:00
activeDropTarget : undefined ,
dropTargetsByOrder : {
'2,0,0' : undefined ,
'2,0,1' : { . . . items [ 1 ] , onDrop , dropType : 'reorder' } ,
'2,0,2' : { . . . items [ 2 ] , onDrop , dropType : 'reorder' } ,
2021-02-01 11:54:16 +01:00
} ,
2021-02-05 18:17:03 +01:00
setActiveDropTarget ,
setA11yMessage ,
} ) ;
2021-03-29 14:07:39 +02:00
const keyboardHandler = component
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
. first ( ) ;
2021-02-05 18:17:03 +01:00
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowUp' } ) ;
expect ( setActiveDropTarget ) . not . toHaveBeenCalled ( ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowDown' } ) ;
2021-03-29 14:07:39 +02:00
expect ( setActiveDropTarget ) . toBeCalledWith ( { . . . items [ 1 ] , dropType : 'reorder' } ) ;
2021-02-05 18:17:03 +01:00
expect ( setA11yMessage ) . toBeCalledWith (
2021-02-17 16:48:26 +01:00
'Reorder Label1 in X group from position 1 to position 2. Press space or enter to reorder'
2021-02-01 11:54:16 +01:00
) ;
2021-02-05 18:17:03 +01:00
} ) ;
2021-03-29 14:07:39 +02:00
2021-02-05 18:17:03 +01:00
test ( ` Keyboard navigation: user can drop element to an activeDropTarget ` , ( ) = > {
const component = mountComponent ( {
2021-02-15 12:48:06 +01:00
dragging : { . . . items [ 0 ] } ,
2021-02-21 10:02:04 +01:00
activeDropTarget : { . . . items [ 2 ] , dropType : 'reorder' , onDrop } ,
dropTargetsByOrder : {
'2,0,0' : { . . . items [ 0 ] , onDrop , dropType : 'reorder' } ,
'2,0,1' : { . . . items [ 1 ] , onDrop , dropType : 'reorder' } ,
'2,0,2' : { . . . items [ 2 ] , onDrop , dropType : 'reorder' } ,
2021-02-05 18:17:03 +01:00
} ,
keyboardMode : true ,
} ) ;
2020-11-03 21:18:44 +01:00
const keyboardHandler = component
2021-02-01 11:54:16 +01:00
. find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' )
2021-03-29 14:07:39 +02:00
. first ( )
2021-02-01 11:54:16 +01:00
. simulate ( 'focus' ) ;
act ( ( ) = > {
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowDown' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowDown' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Enter' } ) ;
} ) ;
2021-02-05 18:17:03 +01:00
expect ( onDrop ) . toBeCalledWith ( items [ 0 ] , 'reorder' ) ;
} ) ;
test ( ` Keyboard Navigation: Doesn't call onDrop when movement is cancelled ` , ( ) = > {
const setA11yMessage = jest . fn ( ) ;
const onDropHandler = jest . fn ( ) ;
2021-02-15 12:48:06 +01:00
const component = mountComponent (
{ dragging : { . . . items [ 0 ] } , setA11yMessage } ,
onDropHandler
) ;
2021-02-05 18:17:03 +01:00
const keyboardHandler = component . find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Escape' } ) ;
2021-03-29 14:07:39 +02:00
act ( ( ) = > {
jest . runAllTimers ( ) ;
} ) ;
2021-02-05 18:17:03 +01:00
expect ( onDropHandler ) . not . toHaveBeenCalled ( ) ;
2021-02-17 16:48:26 +01:00
expect ( setA11yMessage ) . toBeCalledWith (
'Movement cancelled. Label1 returned to X group at position 1'
) ;
2021-02-05 18:17:03 +01:00
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowDown' } ) ;
keyboardHandler . simulate ( 'blur' ) ;
expect ( onDropHandler ) . not . toHaveBeenCalled ( ) ;
2021-02-17 16:48:26 +01:00
expect ( setA11yMessage ) . toBeCalledWith (
'Movement cancelled. Label1 returned to X group at position 1'
) ;
2021-02-01 11:54:16 +01:00
} ) ;
test ( ` Keyboard Navigation: Reordered elements get extra styles to show the reorder effect ` , ( ) = > {
const setA11yMessage = jest . fn ( ) ;
2021-02-05 18:17:03 +01:00
const component = mountComponent ( {
2021-02-15 12:48:06 +01:00
dragging : { . . . items [ 0 ] } ,
2021-02-05 18:17:03 +01:00
keyboardMode : true ,
2021-02-21 10:02:04 +01:00
activeDropTarget : undefined ,
dropTargetsByOrder : {
'2,0,0' : undefined ,
'2,0,1' : { . . . items [ 1 ] , onDrop , dropType : 'reorder' } ,
'2,0,2' : { . . . items [ 2 ] , onDrop , dropType : 'reorder' } ,
2021-02-05 18:17:03 +01:00
} ,
setA11yMessage ,
} ) ;
2020-11-03 21:18:44 +01:00
2021-02-01 11:54:16 +01:00
const keyboardHandler = component . find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' ) ;
2020-11-03 21:18:44 +01:00
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowDown' } ) ;
2021-02-01 11:54:16 +01:00
expect (
component . find ( '[data-test-subj="lnsDragDrop-reorderableDrag"]' ) . at ( 0 ) . prop ( 'style' )
) . toEqual ( {
transform : 'translateY(+8px)' ,
} ) ;
expect (
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 0 ) . prop ( 'style' )
) . toEqual ( {
transform : 'translateY(-40px)' ,
} ) ;
expect (
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 1 ) . prop ( 'style' )
) . toEqual ( undefined ) ;
expect ( setA11yMessage ) . toBeCalledWith (
2021-02-17 16:48:26 +01:00
'Reorder Label1 in X group from position 1 to position 2. Press space or enter to reorder'
2021-02-01 11:54:16 +01:00
) ;
component
. find ( '[data-test-subj="lnsDragDrop-reorderableDropLayer"]' )
. at ( 1 )
. simulate ( 'dragleave' ) ;
expect (
component . find ( '[data-test-subj="lnsDragDrop-reorderableDrag"]' ) . at ( 0 ) . prop ( 'style' )
) . toEqual ( undefined ) ;
expect (
component . find ( '[data-test-subj="lnsDragDrop-translatableDrop"]' ) . at ( 1 ) . prop ( 'style' )
) . toEqual ( undefined ) ;
2020-11-03 21:18:44 +01:00
} ) ;
2021-02-01 11:54:16 +01:00
test ( ` Keyboard Navigation: User cannot drop element to itself ` , ( ) = > {
const setA11yMessage = jest . fn ( ) ;
2021-02-05 18:17:03 +01:00
const setActiveDropTarget = jest . fn ( ) ;
2021-02-01 11:54:16 +01:00
const component = mount (
< ChildDragDropProvider
{ . . . defaultContext }
keyboardMode = { true }
activeDropTarget = { {
2021-02-21 10:02:04 +01:00
. . . items [ 1 ] ,
onDrop ,
dropType : 'reorder' ,
} }
dropTargetsByOrder = { {
'2,0,1,0' : undefined ,
'2,0,1,1' : { . . . items [ 1 ] , onDrop , dropType : 'reorder' } ,
2021-02-01 11:54:16 +01:00
} }
2021-02-15 12:48:06 +01:00
dragging = { { . . . items [ 0 ] } }
2021-02-01 11:54:16 +01:00
setActiveDropTarget = { setActiveDropTarget }
setA11yMessage = { setA11yMessage }
>
< ReorderProvider id = "groupId" >
< DragDrop
draggable
2021-02-05 18:17:03 +01:00
dragType = "move"
reorderableGroup = { [ items [ 0 ] , items [ 1 ] ] }
value = { items [ 0 ] }
order = { [ 2 , 0 , 1 , 0 ] }
2021-02-01 11:54:16 +01:00
>
< span > 1 < / span >
< / DragDrop >
< DragDrop
draggable
2021-02-05 18:17:03 +01:00
dragType = "move"
2021-03-29 14:07:39 +02:00
dropTypes = { [ 'reorder' ] }
2021-02-05 18:17:03 +01:00
reorderableGroup = { [ items [ 0 ] , items [ 1 ] ] }
value = { items [ 1 ] }
order = { [ 2 , 0 , 1 , 1 ] }
2021-02-01 11:54:16 +01:00
>
< span > 2 < / span >
< / DragDrop >
< / ReorderProvider >
< / ChildDragDropProvider >
) ;
const keyboardHandler = component . find ( '[data-test-subj="lnsDragDrop-keyboardHandler"]' ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'Space' } ) ;
keyboardHandler . simulate ( 'keydown' , { key : 'ArrowUp' } ) ;
2021-02-05 18:17:03 +01:00
expect ( setActiveDropTarget ) . toBeCalledWith ( undefined ) ;
2021-02-17 16:48:26 +01:00
expect ( setA11yMessage ) . toBeCalledWith ( 'Label1 returned to its initial position 1' ) ;
2020-11-03 21:18:44 +01:00
} ) ;
} ) ;
2019-09-17 20:57:53 +02:00
} ) ;