mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-28 10:12:11 +00:00
Merge remote-tracking branch 'origin/main' into feat/new-workflow-templates
This commit is contained in:
@@ -2,12 +2,8 @@ import { createPinia, setActivePinia } from 'pinia'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems'
|
||||
import {
|
||||
LGraphEventMode,
|
||||
LGraphNode,
|
||||
Positionable,
|
||||
Reroute
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphNode, Positionable } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphEventMode, Reroute } from '@/lib/litegraph/src/litegraph'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { app } from '@/scripts/app'
|
||||
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useCanvasInteractions } from '@/composables/graph/useCanvasInteractions'
|
||||
import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
|
||||
// Mock stores
|
||||
vi.mock('@/renderer/core/canvas/canvasStore', () => {
|
||||
const getCanvas = vi.fn()
|
||||
const setCursorStyle = vi.fn()
|
||||
return {
|
||||
useCanvasStore: vi.fn(() => ({
|
||||
getCanvas,
|
||||
setCursorStyle
|
||||
}))
|
||||
}
|
||||
})
|
||||
vi.mock('@/platform/settings/settingStore', () => {
|
||||
const getFn = vi.fn()
|
||||
return { useSettingStore: vi.fn(() => ({ get: getFn })) }
|
||||
})
|
||||
vi.mock('@/scripts/app', () => ({
|
||||
app: {
|
||||
canvas: {
|
||||
canvas: {
|
||||
dispatchEvent: vi.fn()
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
function createMockLGraphCanvas(read_only = true): LGraphCanvas {
|
||||
const mockCanvas: Partial<LGraphCanvas> = { read_only }
|
||||
return mockCanvas as LGraphCanvas
|
||||
}
|
||||
|
||||
function createMockPointerEvent(
|
||||
buttons: PointerEvent['buttons'] = 1
|
||||
): PointerEvent {
|
||||
const mockEvent: Partial<PointerEvent> = {
|
||||
buttons,
|
||||
preventDefault: vi.fn(),
|
||||
stopPropagation: vi.fn()
|
||||
}
|
||||
return mockEvent as PointerEvent
|
||||
}
|
||||
|
||||
function createMockWheelEvent(ctrlKey = false, metaKey = false): WheelEvent {
|
||||
const mockEvent: Partial<WheelEvent> = {
|
||||
ctrlKey,
|
||||
metaKey,
|
||||
preventDefault: vi.fn(),
|
||||
stopPropagation: vi.fn()
|
||||
}
|
||||
return mockEvent as WheelEvent
|
||||
}
|
||||
|
||||
describe('useCanvasInteractions', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks()
|
||||
})
|
||||
|
||||
describe('handlePointer', () => {
|
||||
it('should intercept left mouse events when canvas is read_only to enable space+drag navigation', () => {
|
||||
const { getCanvas } = useCanvasStore()
|
||||
const mockCanvas = createMockLGraphCanvas(true)
|
||||
vi.mocked(getCanvas).mockReturnValue(mockCanvas)
|
||||
|
||||
const { handlePointer } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockPointerEvent(1) // Left Mouse Button
|
||||
handlePointer(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should forward middle mouse button events to canvas', () => {
|
||||
const { getCanvas } = useCanvasStore()
|
||||
const mockCanvas = createMockLGraphCanvas(false)
|
||||
vi.mocked(getCanvas).mockReturnValue(mockCanvas)
|
||||
const { handlePointer } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockPointerEvent(4) // Middle mouse button
|
||||
handlePointer(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not prevent default when canvas is not in read_only mode and not middle button', () => {
|
||||
const { getCanvas } = useCanvasStore()
|
||||
const mockCanvas = createMockLGraphCanvas(false)
|
||||
vi.mocked(getCanvas).mockReturnValue(mockCanvas)
|
||||
const { handlePointer } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockPointerEvent(1)
|
||||
handlePointer(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).not.toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should return early when canvas is null', () => {
|
||||
const { getCanvas } = useCanvasStore()
|
||||
vi.mocked(getCanvas).mockReturnValue(null as unknown as LGraphCanvas) // TODO: Fix misaligned types
|
||||
const { handlePointer } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockPointerEvent(1)
|
||||
handlePointer(mockEvent)
|
||||
|
||||
expect(getCanvas).toHaveBeenCalled()
|
||||
expect(mockEvent.preventDefault).not.toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleWheel', () => {
|
||||
it('should forward ctrl+wheel events to canvas in standard nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('standard')
|
||||
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
// Ctrl key pressed
|
||||
const mockEvent = createMockWheelEvent(true)
|
||||
|
||||
handleWheel(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should forward all wheel events to canvas in legacy nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('legacy')
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockWheelEvent()
|
||||
handleWheel(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not prevent default for regular wheel events in standard nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('standard')
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockWheelEvent()
|
||||
handleWheel(mockEvent)
|
||||
|
||||
expect(mockEvent.preventDefault).not.toHaveBeenCalled()
|
||||
expect(mockEvent.stopPropagation).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { useManagerQueue } from '@/composables/useManagerQueue'
|
||||
import { components } from '@/types/generatedManagerTypes'
|
||||
import type { components } from '@/types/generatedManagerTypes'
|
||||
|
||||
// Mock dialog service
|
||||
vi.mock('@/services/dialogService', () => ({
|
||||
|
||||
@@ -56,10 +56,10 @@ describe('useManagerState', () => {
|
||||
})
|
||||
|
||||
describe('managerUIState property', () => {
|
||||
it('should return DISABLED state when --disable-manager is present', () => {
|
||||
it('should return DISABLED state when --enable-manager is NOT present', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--disable-manager'] }
|
||||
system: { argv: ['python', 'main.py'] } // No --enable-manager flag
|
||||
}),
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
@@ -76,7 +76,14 @@ describe('useManagerState', () => {
|
||||
it('should return LEGACY_UI state when --enable-manager-legacy-ui is present', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager-legacy-ui'] }
|
||||
system: {
|
||||
argv: [
|
||||
'python',
|
||||
'main.py',
|
||||
'--enable-manager',
|
||||
'--enable-manager-legacy-ui'
|
||||
]
|
||||
} // Both flags needed
|
||||
}),
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
@@ -92,7 +99,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('should return NEW_UI state when client and server both support v4', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
@@ -114,7 +123,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('should return LEGACY_UI state when server supports v4 but client does not', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
@@ -136,7 +147,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('should return LEGACY_UI state when legacy manager extension exists', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({})
|
||||
@@ -155,7 +168,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('should return NEW_UI state when server feature flags are undefined', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({})
|
||||
@@ -175,7 +190,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('should return LEGACY_UI state when server does not support v4', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({})
|
||||
@@ -212,14 +229,17 @@ describe('useManagerState', () => {
|
||||
|
||||
const managerState = useManagerState()
|
||||
|
||||
expect(managerState.managerUIState.value).toBe(ManagerUIState.NEW_UI)
|
||||
// When systemStats is null, we can't check for --enable-manager flag, so manager is disabled
|
||||
expect(managerState.managerUIState.value).toBe(ManagerUIState.DISABLED)
|
||||
})
|
||||
})
|
||||
|
||||
describe('helper properties', () => {
|
||||
it('isManagerEnabled should return true when state is not DISABLED', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
@@ -237,7 +257,7 @@ describe('useManagerState', () => {
|
||||
it('isManagerEnabled should return false when state is DISABLED', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--disable-manager'] }
|
||||
system: { argv: ['python', 'main.py'] } // No --enable-manager flag means disabled
|
||||
}),
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
@@ -252,7 +272,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('isNewManagerUI should return true when state is NEW_UI', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
@@ -270,7 +292,14 @@ describe('useManagerState', () => {
|
||||
it('isLegacyManagerUI should return true when state is LEGACY_UI', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager-legacy-ui'] }
|
||||
system: {
|
||||
argv: [
|
||||
'python',
|
||||
'main.py',
|
||||
'--enable-manager',
|
||||
'--enable-manager-legacy-ui'
|
||||
]
|
||||
} // Both flags needed
|
||||
}),
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
@@ -285,7 +314,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('shouldShowInstallButton should return true only for NEW_UI', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
@@ -302,7 +333,9 @@ describe('useManagerState', () => {
|
||||
|
||||
it('shouldShowManagerButtons should return true when not DISABLED', () => {
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue({
|
||||
systemStats: ref({ system: { argv: ['python', 'main.py'] } }),
|
||||
systemStats: ref({
|
||||
system: { argv: ['python', 'main.py', '--enable-manager'] }
|
||||
}), // Need --enable-manager
|
||||
isInitialized: ref(true)
|
||||
} as any)
|
||||
vi.mocked(api.getClientFeatureFlags).mockReturnValue({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useNodeChatHistory } from '@/composables/node/useNodeChatHistory'
|
||||
import { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
|
||||
vi.mock(
|
||||
'@/renderer/extensions/vueNodes/widgets/composables/useChatHistoryWidget',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
import { useServerLogs } from '@/composables/useServerLogs'
|
||||
import { LogsWsMessage } from '@/schemas/apiSchema'
|
||||
import type { LogsWsMessage } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
|
||||
vi.mock('@/scripts/api', () => ({
|
||||
|
||||
Reference in New Issue
Block a user