mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-04 15:10:06 +00:00
- Restore original useManagerQueue, useServerLogs, and comfyManagerService interfaces - Restore original component implementations for ManagerProgressDialogContent and ManagerProgressHeader - Fix all TypeScript interface compatibility issues by using original PR implementations - Remove duplicate setting that was causing runtime errors This fixes merge errors where interfaces were incorrectly mixed between old and new implementations.
330 lines
9.9 KiB
TypeScript
330 lines
9.9 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { nextTick } from 'vue'
|
|
|
|
import { useManagerQueue } from '@/composables/useManagerQueue'
|
|
import { api } from '@/scripts/api'
|
|
|
|
vi.mock('@/scripts/api', () => ({
|
|
api: {
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
dispatchEvent: vi.fn()
|
|
}
|
|
}))
|
|
|
|
describe('useManagerQueue', () => {
|
|
const createMockTask = (result: any = 'result') => ({
|
|
task: vi.fn().mockResolvedValue(result),
|
|
onComplete: vi.fn()
|
|
})
|
|
|
|
const createQueueWithMockTask = () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask = createMockTask()
|
|
queue.enqueueTask(mockTask)
|
|
return { queue, mockTask }
|
|
}
|
|
|
|
const getEventListenerCallback = () =>
|
|
vi.mocked(api.addEventListener).mock.calls[0][1]
|
|
|
|
const simulateServerStatus = async (status: 'all-done' | 'in_progress') => {
|
|
const event = new CustomEvent('cm-queue-status', {
|
|
detail: { status }
|
|
})
|
|
getEventListenerCallback()!(event as any)
|
|
await nextTick()
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('initialization', () => {
|
|
it('should initialize with empty queue and DONE status', () => {
|
|
const queue = useManagerQueue()
|
|
|
|
expect(queue.queueLength.value).toBe(0)
|
|
expect(queue.statusMessage.value).toBe('all-done')
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('queue management', () => {
|
|
it('should add tasks to the queue', () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask = createMockTask()
|
|
|
|
queue.enqueueTask(mockTask)
|
|
|
|
expect(queue.queueLength.value).toBe(1)
|
|
expect(queue.allTasksDone.value).toBe(false)
|
|
})
|
|
|
|
it('should clear the queue when clearQueue is called', () => {
|
|
const queue = useManagerQueue()
|
|
|
|
// Add some tasks
|
|
queue.enqueueTask(createMockTask())
|
|
queue.enqueueTask(createMockTask())
|
|
|
|
expect(queue.queueLength.value).toBe(2)
|
|
|
|
// Clear the queue
|
|
queue.clearQueue()
|
|
|
|
expect(queue.queueLength.value).toBe(0)
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('server status handling', () => {
|
|
it('should update server status when receiving websocket events', async () => {
|
|
const queue = useManagerQueue()
|
|
|
|
await simulateServerStatus('in_progress')
|
|
|
|
expect(queue.statusMessage.value).toBe('in_progress')
|
|
expect(queue.allTasksDone.value).toBe(false)
|
|
})
|
|
|
|
it('should handle invalid status values gracefully', async () => {
|
|
const queue = useManagerQueue()
|
|
|
|
// Simulate an invalid status
|
|
const event = new CustomEvent('cm-queue-status', {
|
|
detail: null as any
|
|
})
|
|
|
|
getEventListenerCallback()!(event)
|
|
await nextTick()
|
|
|
|
// Should maintain the default status
|
|
expect(queue.statusMessage.value).toBe('all-done')
|
|
})
|
|
|
|
it('should handle missing status property gracefully', async () => {
|
|
const queue = useManagerQueue()
|
|
|
|
// Simulate a detail object without status property
|
|
const event = new CustomEvent('cm-queue-status', {
|
|
detail: { someOtherProperty: 'value' } as any
|
|
})
|
|
|
|
getEventListenerCallback()!(event)
|
|
await nextTick()
|
|
|
|
// Should maintain the default status
|
|
expect(queue.statusMessage.value).toBe('all-done')
|
|
})
|
|
})
|
|
|
|
describe('task execution', () => {
|
|
it('should start the next task when server is idle and queue has items', async () => {
|
|
const { queue, mockTask } = createQueueWithMockTask()
|
|
|
|
await simulateServerStatus('all-done')
|
|
|
|
// Task should have been started
|
|
expect(mockTask.task).toHaveBeenCalled()
|
|
expect(queue.queueLength.value).toBe(0)
|
|
})
|
|
|
|
it('should execute onComplete callback when task completes and server becomes idle', async () => {
|
|
const { mockTask } = createQueueWithMockTask()
|
|
|
|
// Start the task
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask.task).toHaveBeenCalled()
|
|
|
|
// Simulate task completion
|
|
await mockTask.task.mock.results[0].value
|
|
|
|
// Simulate server cycle (in_progress -> done)
|
|
await simulateServerStatus('in_progress')
|
|
expect(mockTask.onComplete).not.toHaveBeenCalled()
|
|
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask.onComplete).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle tasks without onComplete callback', async () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask = { task: vi.fn().mockResolvedValue('result') }
|
|
|
|
queue.enqueueTask(mockTask)
|
|
|
|
// Start the task
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask.task).toHaveBeenCalled()
|
|
|
|
// Simulate task completion
|
|
await mockTask.task.mock.results[0].value
|
|
|
|
// Simulate server cycle
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
|
|
// Should not throw errors even without onComplete
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
|
|
it('should process multiple tasks in sequence', async () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask1 = createMockTask('result1')
|
|
const mockTask2 = createMockTask('result2')
|
|
|
|
// Add tasks to the queue
|
|
queue.enqueueTask(mockTask1)
|
|
queue.enqueueTask(mockTask2)
|
|
expect(queue.queueLength.value).toBe(2)
|
|
|
|
// Process first task
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask1.task).toHaveBeenCalled()
|
|
expect(queue.queueLength.value).toBe(1)
|
|
|
|
// Complete first task
|
|
await mockTask1.task.mock.results[0].value
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask1.onComplete).toHaveBeenCalled()
|
|
|
|
// Process second task
|
|
expect(mockTask2.task).toHaveBeenCalled()
|
|
expect(queue.queueLength.value).toBe(0)
|
|
|
|
// Complete second task
|
|
await mockTask2.task.mock.results[0].value
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask2.onComplete).toHaveBeenCalled()
|
|
|
|
// Queue should be empty and all tasks done
|
|
expect(queue.queueLength.value).toBe(0)
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
|
|
it('should handle task that returns rejected promise', async () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask = {
|
|
task: vi.fn().mockRejectedValue(new Error('Task failed')),
|
|
onComplete: vi.fn()
|
|
}
|
|
|
|
queue.enqueueTask(mockTask)
|
|
|
|
// Start the task
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask.task).toHaveBeenCalled()
|
|
|
|
// Let the promise rejection happen
|
|
try {
|
|
await mockTask.task()
|
|
} catch (e) {
|
|
// Ignore the error
|
|
}
|
|
|
|
// Simulate server cycle
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
|
|
// onComplete should still be called for failed tasks
|
|
expect(mockTask.onComplete).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle multiple multiple tasks enqueued at once while server busy', async () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask1 = createMockTask()
|
|
const mockTask2 = createMockTask()
|
|
const mockTask3 = createMockTask()
|
|
|
|
// Three tasks enqueued at once
|
|
await simulateServerStatus('in_progress')
|
|
await Promise.all([
|
|
queue.enqueueTask(mockTask1),
|
|
queue.enqueueTask(mockTask2),
|
|
queue.enqueueTask(mockTask3)
|
|
])
|
|
|
|
// Task 1
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask1.task).toHaveBeenCalled()
|
|
|
|
// Verify state of onComplete callbacks
|
|
expect(mockTask1.onComplete).toHaveBeenCalled()
|
|
expect(mockTask2.onComplete).not.toHaveBeenCalled()
|
|
expect(mockTask3.onComplete).not.toHaveBeenCalled()
|
|
|
|
// Verify state of queue
|
|
expect(queue.queueLength.value).toBe(2)
|
|
expect(queue.allTasksDone.value).toBe(false)
|
|
|
|
// Task 2
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask2.task).toHaveBeenCalled()
|
|
|
|
// Verify state of onComplete callbacks
|
|
expect(mockTask2.onComplete).toHaveBeenCalled()
|
|
expect(mockTask3.onComplete).not.toHaveBeenCalled()
|
|
|
|
// Verify state of queue
|
|
expect(queue.queueLength.value).toBe(1)
|
|
expect(queue.allTasksDone.value).toBe(false)
|
|
|
|
// Task 3
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
|
|
// Verify state of onComplete callbacks
|
|
expect(mockTask3.task).toHaveBeenCalled()
|
|
expect(mockTask3.onComplete).toHaveBeenCalled()
|
|
|
|
// Verify state of queue
|
|
expect(queue.queueLength.value).toBe(0)
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
|
|
it('should handle adding tasks while processing is in progress', async () => {
|
|
const queue = useManagerQueue()
|
|
const mockTask1 = createMockTask()
|
|
const mockTask2 = createMockTask()
|
|
|
|
// Add first task and start processing
|
|
queue.enqueueTask(mockTask1)
|
|
await simulateServerStatus('all-done')
|
|
expect(mockTask1.task).toHaveBeenCalled()
|
|
|
|
// Add second task while first is processing
|
|
queue.enqueueTask(mockTask2)
|
|
expect(queue.queueLength.value).toBe(1)
|
|
|
|
// Complete first task
|
|
await mockTask1.task.mock.results[0].value
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
|
|
// Second task should now be processed
|
|
expect(mockTask2.task).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle server status changes without tasks in queue', async () => {
|
|
const queue = useManagerQueue()
|
|
|
|
// Cycle server status without any tasks
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
await simulateServerStatus('in_progress')
|
|
await simulateServerStatus('all-done')
|
|
|
|
// Should not cause any errors
|
|
expect(queue.allTasksDone.value).toBe(true)
|
|
})
|
|
})
|
|
})
|