mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-25 07:05:26 +00:00
## Summary
Replace `vi.mock('vue-i18n')` stub with a real `createI18n` plugin
instance in `useReconnectingNotification` tests.
## Changes
- **What**: Add `setupComposable()` helper that renders a wrapper
component via `@testing-library/vue` with a real `createI18n` plugin.
Assertions now check translated values
(`'Reconnecting'`/`'Reconnected'`) instead of raw i18n keys. Removes the
brittle `vi.mock('vue-i18n')` stub.
## Review Focus
Straightforward test-only change — the composable requires a component
setup context for `useI18n()`, so we render a thin wrapper via
`@testing-library/vue` with the i18n plugin installed.
Fixes #11153
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11386-test-use-real-vue-i18n-plugin-in-useReconnectingNotification-tests-3476d73d3650814ba70eea6df91c8bbe)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Alexander Brown <drjkl@comfy.org>
160 lines
4.0 KiB
TypeScript
160 lines
4.0 KiB
TypeScript
import { createTestingPinia } from '@pinia/testing'
|
|
import { render } from '@testing-library/vue'
|
|
import { setActivePinia } from 'pinia'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { defineComponent } from 'vue'
|
|
import { createI18n } from 'vue-i18n'
|
|
|
|
import { useReconnectingNotification } from '@/composables/useReconnectingNotification'
|
|
|
|
const mockToastAdd = vi.fn()
|
|
const mockToastRemove = vi.fn()
|
|
|
|
vi.mock('primevue/usetoast', () => ({
|
|
useToast: () => ({
|
|
add: mockToastAdd,
|
|
remove: mockToastRemove
|
|
})
|
|
}))
|
|
|
|
function setupComposable(): ReturnType<typeof useReconnectingNotification> {
|
|
const i18n = createI18n({
|
|
legacy: false,
|
|
locale: 'en',
|
|
messages: {
|
|
en: {
|
|
g: {
|
|
reconnecting: 'Reconnecting',
|
|
reconnected: 'Reconnected'
|
|
}
|
|
}
|
|
}
|
|
})
|
|
let result!: ReturnType<typeof useReconnectingNotification>
|
|
const Wrapper = defineComponent({
|
|
setup() {
|
|
result = useReconnectingNotification()
|
|
return () => null
|
|
}
|
|
})
|
|
render(Wrapper, { global: { plugins: [i18n] } })
|
|
return result
|
|
}
|
|
|
|
const settingMocks = vi.hoisted(() => ({
|
|
disableToast: false
|
|
}))
|
|
|
|
vi.mock('@/platform/settings/settingStore', () => ({
|
|
useSettingStore: vi.fn(() => ({
|
|
get: vi.fn((key: string) => {
|
|
if (key === 'Comfy.Toast.DisableReconnectingToast')
|
|
return settingMocks.disableToast
|
|
return undefined
|
|
})
|
|
}))
|
|
}))
|
|
|
|
describe('useReconnectingNotification', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createTestingPinia({ stubActions: false }))
|
|
vi.useFakeTimers()
|
|
vi.clearAllMocks()
|
|
settingMocks.disableToast = false
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
})
|
|
|
|
it('does not show toast immediately on reconnecting', () => {
|
|
const { onReconnecting } = setupComposable()
|
|
|
|
onReconnecting()
|
|
|
|
expect(mockToastAdd).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('shows error toast after delay', () => {
|
|
const { onReconnecting } = setupComposable()
|
|
|
|
onReconnecting()
|
|
vi.advanceTimersByTime(1500)
|
|
|
|
expect(mockToastAdd).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
severity: 'error',
|
|
summary: 'Reconnecting'
|
|
})
|
|
)
|
|
})
|
|
|
|
it('suppresses toast when reconnected before delay expires', () => {
|
|
const { onReconnecting, onReconnected } = setupComposable()
|
|
|
|
onReconnecting()
|
|
vi.advanceTimersByTime(500)
|
|
onReconnected()
|
|
vi.advanceTimersByTime(1500)
|
|
|
|
expect(mockToastAdd).not.toHaveBeenCalled()
|
|
expect(mockToastRemove).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('removes toast and shows success when reconnected after delay', () => {
|
|
const { onReconnecting, onReconnected } = setupComposable()
|
|
|
|
onReconnecting()
|
|
vi.advanceTimersByTime(1500)
|
|
mockToastAdd.mockClear()
|
|
|
|
onReconnected()
|
|
|
|
expect(mockToastRemove).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
severity: 'error',
|
|
summary: 'Reconnecting'
|
|
})
|
|
)
|
|
expect(mockToastAdd).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
severity: 'success',
|
|
summary: 'Reconnected',
|
|
life: 2000
|
|
})
|
|
)
|
|
})
|
|
|
|
it('does nothing when toast is disabled via setting', () => {
|
|
settingMocks.disableToast = true
|
|
const { onReconnecting, onReconnected } = setupComposable()
|
|
|
|
onReconnecting()
|
|
vi.advanceTimersByTime(1500)
|
|
onReconnected()
|
|
|
|
expect(mockToastAdd).not.toHaveBeenCalled()
|
|
expect(mockToastRemove).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('does nothing when onReconnected is called without prior onReconnecting', () => {
|
|
const { onReconnected } = setupComposable()
|
|
|
|
onReconnected()
|
|
|
|
expect(mockToastAdd).not.toHaveBeenCalled()
|
|
expect(mockToastRemove).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('handles multiple reconnecting events without duplicating toasts', () => {
|
|
const { onReconnecting } = setupComposable()
|
|
|
|
onReconnecting()
|
|
vi.advanceTimersByTime(1500) // first toast fires
|
|
onReconnecting() // second reconnecting event
|
|
vi.advanceTimersByTime(1500) // second toast fires
|
|
|
|
expect(mockToastAdd).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|