mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
test: address PR review feedback on desktop-ui unit tests
- Assert isRunningInstallationFix resets to false after execution - Verify specific URLs in window.open assertions - Fix invalid slot HTML in TaskCard stub template - Assert concrete normalized URL value instead of typeof check - Eliminate renderCard duplication via optional task param - Remove toHaveProperty change-detector test per project guidelines - Replace as unknown as Terminal with Pick<Terminal, 'write'> - Extract shared withSetup helper to src/test/withSetup.ts - Remove initial state change-detector tests per project guidelines
This commit is contained in:
@@ -163,7 +163,7 @@ describe('UrlInput', () => {
|
||||
await user.tab()
|
||||
|
||||
const emittedUrl = onUpdate.mock.calls[0]?.[0]
|
||||
expect(typeof emittedUrl).toBe('string')
|
||||
expect(emittedUrl).toBe('https://example.com/')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -33,7 +33,17 @@ const baseTask: MaintenanceTask = {
|
||||
execute: vi.fn().mockResolvedValue(true)
|
||||
}
|
||||
|
||||
function renderCard(state: 'OK' | 'error' | 'warning' | 'skipped') {
|
||||
const cardStubs = {
|
||||
Card: {
|
||||
template: '<div data-testid="card"><slot name="content"></slot></div>'
|
||||
},
|
||||
Button: { template: '<button />' }
|
||||
}
|
||||
|
||||
function renderCard(
|
||||
state: 'OK' | 'error' | 'warning' | 'skipped',
|
||||
task: MaintenanceTask = baseTask
|
||||
) {
|
||||
mockGetRunner.mockReturnValue({
|
||||
state,
|
||||
executing: false,
|
||||
@@ -42,18 +52,10 @@ function renderCard(state: 'OK' | 'error' | 'warning' | 'skipped') {
|
||||
})
|
||||
|
||||
return render(TaskCard, {
|
||||
props: { task: baseTask },
|
||||
props: { task },
|
||||
global: {
|
||||
plugins: [[PrimeVue, { unstyled: true }]],
|
||||
stubs: {
|
||||
Card: {
|
||||
template:
|
||||
'<div data-testid="card"><slot name="content" /></slot></div>'
|
||||
},
|
||||
Button: {
|
||||
template: '<button />'
|
||||
}
|
||||
}
|
||||
stubs: cardStubs
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -80,26 +82,7 @@ describe('TaskCard', () => {
|
||||
...baseTask,
|
||||
errorDescription: undefined
|
||||
}
|
||||
mockGetRunner.mockReturnValue({
|
||||
state: 'error',
|
||||
executing: false,
|
||||
refreshing: false
|
||||
})
|
||||
|
||||
render(TaskCard, {
|
||||
props: { task: taskWithoutErrorDesc },
|
||||
global: {
|
||||
plugins: [[PrimeVue, { unstyled: true }]],
|
||||
stubs: {
|
||||
Card: {
|
||||
template:
|
||||
'<div data-testid="card"><slot name="content" /></slot></div>'
|
||||
},
|
||||
Button: { template: '<button />' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
renderCard('error', taskWithoutErrorDesc)
|
||||
expect(screen.getByText('Short description')).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { render } from '@testing-library/vue'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { mockTerminal, MockTerminal, mockFitAddon, MockFitAddon } = vi.hoisted(
|
||||
() => {
|
||||
@@ -33,22 +32,9 @@ vi.mock('@xterm/xterm', () => ({ Terminal: MockTerminal }))
|
||||
vi.mock('@xterm/addon-fit', () => ({ FitAddon: MockFitAddon }))
|
||||
vi.mock('@xterm/xterm/css/xterm.css', () => ({}))
|
||||
|
||||
import { withSetup } from '@/test/withSetup'
|
||||
import { useTerminal } from '@/composables/bottomPanelTabs/useTerminal'
|
||||
|
||||
function withSetup<T>(composable: () => T): T {
|
||||
let result!: T
|
||||
render(
|
||||
defineComponent({
|
||||
setup() {
|
||||
result = composable()
|
||||
return {}
|
||||
},
|
||||
template: '<div />'
|
||||
})
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
function getKeyHandler(): (event: KeyboardEvent) => boolean {
|
||||
return mockTerminal.attachCustomKeyEventHandler.mock.calls[0][0]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { render } from '@testing-library/vue'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
const { mockSerialize, MockSerializeAddon } = vi.hoisted(() => {
|
||||
const mockSerialize = vi.fn<[], string>()
|
||||
@@ -21,22 +19,9 @@ vi.mock('@xterm/addon-serialize', () => ({
|
||||
}))
|
||||
|
||||
import type { Terminal } from '@xterm/xterm'
|
||||
import { withSetup } from '@/test/withSetup'
|
||||
import { useTerminalBuffer } from '@/composables/bottomPanelTabs/useTerminalBuffer'
|
||||
|
||||
function withSetup<T>(composable: () => T): T {
|
||||
let result!: T
|
||||
render(
|
||||
defineComponent({
|
||||
setup() {
|
||||
result = composable()
|
||||
return {}
|
||||
},
|
||||
template: '<div />'
|
||||
})
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
describe('useTerminalBuffer', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
@@ -48,7 +33,7 @@ describe('useTerminalBuffer', () => {
|
||||
mockSerialize.mockReturnValue('hello world')
|
||||
const { copyTo } = withSetup(() => useTerminalBuffer())
|
||||
const mockWrite = vi.fn()
|
||||
copyTo({ write: mockWrite } as unknown as Terminal)
|
||||
copyTo({ write: mockWrite } as Pick<Terminal, 'write'>)
|
||||
expect(mockWrite).toHaveBeenCalledWith('hello world')
|
||||
})
|
||||
|
||||
@@ -56,7 +41,7 @@ describe('useTerminalBuffer', () => {
|
||||
mockSerialize.mockReturnValue('')
|
||||
const { copyTo } = withSetup(() => useTerminalBuffer())
|
||||
const mockWrite = vi.fn()
|
||||
copyTo({ write: mockWrite } as unknown as Terminal)
|
||||
copyTo({ write: mockWrite } as Pick<Terminal, 'write'>)
|
||||
expect(mockWrite).toHaveBeenCalledWith('')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -25,15 +25,6 @@ describe('getDialog', () => {
|
||||
expect(result.id).toBe('invalidDialog')
|
||||
})
|
||||
|
||||
it('includes id, title, message, and buttons in the result', () => {
|
||||
const result = getDialog('reinstallVenv')
|
||||
expect(result).toHaveProperty('id')
|
||||
expect(result).toHaveProperty('title')
|
||||
expect(result).toHaveProperty('message')
|
||||
expect(result).toHaveProperty('buttons')
|
||||
expect(Array.isArray(result.buttons)).toBe(true)
|
||||
})
|
||||
|
||||
it('returns a deep clone — mutations do not affect the original', () => {
|
||||
const result = getDialog('reinstallVenv')
|
||||
const originalFirstLabel = DESKTOP_DIALOGS.reinstallVenv.buttons[0].label
|
||||
|
||||
@@ -48,19 +48,28 @@ describe('desktopMaintenanceTasks', () => {
|
||||
})
|
||||
|
||||
describe('URL-opening tasks', () => {
|
||||
it('git execute opens a browser tab', () => {
|
||||
it('git execute opens the git download page', () => {
|
||||
findTask('git').execute()
|
||||
expect(window.open).toHaveBeenCalledOnce()
|
||||
expect(window.open).toHaveBeenCalledWith(
|
||||
'https://git-scm.com/downloads/',
|
||||
'_blank'
|
||||
)
|
||||
})
|
||||
|
||||
it('uv execute opens a browser tab', () => {
|
||||
it('uv execute opens the uv installation page', () => {
|
||||
findTask('uv').execute()
|
||||
expect(window.open).toHaveBeenCalledOnce()
|
||||
expect(window.open).toHaveBeenCalledWith(
|
||||
'https://docs.astral.sh/uv/getting-started/installation/',
|
||||
'_blank'
|
||||
)
|
||||
})
|
||||
|
||||
it('vcRedist execute opens a browser tab', () => {
|
||||
it('vcRedist execute opens the VC++ redistributable download', () => {
|
||||
findTask('vcRedist').execute()
|
||||
expect(window.open).toHaveBeenCalledOnce()
|
||||
expect(window.open).toHaveBeenCalledWith(
|
||||
'https://aka.ms/vs/17/release/vc_redist.x64.exe',
|
||||
'_blank'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -68,32 +68,6 @@ describe('useMaintenanceTaskStore', () => {
|
||||
store = createStore()
|
||||
})
|
||||
|
||||
describe('initial state', () => {
|
||||
it('creates runners for all tasks', () => {
|
||||
expect(store.tasks.length).toBe(testTasks.length)
|
||||
})
|
||||
|
||||
it('starts with isRefreshing false', () => {
|
||||
expect(store.isRefreshing).toBe(false)
|
||||
})
|
||||
|
||||
it('starts with no errors', () => {
|
||||
expect(store.anyErrors).toBe(false)
|
||||
})
|
||||
|
||||
it('starts with unsafeBasePath false', () => {
|
||||
expect(store.unsafeBasePath).toBe(false)
|
||||
})
|
||||
|
||||
it('starts with no running terminal commands', () => {
|
||||
expect(store.isRunningTerminalCommand).toBe(false)
|
||||
})
|
||||
|
||||
it('starts with no running installation fixes', () => {
|
||||
expect(store.isRunningInstallationFix).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('processUpdate', () => {
|
||||
it('sets isRefreshing to true during in-progress update', () => {
|
||||
store.processUpdate(makeUpdate({ inProgress: true }))
|
||||
@@ -308,6 +282,7 @@ describe('useMaintenanceTaskStore', () => {
|
||||
|
||||
resolveTask(true)
|
||||
await executePromise
|
||||
expect(store.isRunningInstallationFix).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
16
apps/desktop-ui/src/test/withSetup.ts
Normal file
16
apps/desktop-ui/src/test/withSetup.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { render } from '@testing-library/vue'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export function withSetup<T>(composable: () => T): T {
|
||||
let result!: T
|
||||
render(
|
||||
defineComponent({
|
||||
setup() {
|
||||
result = composable()
|
||||
return {}
|
||||
},
|
||||
template: '<div />'
|
||||
})
|
||||
)
|
||||
return result
|
||||
}
|
||||
@@ -1,23 +1,9 @@
|
||||
import { render } from '@testing-library/vue'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { computed, defineComponent, nextTick, ref } from 'vue'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
|
||||
import { withSetup } from '@/test/withSetup'
|
||||
import { useMinLoadingDurationRef } from '@/utils/refUtil'
|
||||
|
||||
function withSetup<T>(composable: () => T): T {
|
||||
let result!: T
|
||||
render(
|
||||
defineComponent({
|
||||
setup() {
|
||||
result = composable()
|
||||
return {}
|
||||
},
|
||||
template: '<div />'
|
||||
})
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
describe('useMinLoadingDurationRef', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
|
||||
Reference in New Issue
Block a user