mirror of
https://github.com/apache/superset.git
synced 2026-06-11 18:49:15 +00:00
121 lines
4.1 KiB
TypeScript
121 lines
4.1 KiB
TypeScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
import {
|
|
DroppableData,
|
|
resolveDragEnd,
|
|
} from 'src/explore/components/ExploreContainer/ExploreDndContext';
|
|
import { DndItemType } from 'src/explore/components/DndItemType';
|
|
import { DndItemValue } from 'src/explore/components/DatasourcePanel/types';
|
|
|
|
/**
|
|
* @dnd-kit's PointerSensor only reacts to real pointer events, which jsdom
|
|
* cannot meaningfully dispatch (it has no layout). To exercise drop behavior in
|
|
* unit tests we capture the `data` object a control registers via
|
|
* `useDroppable` and feed it through the same `resolveDragEnd` dispatcher the
|
|
* live `ExploreDndContextProvider` runs on drag end.
|
|
*
|
|
* Usage: spy on `useDroppable` with `captureDroppableData`, render the control,
|
|
* then call `simulateDrop` with the dragged item.
|
|
*/
|
|
export type CapturedDroppable = { current: DroppableData | undefined };
|
|
|
|
/**
|
|
* Returns a `jest.fn` mock implementation for `@dnd-kit/core`'s `useDroppable`
|
|
* that records the most recently registered droppable data into `captured`,
|
|
* while returning an inert droppable shape so the control still renders.
|
|
*/
|
|
export function captureDroppableData(captured: CapturedDroppable) {
|
|
return (args: { data?: DroppableData }) => {
|
|
captured.current = args?.data;
|
|
return {
|
|
setNodeRef: () => {},
|
|
isOver: false,
|
|
active: null,
|
|
rect: { current: null },
|
|
node: { current: null },
|
|
over: null,
|
|
};
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Drives a single drag-and-drop of `item` onto the captured droppable through
|
|
* the production `resolveDragEnd` dispatcher.
|
|
*/
|
|
export function simulateDrop(
|
|
captured: CapturedDroppable,
|
|
item: { type: DndItemType; value: DndItemValue },
|
|
) {
|
|
resolveDragEnd(
|
|
{ id: 'drag-source', data: { current: item } },
|
|
{ id: 'dropzone', data: { current: captured.current ?? {} } },
|
|
);
|
|
}
|
|
|
|
export type SortableItemData = {
|
|
type: string;
|
|
dragIndex: number;
|
|
onShiftOptions?: (dragIndex: number, hoverIndex: number) => void;
|
|
onMoveLabel?: (dragIndex: number, hoverIndex: number) => void;
|
|
onDropLabel?: () => void;
|
|
};
|
|
|
|
export type CapturedSortables = { items: SortableItemData[] };
|
|
|
|
/**
|
|
* Returns a `jest.fn` implementation for `@dnd-kit/sortable`'s `useSortable`
|
|
* that records each sortable item's registered data (carrying the reorder
|
|
* callbacks) into `captured`, while returning an inert sortable shape so the
|
|
* control still renders.
|
|
*/
|
|
export function captureSortableData(captured: CapturedSortables) {
|
|
return (args: { data?: SortableItemData }) => {
|
|
if (args?.data) {
|
|
captured.items.push(args.data);
|
|
}
|
|
return {
|
|
attributes: {},
|
|
listeners: {},
|
|
setNodeRef: () => {},
|
|
transform: null,
|
|
transition: undefined,
|
|
isDragging: false,
|
|
setActivatorNodeRef: () => {},
|
|
};
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Drives an in-list reorder (drag item at `fromIndex` over item at `toIndex`)
|
|
* through the production `resolveDragEnd` dispatcher, using the reorder
|
|
* callbacks the control registered on its sortable items.
|
|
*/
|
|
export function simulateReorder(
|
|
captured: CapturedSortables,
|
|
fromIndex: number,
|
|
toIndex: number,
|
|
) {
|
|
const from = captured.items.find(i => i.dragIndex === fromIndex);
|
|
const to = captured.items.find(i => i.dragIndex === toIndex);
|
|
resolveDragEnd(
|
|
{ id: `from-${fromIndex}`, data: { current: from } },
|
|
{ id: `to-${toIndex}`, data: { current: to } },
|
|
);
|
|
}
|