mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-25 08:49:36 +00:00
[Feature] Add "All" category to template workflows (#3931)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
301
tests-ui/tests/composables/useTemplateWorkflows.test.ts
Normal file
301
tests-ui/tests/composables/useTemplateWorkflows.test.ts
Normal file
@@ -0,0 +1,301 @@
|
||||
import { flushPromises } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { useTemplateWorkflows } from '@/composables/useTemplateWorkflows'
|
||||
import { useWorkflowTemplatesStore } from '@/stores/workflowTemplatesStore'
|
||||
|
||||
// Mock the store
|
||||
vi.mock('@/stores/workflowTemplatesStore', () => ({
|
||||
useWorkflowTemplatesStore: vi.fn()
|
||||
}))
|
||||
|
||||
// Mock the API
|
||||
vi.mock('@/scripts/api', () => ({
|
||||
api: {
|
||||
fileURL: vi.fn((path) => `mock-file-url${path}`),
|
||||
apiURL: vi.fn((path) => `mock-api-url${path}`)
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock the app
|
||||
vi.mock('@/scripts/app', () => ({
|
||||
app: {
|
||||
loadGraphData: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock Vue I18n
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({
|
||||
t: vi.fn((key, fallback) => fallback || key)
|
||||
})
|
||||
}))
|
||||
|
||||
// Mock the dialog store
|
||||
vi.mock('@/stores/dialogStore', () => ({
|
||||
useDialogStore: vi.fn(() => ({
|
||||
closeDialog: vi.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
// Mock fetch
|
||||
global.fetch = vi.fn()
|
||||
|
||||
describe('useTemplateWorkflows', () => {
|
||||
let mockWorkflowTemplatesStore: any
|
||||
|
||||
beforeEach(() => {
|
||||
mockWorkflowTemplatesStore = {
|
||||
isLoaded: false,
|
||||
loadWorkflowTemplates: vi.fn().mockResolvedValue(true),
|
||||
groupedTemplates: [
|
||||
{
|
||||
label: 'ComfyUI Examples',
|
||||
modules: [
|
||||
{
|
||||
moduleName: 'all',
|
||||
title: 'All',
|
||||
localizedTitle: 'All Templates',
|
||||
templates: [
|
||||
{
|
||||
name: 'template1',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
sourceModule: 'default',
|
||||
localizedTitle: 'Template 1'
|
||||
},
|
||||
{
|
||||
name: 'template2',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
sourceModule: 'custom-module',
|
||||
description: 'A custom template'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
moduleName: 'default',
|
||||
title: 'Default',
|
||||
localizedTitle: 'Default Templates',
|
||||
templates: [
|
||||
{
|
||||
name: 'template1',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
localizedTitle: 'Template 1',
|
||||
localizedDescription: 'A default template'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
vi.mocked(useWorkflowTemplatesStore).mockReturnValue(
|
||||
mockWorkflowTemplatesStore
|
||||
)
|
||||
|
||||
// Mock fetch response
|
||||
vi.mocked(fetch).mockResolvedValue({
|
||||
json: vi.fn().mockResolvedValue({ workflow: 'data' })
|
||||
} as unknown as Response)
|
||||
})
|
||||
|
||||
it('should load templates from store', async () => {
|
||||
const { loadTemplates, isTemplatesLoaded } = useTemplateWorkflows()
|
||||
|
||||
expect(isTemplatesLoaded.value).toBe(false)
|
||||
|
||||
await loadTemplates()
|
||||
|
||||
expect(mockWorkflowTemplatesStore.loadWorkflowTemplates).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should select the first template category', () => {
|
||||
const { selectFirstTemplateCategory, selectedTemplate } =
|
||||
useTemplateWorkflows()
|
||||
|
||||
selectFirstTemplateCategory()
|
||||
|
||||
expect(selectedTemplate.value).toEqual(
|
||||
mockWorkflowTemplatesStore.groupedTemplates[0].modules[0]
|
||||
)
|
||||
})
|
||||
|
||||
it('should select a template category', () => {
|
||||
const { selectTemplateCategory, selectedTemplate } = useTemplateWorkflows()
|
||||
const category = mockWorkflowTemplatesStore.groupedTemplates[0].modules[1] // Default category
|
||||
|
||||
const result = selectTemplateCategory(category)
|
||||
|
||||
expect(result).toBe(true)
|
||||
expect(selectedTemplate.value).toEqual(category)
|
||||
})
|
||||
|
||||
it('should format template thumbnails correctly for default templates', () => {
|
||||
const { getTemplateThumbnailUrl } = useTemplateWorkflows()
|
||||
const template = {
|
||||
name: 'test-template',
|
||||
mediaSubtype: 'jpg',
|
||||
mediaType: 'image',
|
||||
description: 'Test template'
|
||||
}
|
||||
|
||||
const url = getTemplateThumbnailUrl(template, 'default', '1')
|
||||
|
||||
expect(url).toBe('mock-file-url/templates/test-template-1.jpg')
|
||||
})
|
||||
|
||||
it('should format template thumbnails correctly for custom templates', () => {
|
||||
const { getTemplateThumbnailUrl } = useTemplateWorkflows()
|
||||
const template = {
|
||||
name: 'test-template',
|
||||
mediaSubtype: 'jpg',
|
||||
mediaType: 'image',
|
||||
description: 'Test template'
|
||||
}
|
||||
|
||||
const url = getTemplateThumbnailUrl(template, 'custom-module')
|
||||
|
||||
expect(url).toBe(
|
||||
'mock-api-url/workflow_templates/custom-module/test-template.jpg'
|
||||
)
|
||||
})
|
||||
|
||||
it('should format template titles correctly', () => {
|
||||
const { getTemplateTitle } = useTemplateWorkflows()
|
||||
|
||||
// Default template with localized title
|
||||
const titleWithLocalized = getTemplateTitle(
|
||||
{
|
||||
name: 'test',
|
||||
localizedTitle: 'Localized Title',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
description: 'Test'
|
||||
},
|
||||
'default'
|
||||
)
|
||||
expect(titleWithLocalized).toBe('Localized Title')
|
||||
|
||||
// Default template without localized title
|
||||
const titleWithFallback = getTemplateTitle(
|
||||
{
|
||||
name: 'test',
|
||||
title: 'Title',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
description: 'Test'
|
||||
},
|
||||
'default'
|
||||
)
|
||||
expect(titleWithFallback).toBe('Title')
|
||||
|
||||
// Custom template
|
||||
const customTitle = getTemplateTitle(
|
||||
{
|
||||
name: 'test-template',
|
||||
title: 'Custom Title',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
description: 'Test'
|
||||
},
|
||||
'custom-module'
|
||||
)
|
||||
expect(customTitle).toBe('Custom Title')
|
||||
|
||||
// Fallback to name
|
||||
const nameOnly = getTemplateTitle(
|
||||
{
|
||||
name: 'name-only',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
description: 'Test'
|
||||
},
|
||||
'custom-module'
|
||||
)
|
||||
expect(nameOnly).toBe('name-only')
|
||||
})
|
||||
|
||||
it('should format template descriptions correctly', () => {
|
||||
const { getTemplateDescription } = useTemplateWorkflows()
|
||||
|
||||
// Default template with localized description
|
||||
const descWithLocalized = getTemplateDescription(
|
||||
{
|
||||
name: 'test',
|
||||
localizedDescription: 'Localized Description',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg',
|
||||
description: 'Test'
|
||||
},
|
||||
'default'
|
||||
)
|
||||
expect(descWithLocalized).toBe('Localized Description')
|
||||
|
||||
// Custom template with description
|
||||
const customDesc = getTemplateDescription(
|
||||
{
|
||||
name: 'test',
|
||||
description: 'custom-template_description',
|
||||
mediaType: 'image',
|
||||
mediaSubtype: 'jpg'
|
||||
},
|
||||
'custom-module'
|
||||
)
|
||||
expect(customDesc).toBe('custom template description')
|
||||
})
|
||||
|
||||
it('should load a template from the "All" category', async () => {
|
||||
const { loadWorkflowTemplate, loadingTemplateId } = useTemplateWorkflows()
|
||||
|
||||
// Set the store as loaded
|
||||
mockWorkflowTemplatesStore.isLoaded = true
|
||||
|
||||
// Load a template from the "All" category
|
||||
const result = await loadWorkflowTemplate('template1', 'all')
|
||||
await flushPromises()
|
||||
|
||||
expect(result).toBe(true)
|
||||
expect(fetch).toHaveBeenCalledWith('mock-file-url/templates/template1.json')
|
||||
expect(loadingTemplateId.value).toBe(null) // Should reset after loading
|
||||
})
|
||||
|
||||
it('should load a template from a regular category', async () => {
|
||||
const { loadWorkflowTemplate } = useTemplateWorkflows()
|
||||
|
||||
// Set the store as loaded
|
||||
mockWorkflowTemplatesStore.isLoaded = true
|
||||
|
||||
// Load a template from the default category
|
||||
const result = await loadWorkflowTemplate('template1', 'default')
|
||||
await flushPromises()
|
||||
|
||||
expect(result).toBe(true)
|
||||
expect(fetch).toHaveBeenCalledWith('mock-file-url/templates/template1.json')
|
||||
})
|
||||
|
||||
it('should handle errors when loading templates', async () => {
|
||||
const { loadWorkflowTemplate, loadingTemplateId } = useTemplateWorkflows()
|
||||
|
||||
// Set the store as loaded
|
||||
mockWorkflowTemplatesStore.isLoaded = true
|
||||
|
||||
// Mock fetch to throw an error
|
||||
vi.mocked(fetch).mockRejectedValueOnce(new Error('Failed to fetch'))
|
||||
|
||||
// Spy on console.error
|
||||
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
|
||||
// Load a template that will fail
|
||||
const result = await loadWorkflowTemplate('error-template', 'default')
|
||||
|
||||
expect(result).toBe(false)
|
||||
expect(consoleSpy).toHaveBeenCalled()
|
||||
expect(loadingTemplateId.value).toBe(null) // Should reset even after error
|
||||
|
||||
// Restore console.error
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user