diff --git a/packages/core/admin/admin/src/content-manager/hooks/tests/useKeyboardDragAndDrop.test.js b/packages/core/admin/admin/src/content-manager/hooks/tests/useKeyboardDragAndDrop.test.js new file mode 100644 index 0000000000..2a5277a2ba --- /dev/null +++ b/packages/core/admin/admin/src/content-manager/hooks/tests/useKeyboardDragAndDrop.test.js @@ -0,0 +1,196 @@ +import { act, renderHook } from '@testing-library/react-hooks'; + +import { useKeyboardDragAndDrop } from '../useKeyboardDragAndDrop'; + +describe('useKeyboardDragAndDrop', () => { + const event = (key) => ({ + preventDefault: jest.fn(), + key, + }); + + describe('onGrabItem', () => { + it('should be called when the event is the enter key', () => { + const onGrabItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onGrabItem })); + + act(() => { + result.current(event('Enter')); + }); + + expect(onGrabItem).toHaveBeenCalledWith(0); + }); + + it('should be called when the event is the space key', () => { + const onGrabItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onGrabItem })); + + act(() => { + result.current(event(' ')); + }); + + expect(onGrabItem).toHaveBeenCalledWith(0); + }); + }); + + describe('onDropItem', () => { + it('should be called after the enter key is pressed twice', () => { + const onDropItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onDropItem })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('Enter')); + }); + + expect(onDropItem).toHaveBeenCalledWith(0); + }); + + it('should be called after the space key is pressed twice', () => { + const onDropItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onDropItem })); + + act(() => { + result.current(event(' ')); + }); + + act(() => { + result.current(event(' ')); + }); + + expect(onDropItem).toHaveBeenCalledWith(0); + }); + }); + + describe('onCancel', () => { + it('should be called when the escape key is pressed provided that the enter or space key has been pressed first', () => { + const onCancel = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onCancel })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('Escape')); + }); + + expect(onCancel).toHaveBeenCalledWith(0); + + act(() => { + result.current(event(' ')); + }); + + act(() => { + result.current(event('Escape')); + }); + + expect(onCancel).toHaveBeenCalledTimes(2); + }); + + it('should not be called if neither the space nor enter key have been pressed first', () => { + const onCancel = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onCancel })); + + act(() => { + result.current(event('Escape')); + }); + + expect(onCancel).not.toHaveBeenCalled(); + }); + }); + + describe('onMoveItem', () => { + it('should be called when the down arrow is pressed provided the enter key has been pressed first', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onMoveItem })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('ArrowDown')); + }); + + expect(onMoveItem).toHaveBeenCalledWith(1, 0); + }); + + it('should be called when the right arrow is pressed provided the enter key has been pressed first', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onMoveItem })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('ArrowRight')); + }); + + expect(onMoveItem).toHaveBeenCalledWith(1, 0); + }); + + it('should not be called with either the down arrow or right arrow if the enter key has not been pressed prior', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(0, { onMoveItem })); + + act(() => { + result.current(event('ArrowDown')); + }); + + act(() => { + result.current(event('ArrowRight')); + }); + + expect(onMoveItem).not.toHaveBeenCalled(); + }); + + it('should be called when the up arrow is pressed provided the enter key has been pressed first', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(1, { onMoveItem })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('ArrowUp')); + }); + + expect(onMoveItem).toHaveBeenCalledWith(0, 1); + }); + + it('should be called when the left arrow is pressed provided the enter key has been pressed first', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(1, { onMoveItem })); + + act(() => { + result.current(event('Enter')); + }); + + act(() => { + result.current(event('ArrowLeft')); + }); + + expect(onMoveItem).toHaveBeenCalledWith(0, 1); + }); + + it('should not be called with either the left or up arrow key if the enter key has not been pressed first', () => { + const onMoveItem = jest.fn(); + const { result } = renderHook(() => useKeyboardDragAndDrop(1, { onMoveItem })); + + act(() => { + result.current(event('ArrowUp')); + }); + + act(() => { + result.current(event('ArrowLeft')); + }); + + expect(onMoveItem).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/core/admin/admin/src/content-manager/hooks/__test__/usePrev.test.js b/packages/core/admin/admin/src/content-manager/hooks/tests/usePrev.test.js similarity index 100% rename from packages/core/admin/admin/src/content-manager/hooks/__test__/usePrev.test.js rename to packages/core/admin/admin/src/content-manager/hooks/tests/usePrev.test.js diff --git a/packages/core/admin/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js b/packages/core/admin/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js index a11c4e6a82..81086df11c 100644 --- a/packages/core/admin/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js +++ b/packages/core/admin/admin/src/content-manager/hooks/useKeyboardDragAndDrop.js @@ -49,10 +49,12 @@ export const useKeyboardDragAndDrop = (index, { onCancel, onDropItem, onGrabItem }; const handleCancel = () => { - setIsSelected(false); + if (isSelected) { + setIsSelected(false); - if (onCancel) { - onCancel(index); + if (onCancel) { + onCancel(index); + } } };