mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-11 16:10:05 +00:00
Road to no explicit any part 8 group 5 (#8329)
## Summary - Add `createMockLLink` and `createMockLinks` factory functions to handle hybrid Map/Record types - Replace `as any` assertions with type-safe factory functions in minimap tests - Implement proper Pinia store mocking using `vi.hoisted()` pattern - Remove unused `createMockSubgraph` export (shadowed by local implementations) ## Test plan - [x] All minimap tests pass (29 tests) - [x] `pnpm typecheck` passes - [x] `pnpm lint` passes - [x] `pnpm knip` passes ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8329-Road-to-no-explicit-any-part-8-group-5-2f56d73d365081218882de81d5526220) by [Unito](https://www.unito.io) --------- Co-authored-by: AustinMroz <austin@comfy.org>
This commit is contained in:
committed by
GitHub
parent
440e25e232
commit
3946d7b5ff
@@ -190,7 +190,7 @@ describe('useReleaseService', () => {
|
||||
})
|
||||
|
||||
it('should set loading state correctly', async () => {
|
||||
let resolvePromise: (value: any) => void
|
||||
let resolvePromise: (value: unknown) => void
|
||||
const promise = new Promise((resolve) => {
|
||||
resolvePromise = resolve
|
||||
})
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { compare, valid } from 'semver'
|
||||
import type { Mock } from 'vitest'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import type { ReleaseNote } from '@/platform/updates/common/releaseService'
|
||||
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
|
||||
|
||||
// Mock the dependencies
|
||||
@@ -19,9 +22,25 @@ vi.mock('@vueuse/core', () => ({
|
||||
|
||||
describe('useReleaseStore', () => {
|
||||
let store: ReturnType<typeof useReleaseStore>
|
||||
let mockReleaseService: any
|
||||
let mockSettingStore: any
|
||||
let mockSystemStatsStore: any
|
||||
let mockReleaseService: {
|
||||
getReleases: Mock
|
||||
isLoading: ReturnType<typeof ref<boolean>>
|
||||
error: ReturnType<typeof ref<string | null>>
|
||||
}
|
||||
let mockSettingStore: { get: Mock; set: Mock }
|
||||
let mockSystemStatsStore: {
|
||||
systemStats: {
|
||||
system: {
|
||||
comfyui_version: string
|
||||
argv?: string[]
|
||||
[key: string]: unknown
|
||||
}
|
||||
devices?: unknown[]
|
||||
} | null
|
||||
isInitialized: boolean
|
||||
refetchSystemStats: Mock
|
||||
getFormFactor: Mock
|
||||
}
|
||||
|
||||
const mockRelease = {
|
||||
id: 1,
|
||||
@@ -38,11 +57,11 @@ describe('useReleaseStore', () => {
|
||||
// Reset all mocks
|
||||
vi.clearAllMocks()
|
||||
|
||||
// Setup mock services
|
||||
// Setup mock services with proper refs
|
||||
mockReleaseService = {
|
||||
getReleases: vi.fn(),
|
||||
isLoading: { value: false },
|
||||
error: { value: null }
|
||||
isLoading: ref(false),
|
||||
error: ref(null)
|
||||
}
|
||||
|
||||
mockSettingStore = {
|
||||
@@ -68,9 +87,21 @@ describe('useReleaseStore', () => {
|
||||
const { useSystemStatsStore } = await import('@/stores/systemStatsStore')
|
||||
const { isElectron } = await import('@/utils/envUtil')
|
||||
|
||||
vi.mocked(useReleaseService).mockReturnValue(mockReleaseService)
|
||||
vi.mocked(useSettingStore).mockReturnValue(mockSettingStore)
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue(mockSystemStatsStore)
|
||||
vi.mocked(useReleaseService).mockReturnValue(
|
||||
mockReleaseService as Partial<
|
||||
ReturnType<typeof useReleaseService>
|
||||
> as ReturnType<typeof useReleaseService>
|
||||
)
|
||||
vi.mocked(useSettingStore).mockReturnValue(
|
||||
mockSettingStore as Partial<
|
||||
ReturnType<typeof useSettingStore>
|
||||
> as ReturnType<typeof useSettingStore>
|
||||
)
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue(
|
||||
mockSystemStatsStore as Partial<
|
||||
ReturnType<typeof useSystemStatsStore>
|
||||
> as ReturnType<typeof useSystemStatsStore>
|
||||
)
|
||||
vi.mocked(isElectron).mockReturnValue(true)
|
||||
vi.mocked(valid).mockReturnValue('1.0.0')
|
||||
|
||||
@@ -171,7 +202,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should show popup for latest version', () => {
|
||||
mockSystemStatsStore.systemStats.system.comfyui_version = '1.2.0'
|
||||
mockSystemStatsStore.systemStats!.system.comfyui_version = '1.2.0'
|
||||
|
||||
vi.mocked(compare).mockReturnValue(0)
|
||||
|
||||
@@ -213,7 +244,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should not show popup even for latest version', () => {
|
||||
mockSystemStatsStore.systemStats.system.comfyui_version = '1.2.0'
|
||||
mockSystemStatsStore.systemStats!.system.comfyui_version = '1.2.0'
|
||||
|
||||
vi.mocked(compare).mockReturnValue(0)
|
||||
|
||||
@@ -265,7 +296,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should skip fetching when --disable-api-nodes is present', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = ['--disable-api-nodes']
|
||||
mockSystemStatsStore.systemStats!.system.argv = ['--disable-api-nodes']
|
||||
|
||||
await store.initialize()
|
||||
|
||||
@@ -274,7 +305,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should skip fetching when --disable-api-nodes is one of multiple args', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = [
|
||||
mockSystemStatsStore.systemStats!.system.argv = [
|
||||
'--port',
|
||||
'8080',
|
||||
'--disable-api-nodes',
|
||||
@@ -288,7 +319,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should fetch normally when --disable-api-nodes is not present', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = [
|
||||
mockSystemStatsStore.systemStats!.system.argv = [
|
||||
'--port',
|
||||
'8080',
|
||||
'--verbose'
|
||||
@@ -302,7 +333,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should fetch normally when argv is undefined', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = undefined
|
||||
mockSystemStatsStore.systemStats!.system.argv = undefined
|
||||
mockReleaseService.getReleases.mockResolvedValue([mockRelease])
|
||||
|
||||
await store.initialize()
|
||||
@@ -330,8 +361,8 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should set loading state correctly', async () => {
|
||||
let resolvePromise: (value: any) => void
|
||||
const promise = new Promise((resolve) => {
|
||||
let resolvePromise: (value: ReleaseNote[] | null) => void
|
||||
const promise = new Promise<ReleaseNote[] | null>((resolve) => {
|
||||
resolvePromise = resolve
|
||||
})
|
||||
|
||||
@@ -372,7 +403,7 @@ describe('useReleaseStore', () => {
|
||||
|
||||
describe('--disable-api-nodes argument handling', () => {
|
||||
it('should skip fetchReleases when --disable-api-nodes is present', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = ['--disable-api-nodes']
|
||||
mockSystemStatsStore.systemStats!.system.argv = ['--disable-api-nodes']
|
||||
|
||||
await store.fetchReleases()
|
||||
|
||||
@@ -381,7 +412,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should skip fetchReleases when --disable-api-nodes is among other args', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = [
|
||||
mockSystemStatsStore.systemStats!.system.argv = [
|
||||
'--port',
|
||||
'8080',
|
||||
'--disable-api-nodes',
|
||||
@@ -395,7 +426,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should proceed with fetchReleases when --disable-api-nodes is not present', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = [
|
||||
mockSystemStatsStore.systemStats!.system.argv = [
|
||||
'--port',
|
||||
'8080',
|
||||
'--verbose'
|
||||
@@ -407,8 +438,8 @@ describe('useReleaseStore', () => {
|
||||
expect(mockReleaseService.getReleases).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should proceed with fetchReleases when argv is null', async () => {
|
||||
mockSystemStatsStore.systemStats.system.argv = null
|
||||
it('should proceed with fetchReleases when argv is undefined', async () => {
|
||||
mockSystemStatsStore.systemStats!.system.argv = undefined
|
||||
mockReleaseService.getReleases.mockResolvedValue([mockRelease])
|
||||
|
||||
await store.fetchReleases()
|
||||
@@ -515,7 +546,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should show popup for latest version', () => {
|
||||
mockSystemStatsStore.systemStats.system.comfyui_version = '1.2.0' // Same as release
|
||||
mockSystemStatsStore.systemStats!.system.comfyui_version = '1.2.0' // Same as release
|
||||
mockSettingStore.get.mockImplementation((key: string) => {
|
||||
if (key === 'Comfy.Notification.ShowVersionUpdates') return true
|
||||
return null
|
||||
@@ -592,7 +623,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should show popup for latest version', () => {
|
||||
mockSystemStatsStore.systemStats.system.comfyui_version = '1.2.0'
|
||||
mockSystemStatsStore.systemStats!.system.comfyui_version = '1.2.0'
|
||||
|
||||
vi.mocked(compare).mockReturnValue(0)
|
||||
|
||||
@@ -649,7 +680,7 @@ describe('useReleaseStore', () => {
|
||||
})
|
||||
|
||||
it('should NOT show popup even for latest version', () => {
|
||||
mockSystemStatsStore.systemStats.system.comfyui_version = '1.2.0'
|
||||
mockSystemStatsStore.systemStats!.system.comfyui_version = '1.2.0'
|
||||
|
||||
vi.mocked(compare).mockReturnValue(0)
|
||||
|
||||
|
||||
@@ -40,17 +40,20 @@ vi.mock('@/scripts/api', () => ({
|
||||
// Mock vue-i18n
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: (key: string, params?: any) => {
|
||||
t: (key: string, params?: Record<string, string | number> | unknown) => {
|
||||
if (key === 'g.versionMismatchWarning')
|
||||
return 'Version Compatibility Warning'
|
||||
if (key === 'g.versionMismatchWarningMessage' && params) {
|
||||
return `${params.warning}: ${params.detail} Visit https://docs.comfy.org/installation/update_comfyui#common-update-issues for update instructions.`
|
||||
const p = params as Record<string, string>
|
||||
return `${p.warning}: ${p.detail} Visit https://docs.comfy.org/installation/update_comfyui#common-update-issues for update instructions.`
|
||||
}
|
||||
if (key === 'g.frontendOutdated' && params) {
|
||||
return `Frontend version ${params.frontendVersion} is outdated. Backend requires ${params.requiredVersion} or higher.`
|
||||
const p = params as Record<string, string>
|
||||
return `Frontend version ${p.frontendVersion} is outdated. Backend requires ${p.requiredVersion} or higher.`
|
||||
}
|
||||
if (key === 'g.frontendNewer' && params) {
|
||||
return `Frontend version ${params.frontendVersion} may not be compatible with backend version ${params.backendVersion}.`
|
||||
const p = params as Record<string, string>
|
||||
return `Frontend version ${p.frontendVersion} may not be compatible with backend version ${p.backendVersion}.`
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { useVersionCompatibilityStore } from '@/platform/updates/common/versionCompatibilityStore'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||
|
||||
vi.mock('@/config', () => ({
|
||||
default: {
|
||||
@@ -12,13 +10,14 @@ vi.mock('@/config', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/systemStatsStore')
|
||||
const mockUseSystemStatsStore = vi.hoisted(() => vi.fn())
|
||||
vi.mock('@/stores/systemStatsStore', () => ({
|
||||
useSystemStatsStore: mockUseSystemStatsStore
|
||||
}))
|
||||
|
||||
// Mock settingStore
|
||||
const mockUseSettingStore = vi.hoisted(() => vi.fn())
|
||||
vi.mock('@/platform/settings/settingStore', () => ({
|
||||
useSettingStore: vi.fn(() => ({
|
||||
get: vi.fn(() => false) // Default to warnings enabled (false = not disabled)
|
||||
}))
|
||||
useSettingStore: mockUseSettingStore
|
||||
}))
|
||||
|
||||
// Mock useStorage and until from VueUse
|
||||
@@ -28,10 +27,16 @@ vi.mock('@vueuse/core', () => ({
|
||||
until: vi.fn(() => Promise.resolve())
|
||||
}))
|
||||
|
||||
type MockSystemStatsStore = {
|
||||
systemStats: unknown
|
||||
isInitialized: boolean
|
||||
refetchSystemStats: ReturnType<typeof vi.fn>
|
||||
}
|
||||
|
||||
describe('useVersionCompatibilityStore', () => {
|
||||
let store: ReturnType<typeof useVersionCompatibilityStore>
|
||||
let mockSystemStatsStore: any
|
||||
let mockSettingStore: any
|
||||
let mockSystemStatsStore: MockSystemStatsStore
|
||||
let mockSettingStore: { get: ReturnType<typeof vi.fn> }
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
@@ -49,8 +54,8 @@ describe('useVersionCompatibilityStore', () => {
|
||||
get: vi.fn(() => false) // Default to warnings enabled
|
||||
}
|
||||
|
||||
vi.mocked(useSystemStatsStore).mockReturnValue(mockSystemStatsStore)
|
||||
vi.mocked(useSettingStore).mockReturnValue(mockSettingStore)
|
||||
mockUseSystemStatsStore.mockReturnValue(mockSystemStatsStore)
|
||||
mockUseSettingStore.mockReturnValue(mockSettingStore)
|
||||
|
||||
store = useVersionCompatibilityStore()
|
||||
})
|
||||
@@ -213,7 +218,9 @@ describe('useVersionCompatibilityStore', () => {
|
||||
|
||||
it('should not show warning when disabled via setting', async () => {
|
||||
// Enable the disable setting
|
||||
mockSettingStore.get.mockReturnValue(true)
|
||||
;(
|
||||
mockSettingStore as { get: ReturnType<typeof vi.fn> }
|
||||
).get.mockReturnValue(true)
|
||||
|
||||
// Set up version mismatch that would normally show warning
|
||||
mockSystemStatsStore.systemStats = {
|
||||
@@ -227,9 +234,9 @@ describe('useVersionCompatibilityStore', () => {
|
||||
await store.checkVersionCompatibility()
|
||||
|
||||
expect(store.shouldShowWarning).toBe(false)
|
||||
expect(mockSettingStore.get).toHaveBeenCalledWith(
|
||||
'Comfy.VersionCompatibility.DisableWarnings'
|
||||
)
|
||||
expect(
|
||||
(mockSettingStore as { get: ReturnType<typeof vi.fn> }).get
|
||||
).toHaveBeenCalledWith('Comfy.VersionCompatibility.DisableWarnings')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { ReleaseNote } from '../common/releaseService'
|
||||
import ReleaseNotificationToast from './ReleaseNotificationToast.vue'
|
||||
|
||||
interface TestWindow extends Window {
|
||||
electronAPI?: Record<string, unknown>
|
||||
}
|
||||
|
||||
const { commandExecuteMock } = vi.hoisted(() => ({
|
||||
commandExecuteMock: vi.fn()
|
||||
}))
|
||||
@@ -192,7 +196,7 @@ describe('ReleaseNotificationToast', () => {
|
||||
value: mockWindowOpen,
|
||||
writable: true
|
||||
})
|
||||
;(window as any).electronAPI = {}
|
||||
;(window as TestWindow).electronAPI = {}
|
||||
|
||||
wrapper = mountComponent()
|
||||
await wrapper.vm.handleUpdate()
|
||||
@@ -203,7 +207,7 @@ describe('ReleaseNotificationToast', () => {
|
||||
expect(mockWindowOpen).not.toHaveBeenCalled()
|
||||
expect(toastErrorHandlerMock).not.toHaveBeenCalled()
|
||||
|
||||
delete (window as any).electronAPI
|
||||
delete (window as TestWindow).electronAPI
|
||||
})
|
||||
|
||||
it('shows an error toast if the desktop updater flow fails in Electron', async () => {
|
||||
@@ -220,7 +224,7 @@ describe('ReleaseNotificationToast', () => {
|
||||
value: mockWindowOpen,
|
||||
writable: true
|
||||
})
|
||||
;(window as any).electronAPI = {}
|
||||
;(window as TestWindow).electronAPI = {}
|
||||
|
||||
wrapper = mountComponent()
|
||||
await wrapper.vm.handleUpdate()
|
||||
@@ -228,7 +232,7 @@ describe('ReleaseNotificationToast', () => {
|
||||
expect(toastErrorHandlerMock).toHaveBeenCalledWith(error)
|
||||
expect(mockWindowOpen).not.toHaveBeenCalled()
|
||||
|
||||
delete (window as any).electronAPI
|
||||
delete (window as TestWindow).electronAPI
|
||||
})
|
||||
|
||||
it('calls handleShowChangelog when learn more link is clicked', async () => {
|
||||
|
||||
@@ -165,7 +165,9 @@ describe('WhatsNewPopup', () => {
|
||||
wrapper = mountComponent()
|
||||
|
||||
// Call the close method directly instead of triggering DOM event
|
||||
await (wrapper.vm as any).closePopup()
|
||||
await (
|
||||
wrapper.vm as typeof wrapper.vm & { closePopup: () => Promise<void> }
|
||||
).closePopup()
|
||||
|
||||
expect(wrapper.emitted('whats-new-dismissed')).toBeTruthy()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user