diff --git a/frontend/src/common/drag-and-drop/sortable-lists-engine.preview.spec.ts b/frontend/src/common/drag-and-drop/sortable-lists-engine.preview.spec.ts index 22ead4d7e03f..ce1b72862165 100644 --- a/frontend/src/common/drag-and-drop/sortable-lists-engine.preview.spec.ts +++ b/frontend/src/common/drag-and-drop/sortable-lists-engine.preview.spec.ts @@ -29,21 +29,21 @@ // The drag preview's `getOffset` decides where the pointer sits on the // preview, and Pragmatic only hands it to the real `setCustomNativeDragPreview` // — nothing observable from the outside. So this file mocks that module and -// reads the options back, which the sibling engine spec cannot do: it renders -// previews for real. Separate file rather than a mock added there, because the -// suite runs with `isolate: false` and shares one module registry. +// reads the options back. It stays a separate file from the sibling engine +// spec because that one renders previews for real, and one file cannot both +// stub and exercise the same module. import { vi } from 'vitest'; import { NativeDragSimulation } from 'core-common/drag-and-drop/testing/native-drag-simulation'; -import { createSortableRoot } from './sortable-lists-engine'; +import type { createSortableRoot as createSortableRootFn } from './sortable-lists-engine'; -const { previewCalls } = vi.hoisted(() => ({ - previewCalls: [] as { - getOffset?:(args:{ container:HTMLElement }) => { x:number; y:number }; - }[], -})); +// `doMock` is not hoisted, so this initialises before the factory below runs +// and a plain const does the job `vi.hoisted()` used to. +const previewCalls:{ + getOffset?:(args:{ container:HTMLElement }) => { x:number; y:number }; +}[] = []; -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ setCustomNativeDragPreview: (options:{ getOffset?:(args:{ container:HTMLElement }) => { x:number; y:number }; }) => { @@ -51,9 +51,15 @@ vi.mock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-previe }, })); +let createSortableRoot:typeof createSortableRootFn; + describe('createSortableRoot drag preview offset', () => { let cleanupFns:(() => void)[] = []; + beforeAll(async () => { + ({ createSortableRoot } = await import('./sortable-lists-engine')); + }); + beforeEach(() => { previewCalls.length = 0; }); afterEach(() => { diff --git a/frontend/src/common/drag-and-drop/sortable-lists-engine.spec.ts b/frontend/src/common/drag-and-drop/sortable-lists-engine.spec.ts index f515b3b28b43..ed0ddcf6e350 100644 --- a/frontend/src/common/drag-and-drop/sortable-lists-engine.spec.ts +++ b/frontend/src/common/drag-and-drop/sortable-lists-engine.spec.ts @@ -32,23 +32,23 @@ import { centerOf, towardsEdgeOf, } from 'core-common/drag-and-drop/testing/native-drag-simulation'; -import { - createSortableRoot, - type SortableDropIntent, - type SortableDropTransaction, - type SortableSource, +import type { + createSortableRoot as createSortableRootFn, + SortableDropIntent, + SortableDropTransaction, + SortableSource, } from './sortable-lists-engine'; -const { autoScrollRegistrations } = vi.hoisted(() => ({ - autoScrollRegistrations: [] as { - element:Element; - getAllowedAxis:() => string; - cleanup:() => void; - cleaned:boolean; - }[], -})); +// `doMock` is not hoisted, so this initialises before the factory below runs +// and a plain const does the job `vi.hoisted()` used to. +const autoScrollRegistrations:{ + element:Element; + getAllowedAxis:() => string; + cleanup:() => void; + cleaned:boolean; +}[] = []; -vi.mock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ autoScrollForElements: (args:{ element:Element; getAllowedAxis:() => string }) => { const entry = { element: args.element, @@ -62,6 +62,8 @@ vi.mock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ }, })); +let createSortableRoot:typeof createSortableRootFn; + const liveRegistrations = () => autoScrollRegistrations.filter((r) => !r.cleaned); function buildList(items:string[]):{ root:HTMLElement; rows:HTMLElement[] } { @@ -145,6 +147,10 @@ function buildCardGrid(items:string[], columns:number):{ root:HTMLElement; cards describe('createSortableRoot', () => { let cleanupFns:(() => void)[] = []; + beforeAll(async () => { + ({ createSortableRoot } = await import('./sortable-lists-engine')); + }); + beforeEach(() => { autoScrollRegistrations.length = 0; }); afterEach(() => { diff --git a/frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts b/frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts index 5de5ccdc9fbd..7faa53bb682b 100644 --- a/frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts +++ b/frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts @@ -26,31 +26,32 @@ // See COPYRIGHT and LICENSE files for more details. //++ -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ +// vi.doMock is not hoisted above imports, unlike vi.mock, so the subject +// below is imported dynamically further down, after these calls run. +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ draggable: vi.fn(() => vi.fn()), dropTargetForElements: vi.fn(() => vi.fn()), monitorForElements: vi.fn(() => vi.fn()), })); -vi.mock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ autoScrollForElements: vi.fn(() => vi.fn()), })); -// This spec mounts the real item controller, which pulls in these modules. -// Tests share one module registry (the runner does not isolate spec files), -// so importing the real versions here would leak into the item controller -// spec and break its spies. Mock them to keep the shared cache inert. -vi.mock('@atlaskit/pragmatic-drag-and-drop/combine', () => ({ +// This spec mounts the real item controller, which pulls in these three +// modules. Stub them so its Pragmatic side effects stay inert; nothing +// here reads them back. +vi.doMock('@atlaskit/pragmatic-drag-and-drop/combine', () => ({ combine: vi.fn((...cleanups:(() => void)[]) => vi.fn(() => { cleanups.forEach((cleanup) => cleanup()); })), })); -vi.mock('@atlaskit/pragmatic-drag-and-drop/prevent-unhandled', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/prevent-unhandled', () => ({ preventUnhandled: { start: vi.fn(), stop: vi.fn() }, })); -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ setCustomNativeDragPreview: vi.fn(), })); diff --git a/frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts b/frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts index c9019b173eb3..ccd45ecf37fb 100644 --- a/frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts +++ b/frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts @@ -26,26 +26,28 @@ // See COPYRIGHT and LICENSE files for more details. //++ -vi.mock('@atlaskit/pragmatic-drag-and-drop/combine', () => ({ +// vi.doMock is not hoisted above imports, unlike vi.mock, so the subject +// below is imported dynamically further down, after these calls run. +vi.doMock('@atlaskit/pragmatic-drag-and-drop/combine', () => ({ combine: vi.fn((...cleanups:(() => void)[]) => vi.fn(() => { cleanups.forEach((cleanup) => cleanup()); })), })); -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ draggable: vi.fn(() => vi.fn()), dropTargetForElements: vi.fn(() => vi.fn()), monitorForElements: vi.fn(() => vi.fn()), })); -vi.mock('@atlaskit/pragmatic-drag-and-drop/prevent-unhandled', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/prevent-unhandled', () => ({ preventUnhandled: { start: vi.fn(), stop: vi.fn(), }, })); -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview', () => ({ setCustomNativeDragPreview: vi.fn(), })); diff --git a/frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts b/frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts index e1eaa25599f0..5593dd5ee549 100644 --- a/frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts +++ b/frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts @@ -26,7 +26,9 @@ // See COPYRIGHT and LICENSE files for more details. //++ -vi.mock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ +// vi.doMock is not hoisted above imports, unlike vi.mock, so the subject +// below is imported dynamically further down, after these calls run. +vi.doMock('@atlaskit/pragmatic-drag-and-drop/element/adapter', () => ({ draggable: vi.fn(() => vi.fn()), dropTargetForElements: vi.fn(() => vi.fn()), monitorForElements: vi.fn(() => vi.fn()), diff --git a/frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts b/frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts index 8729e01054bc..3aee914532e2 100644 --- a/frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts +++ b/frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts @@ -31,7 +31,7 @@ import { setupStimulusTest, type StimulusTestContext } from 'core-stimulus/test- import type ScrollableControllerType from './scrollable.controller'; import type { sortableItemData as sortableItemDataFn, SortableListsRoot } from './drag-and-drop'; -vi.mock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ +vi.doMock('@atlaskit/pragmatic-drag-and-drop-auto-scroll/element', () => ({ autoScrollForElements: vi.fn(() => vi.fn()), }));