mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 11:11:53 +00:00
Feature Implemented: Warning displayed when frontend version mismatches
This commit is contained in:
80
src/components/dialog/content/VersionMismatchWarning.vue
Normal file
80
src/components/dialog/content/VersionMismatchWarning.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<Message
|
||||||
|
v-if="versionStore.shouldShowWarning"
|
||||||
|
severity="warn"
|
||||||
|
icon="pi pi-exclamation-triangle"
|
||||||
|
class="my-2 mx-2"
|
||||||
|
:closable="true"
|
||||||
|
:pt="{
|
||||||
|
root: { class: 'flex-col' },
|
||||||
|
text: { class: 'flex-1' }
|
||||||
|
}"
|
||||||
|
@close="handleDismiss"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col gap-3">
|
||||||
|
<!-- Warning Message -->
|
||||||
|
<div class="font-medium">
|
||||||
|
{{ $t('versionMismatchWarning.title') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Version Details -->
|
||||||
|
<div v-if="versionStore.warningMessage">
|
||||||
|
<div v-if="versionStore.warningMessage.type === 'outdated'">
|
||||||
|
{{
|
||||||
|
$t('versionMismatchWarning.frontendOutdated', {
|
||||||
|
frontendVersion: versionStore.warningMessage.frontendVersion,
|
||||||
|
requiredVersion: versionStore.warningMessage.requiredVersion
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="versionStore.warningMessage.type === 'newer'">
|
||||||
|
{{
|
||||||
|
$t('versionMismatchWarning.frontendNewer', {
|
||||||
|
frontendVersion: versionStore.warningMessage.frontendVersion,
|
||||||
|
backendVersion: versionStore.warningMessage.backendVersion
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Action Buttons -->
|
||||||
|
<div class="flex gap-2 justify-end">
|
||||||
|
<Button
|
||||||
|
v-if="versionStore.isFrontendOutdated"
|
||||||
|
:label="$t('versionMismatchWarning.updateFrontend')"
|
||||||
|
size="small"
|
||||||
|
severity="warn"
|
||||||
|
@click="handleUpdate"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
:label="$t('versionMismatchWarning.dismiss')"
|
||||||
|
size="small"
|
||||||
|
severity="secondary"
|
||||||
|
@click="handleDismiss"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Message>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Button from 'primevue/button'
|
||||||
|
import Message from 'primevue/message'
|
||||||
|
|
||||||
|
import { useVersionCompatibilityStore } from '@/stores/versionCompatibilityStore'
|
||||||
|
|
||||||
|
const versionStore = useVersionCompatibilityStore()
|
||||||
|
|
||||||
|
const handleDismiss = () => {
|
||||||
|
void versionStore.dismissWarning()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpdate = () => {
|
||||||
|
// Open ComfyUI documentation or update instructions
|
||||||
|
window.open('https://docs.comfy.org/get_started/introduction', '_blank')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Custom styles if needed */
|
||||||
|
</style>
|
||||||
@@ -873,5 +873,11 @@ export const CORE_SETTINGS: SettingParams[] = [
|
|||||||
name: 'Release seen timestamp',
|
name: 'Release seen timestamp',
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
defaultValue: 0
|
defaultValue: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'Comfy.VersionMismatch.DismissedVersion',
|
||||||
|
name: 'Dismissed version mismatch warning',
|
||||||
|
type: 'hidden',
|
||||||
|
defaultValue: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1233,6 +1233,13 @@
|
|||||||
"outdatedVersionGeneric": "Some nodes require a newer version of ComfyUI. Please update to use all nodes.",
|
"outdatedVersionGeneric": "Some nodes require a newer version of ComfyUI. Please update to use all nodes.",
|
||||||
"coreNodesFromVersion": "Requires ComfyUI {version}:"
|
"coreNodesFromVersion": "Requires ComfyUI {version}:"
|
||||||
},
|
},
|
||||||
|
"versionMismatchWarning": {
|
||||||
|
"title": "Version Compatibility Warning",
|
||||||
|
"frontendOutdated": "Frontend version {frontendVersion} is outdated. Backend requires version {requiredVersion} or higher.",
|
||||||
|
"frontendNewer": "Frontend version {frontendVersion} may not be compatible with backend version {backendVersion}.",
|
||||||
|
"updateFrontend": "Update Frontend",
|
||||||
|
"dismiss": "Dismiss"
|
||||||
|
},
|
||||||
"errorDialog": {
|
"errorDialog": {
|
||||||
"defaultTitle": "An error occurred",
|
"defaultTitle": "An error occurred",
|
||||||
"loadWorkflowTitle": "Loading aborted due to error reloading workflow data",
|
"loadWorkflowTitle": "Loading aborted due to error reloading workflow data",
|
||||||
|
|||||||
@@ -317,6 +317,7 @@ export const zSystemStats = z.object({
|
|||||||
embedded_python: z.boolean(),
|
embedded_python: z.boolean(),
|
||||||
comfyui_version: z.string(),
|
comfyui_version: z.string(),
|
||||||
pytorch_version: z.string(),
|
pytorch_version: z.string(),
|
||||||
|
required_frontend_version: z.string().optional(),
|
||||||
argv: z.array(z.string()),
|
argv: z.array(z.string()),
|
||||||
ram_total: z.number(),
|
ram_total: z.number(),
|
||||||
ram_free: z.number()
|
ram_free: z.number()
|
||||||
@@ -481,6 +482,8 @@ const zSettings = z.object({
|
|||||||
"what's new seen"
|
"what's new seen"
|
||||||
]),
|
]),
|
||||||
'Comfy.Release.Timestamp': z.number(),
|
'Comfy.Release.Timestamp': z.number(),
|
||||||
|
/** Version compatibility settings */
|
||||||
|
'Comfy.VersionMismatch.DismissedVersion': z.string(),
|
||||||
/** Settings used for testing */
|
/** Settings used for testing */
|
||||||
'test.setting': z.any(),
|
'test.setting': z.any(),
|
||||||
'main.sub.setting.name': z.any(),
|
'main.sub.setting.name': z.any(),
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ The following table lists ALL stores in the system as of 2025-01-30:
|
|||||||
| toastStore.ts | Manages toast notifications | UI |
|
| toastStore.ts | Manages toast notifications | UI |
|
||||||
| userFileStore.ts | Manages user file operations | Files |
|
| userFileStore.ts | Manages user file operations | Files |
|
||||||
| userStore.ts | Manages user data and preferences | User |
|
| userStore.ts | Manages user data and preferences | User |
|
||||||
|
| versionCompatibilityStore.ts | Manages frontend/backend version compatibility warnings | Core |
|
||||||
| widgetStore.ts | Manages widget configurations | Widgets |
|
| widgetStore.ts | Manages widget configurations | Widgets |
|
||||||
| workflowStore.ts | Handles workflow data and operations | Workflows |
|
| workflowStore.ts | Handles workflow data and operations | Workflows |
|
||||||
| workflowTemplatesStore.ts | Manages workflow templates | Workflows |
|
| workflowTemplatesStore.ts | Manages workflow templates | Workflows |
|
||||||
|
|||||||
125
src/stores/versionCompatibilityStore.ts
Normal file
125
src/stores/versionCompatibilityStore.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
import config from '@/config'
|
||||||
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
|
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||||
|
import { compareVersions } from '@/utils/formatUtil'
|
||||||
|
|
||||||
|
export const useVersionCompatibilityStore = defineStore(
|
||||||
|
'versionCompatibility',
|
||||||
|
() => {
|
||||||
|
const systemStatsStore = useSystemStatsStore()
|
||||||
|
const settingStore = useSettingStore()
|
||||||
|
|
||||||
|
const isDismissed = ref(false)
|
||||||
|
const dismissedVersion = ref<string | null>(null)
|
||||||
|
|
||||||
|
const frontendVersion = computed(() => config.app_version)
|
||||||
|
const backendVersion = computed(
|
||||||
|
() => systemStatsStore.systemStats?.system?.comfyui_version ?? ''
|
||||||
|
)
|
||||||
|
const requiredFrontendVersion = computed(
|
||||||
|
() =>
|
||||||
|
systemStatsStore.systemStats?.system?.required_frontend_version ?? ''
|
||||||
|
)
|
||||||
|
|
||||||
|
const isFrontendOutdated = computed(() => {
|
||||||
|
if (!frontendVersion.value || !requiredFrontendVersion.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
compareVersions(requiredFrontendVersion.value, frontendVersion.value) >
|
||||||
|
0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const isFrontendNewer = computed(() => {
|
||||||
|
if (!frontendVersion.value || !backendVersion.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const versionDiff = compareVersions(
|
||||||
|
frontendVersion.value,
|
||||||
|
backendVersion.value
|
||||||
|
)
|
||||||
|
return versionDiff > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasVersionMismatch = computed(() => {
|
||||||
|
return isFrontendOutdated.value || isFrontendNewer.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const shouldShowWarning = computed(() => {
|
||||||
|
if (!hasVersionMismatch.value || isDismissed.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentVersionKey = `${frontendVersion.value}-${backendVersion.value}-${requiredFrontendVersion.value}`
|
||||||
|
return dismissedVersion.value !== currentVersionKey
|
||||||
|
})
|
||||||
|
|
||||||
|
const warningMessage = computed(() => {
|
||||||
|
if (isFrontendOutdated.value) {
|
||||||
|
return {
|
||||||
|
type: 'outdated' as const,
|
||||||
|
frontendVersion: frontendVersion.value,
|
||||||
|
requiredVersion: requiredFrontendVersion.value
|
||||||
|
}
|
||||||
|
} else if (isFrontendNewer.value) {
|
||||||
|
return {
|
||||||
|
type: 'newer' as const,
|
||||||
|
frontendVersion: frontendVersion.value,
|
||||||
|
backendVersion: backendVersion.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
|
||||||
|
async function checkVersionCompatibility() {
|
||||||
|
if (!systemStatsStore.systemStats) {
|
||||||
|
await systemStatsStore.fetchSystemStats()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function dismissWarning() {
|
||||||
|
isDismissed.value = true
|
||||||
|
const currentVersionKey = `${frontendVersion.value}-${backendVersion.value}-${requiredFrontendVersion.value}`
|
||||||
|
dismissedVersion.value = currentVersionKey
|
||||||
|
|
||||||
|
await settingStore.set(
|
||||||
|
'Comfy.VersionMismatch.DismissedVersion',
|
||||||
|
currentVersionKey
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreDismissalState() {
|
||||||
|
const dismissed = settingStore.get(
|
||||||
|
'Comfy.VersionMismatch.DismissedVersion'
|
||||||
|
)
|
||||||
|
if (dismissed) {
|
||||||
|
dismissedVersion.value = dismissed
|
||||||
|
const currentVersionKey = `${frontendVersion.value}-${backendVersion.value}-${requiredFrontendVersion.value}`
|
||||||
|
isDismissed.value = dismissed === currentVersionKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function initialize() {
|
||||||
|
await checkVersionCompatibility()
|
||||||
|
restoreDismissalState()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
frontendVersion,
|
||||||
|
backendVersion,
|
||||||
|
requiredFrontendVersion,
|
||||||
|
hasVersionMismatch,
|
||||||
|
shouldShowWarning,
|
||||||
|
warningMessage,
|
||||||
|
isFrontendOutdated,
|
||||||
|
isFrontendNewer,
|
||||||
|
checkVersionCompatibility,
|
||||||
|
dismissWarning,
|
||||||
|
initialize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<div id="comfyui-body-left" class="comfyui-body-left" />
|
<div id="comfyui-body-left" class="comfyui-body-left" />
|
||||||
<div id="comfyui-body-right" class="comfyui-body-right" />
|
<div id="comfyui-body-right" class="comfyui-body-right" />
|
||||||
<div id="graph-canvas-container" class="graph-canvas-container">
|
<div id="graph-canvas-container" class="graph-canvas-container">
|
||||||
|
<VersionMismatchWarning />
|
||||||
<GraphCanvas @ready="onGraphReady" />
|
<GraphCanvas @ready="onGraphReady" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -28,6 +29,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
|
|
||||||
import MenuHamburger from '@/components/MenuHamburger.vue'
|
import MenuHamburger from '@/components/MenuHamburger.vue'
|
||||||
import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDialog.vue'
|
import UnloadWindowConfirmDialog from '@/components/dialog/UnloadWindowConfirmDialog.vue'
|
||||||
|
import VersionMismatchWarning from '@/components/dialog/content/VersionMismatchWarning.vue'
|
||||||
import GraphCanvas from '@/components/graph/GraphCanvas.vue'
|
import GraphCanvas from '@/components/graph/GraphCanvas.vue'
|
||||||
import GlobalToast from '@/components/toast/GlobalToast.vue'
|
import GlobalToast from '@/components/toast/GlobalToast.vue'
|
||||||
import RerouteMigrationToast from '@/components/toast/RerouteMigrationToast.vue'
|
import RerouteMigrationToast from '@/components/toast/RerouteMigrationToast.vue'
|
||||||
@@ -54,6 +56,7 @@ import {
|
|||||||
} from '@/stores/queueStore'
|
} from '@/stores/queueStore'
|
||||||
import { useServerConfigStore } from '@/stores/serverConfigStore'
|
import { useServerConfigStore } from '@/stores/serverConfigStore'
|
||||||
import { useSettingStore } from '@/stores/settingStore'
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
|
import { useVersionCompatibilityStore } from '@/stores/versionCompatibilityStore'
|
||||||
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||||
@@ -70,6 +73,7 @@ const settingStore = useSettingStore()
|
|||||||
const executionStore = useExecutionStore()
|
const executionStore = useExecutionStore()
|
||||||
const colorPaletteStore = useColorPaletteStore()
|
const colorPaletteStore = useColorPaletteStore()
|
||||||
const queueStore = useQueueStore()
|
const queueStore = useQueueStore()
|
||||||
|
const versionCompatibilityStore = useVersionCompatibilityStore()
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => colorPaletteStore.completedActivePalette,
|
() => colorPaletteStore.completedActivePalette,
|
||||||
@@ -206,6 +210,9 @@ onMounted(() => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to init ComfyUI frontend', e)
|
console.error('Failed to init ComfyUI frontend', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize version compatibility checking (fire-and-forget)
|
||||||
|
void versionCompatibilityStore.initialize()
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ describe('useSystemStatsStore', () => {
|
|||||||
embedded_python: false,
|
embedded_python: false,
|
||||||
comfyui_version: '1.0.0',
|
comfyui_version: '1.0.0',
|
||||||
pytorch_version: '2.0.0',
|
pytorch_version: '2.0.0',
|
||||||
|
required_frontend_version: '1.24.0',
|
||||||
argv: [],
|
argv: [],
|
||||||
ram_total: 16000000000,
|
ram_total: 16000000000,
|
||||||
ram_free: 8000000000
|
ram_free: 8000000000
|
||||||
@@ -92,6 +93,32 @@ describe('useSystemStatsStore', () => {
|
|||||||
|
|
||||||
expect(store.isLoading).toBe(false)
|
expect(store.isLoading).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should handle system stats updates', async () => {
|
||||||
|
const updatedStats = {
|
||||||
|
system: {
|
||||||
|
os: 'Windows',
|
||||||
|
python_version: '3.11.0',
|
||||||
|
embedded_python: false,
|
||||||
|
comfyui_version: '1.1.0',
|
||||||
|
pytorch_version: '2.1.0',
|
||||||
|
required_frontend_version: '1.25.0',
|
||||||
|
argv: [],
|
||||||
|
ram_total: 16000000000,
|
||||||
|
ram_free: 7000000000
|
||||||
|
},
|
||||||
|
devices: []
|
||||||
|
}
|
||||||
|
|
||||||
|
vi.mocked(api.getSystemStats).mockResolvedValue(updatedStats)
|
||||||
|
|
||||||
|
await store.fetchSystemStats()
|
||||||
|
|
||||||
|
expect(store.systemStats).toEqual(updatedStats)
|
||||||
|
expect(store.isLoading).toBe(false)
|
||||||
|
expect(store.error).toBeNull()
|
||||||
|
expect(api.getSystemStats).toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('getFormFactor', () => {
|
describe('getFormFactor', () => {
|
||||||
|
|||||||
267
tests-ui/tests/store/versionCompatibilityStore.test.ts
Normal file
267
tests-ui/tests/store/versionCompatibilityStore.test.ts
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
import { createPinia, setActivePinia } from 'pinia'
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
|
||||||
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
|
import { useSystemStatsStore } from '@/stores/systemStatsStore'
|
||||||
|
import { useVersionCompatibilityStore } from '@/stores/versionCompatibilityStore'
|
||||||
|
|
||||||
|
vi.mock('@/config', () => ({
|
||||||
|
default: {
|
||||||
|
app_version: '1.24.0'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/stores/systemStatsStore')
|
||||||
|
vi.mock('@/stores/settingStore')
|
||||||
|
|
||||||
|
describe('useVersionCompatibilityStore', () => {
|
||||||
|
let store: ReturnType<typeof useVersionCompatibilityStore>
|
||||||
|
let mockSystemStatsStore: any
|
||||||
|
let mockSettingStore: any
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setActivePinia(createPinia())
|
||||||
|
|
||||||
|
mockSystemStatsStore = {
|
||||||
|
systemStats: null,
|
||||||
|
fetchSystemStats: vi.fn()
|
||||||
|
}
|
||||||
|
|
||||||
|
mockSettingStore = {
|
||||||
|
get: vi.fn(),
|
||||||
|
set: vi.fn()
|
||||||
|
}
|
||||||
|
|
||||||
|
vi.mocked(useSystemStatsStore).mockReturnValue(mockSystemStatsStore)
|
||||||
|
vi.mocked(useSettingStore).mockReturnValue(mockSettingStore)
|
||||||
|
|
||||||
|
store = useVersionCompatibilityStore()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('version compatibility detection', () => {
|
||||||
|
it('should detect frontend is outdated when required version is higher', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.isFrontendOutdated).toBe(true)
|
||||||
|
expect(store.isFrontendNewer).toBe(false)
|
||||||
|
expect(store.hasVersionMismatch).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should detect frontend is newer when frontend version is higher than backend', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.23.0',
|
||||||
|
required_frontend_version: '1.23.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.isFrontendOutdated).toBe(false)
|
||||||
|
expect(store.isFrontendNewer).toBe(true)
|
||||||
|
expect(store.hasVersionMismatch).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not detect mismatch when versions are compatible', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.24.0',
|
||||||
|
required_frontend_version: '1.24.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.isFrontendOutdated).toBe(false)
|
||||||
|
expect(store.isFrontendNewer).toBe(false)
|
||||||
|
expect(store.hasVersionMismatch).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle missing version information gracefully', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '',
|
||||||
|
required_frontend_version: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.isFrontendOutdated).toBe(false)
|
||||||
|
expect(store.isFrontendNewer).toBe(false)
|
||||||
|
expect(store.hasVersionMismatch).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('warning display logic', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
mockSettingStore.get.mockReturnValue('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should show warning when there is a version mismatch and not dismissed', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.shouldShowWarning).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not show warning when dismissed', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
void store.dismissWarning()
|
||||||
|
|
||||||
|
expect(store.shouldShowWarning).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not show warning when no version mismatch', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.24.0',
|
||||||
|
required_frontend_version: '1.24.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.shouldShowWarning).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('warning messages', () => {
|
||||||
|
it('should generate outdated message when frontend is outdated', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.warningMessage).toEqual({
|
||||||
|
type: 'outdated',
|
||||||
|
frontendVersion: '1.24.0',
|
||||||
|
requiredVersion: '1.25.0'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should generate newer message when frontend is newer', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.23.0',
|
||||||
|
required_frontend_version: '1.23.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.warningMessage).toEqual({
|
||||||
|
type: 'newer',
|
||||||
|
frontendVersion: '1.24.0',
|
||||||
|
backendVersion: '1.23.0'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return null when no mismatch', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.24.0',
|
||||||
|
required_frontend_version: '1.24.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
|
||||||
|
expect(store.warningMessage).toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('dismissal persistence', () => {
|
||||||
|
it('should save dismissal to settings', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.checkVersionCompatibility()
|
||||||
|
await store.dismissWarning()
|
||||||
|
|
||||||
|
expect(mockSettingStore.set).toHaveBeenCalledWith(
|
||||||
|
'Comfy.VersionMismatch.DismissedVersion',
|
||||||
|
'1.24.0-1.25.0-1.25.0'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should restore dismissal state from settings', async () => {
|
||||||
|
mockSettingStore.get.mockReturnValue('1.24.0-1.25.0-1.25.0')
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.25.0',
|
||||||
|
required_frontend_version: '1.25.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.initialize()
|
||||||
|
|
||||||
|
expect(store.shouldShowWarning).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should show warning for different version combinations even if previous was dismissed', async () => {
|
||||||
|
mockSettingStore.get.mockReturnValue('1.24.0-1.25.0-1.25.0')
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.26.0',
|
||||||
|
required_frontend_version: '1.26.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.initialize()
|
||||||
|
|
||||||
|
expect(store.shouldShowWarning).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('initialization', () => {
|
||||||
|
it('should fetch system stats if not available', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = null
|
||||||
|
|
||||||
|
await store.initialize()
|
||||||
|
|
||||||
|
expect(mockSystemStatsStore.fetchSystemStats).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not fetch system stats if already available', async () => {
|
||||||
|
mockSystemStatsStore.systemStats = {
|
||||||
|
system: {
|
||||||
|
comfyui_version: '1.24.0',
|
||||||
|
required_frontend_version: '1.24.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await store.initialize()
|
||||||
|
|
||||||
|
expect(mockSystemStatsStore.fetchSystemStats).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user