mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 03:01:54 +00:00
fix unit tests
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { describe, expect, it, vi } from 'vitest'
|
import { describe, expect, it, vi } from 'vitest'
|
||||||
|
import { createI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import TemplateWorkflowView from '@/components/templates/TemplateWorkflowView.vue'
|
import TemplateWorkflowView from '@/components/templates/TemplateWorkflowView.vue'
|
||||||
import { TemplateInfo } from '@/types/workflowTemplateTypes'
|
import { TemplateInfo } from '@/types/workflowTemplateTypes'
|
||||||
@@ -53,10 +54,46 @@ vi.mock('@/components/templates/TemplateWorkflowList.vue', () => ({
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/components/templates/TemplateSearchBar.vue', () => ({
|
||||||
|
default: {
|
||||||
|
template: '<div class="mock-search-bar"></div>',
|
||||||
|
props: ['searchQuery', 'filteredCount'],
|
||||||
|
emits: ['update:searchQuery', 'clearFilters']
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/components/templates/TemplateWorkflowCardSkeleton.vue', () => ({
|
||||||
|
default: {
|
||||||
|
template: '<div class="mock-skeleton"></div>'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@vueuse/core', () => ({
|
vi.mock('@vueuse/core', () => ({
|
||||||
useLocalStorage: () => 'grid'
|
useLocalStorage: () => 'grid'
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/composables/useIntersectionObserver', () => ({
|
||||||
|
useIntersectionObserver: vi.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/composables/useLazyPagination', () => ({
|
||||||
|
useLazyPagination: (items: any) => ({
|
||||||
|
paginatedItems: items,
|
||||||
|
isLoading: { value: false },
|
||||||
|
hasMoreItems: { value: false },
|
||||||
|
loadNextPage: vi.fn(),
|
||||||
|
reset: vi.fn()
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/composables/useTemplateFiltering', () => ({
|
||||||
|
useTemplateFiltering: (templates: any) => ({
|
||||||
|
searchQuery: { value: '' },
|
||||||
|
filteredTemplates: templates,
|
||||||
|
filteredCount: { value: templates.value?.length || 0 }
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
describe('TemplateWorkflowView', () => {
|
describe('TemplateWorkflowView', () => {
|
||||||
const createTemplate = (name: string): TemplateInfo => ({
|
const createTemplate = (name: string): TemplateInfo => ({
|
||||||
name,
|
name,
|
||||||
@@ -67,6 +104,18 @@ describe('TemplateWorkflowView', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const mountView = (props = {}) => {
|
const mountView = (props = {}) => {
|
||||||
|
const i18n = createI18n({
|
||||||
|
legacy: false,
|
||||||
|
locale: 'en',
|
||||||
|
messages: {
|
||||||
|
en: {
|
||||||
|
templateWorkflows: {
|
||||||
|
loadingMore: 'Loading more...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return mount(TemplateWorkflowView, {
|
return mount(TemplateWorkflowView, {
|
||||||
props: {
|
props: {
|
||||||
title: 'Test Templates',
|
title: 'Test Templates',
|
||||||
@@ -79,6 +128,9 @@ describe('TemplateWorkflowView', () => {
|
|||||||
],
|
],
|
||||||
loading: null,
|
loading: null,
|
||||||
...props
|
...props
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
plugins: [i18n]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,15 @@ vi.mock('@/components/templates/thumbnails/BaseThumbnail.vue', () => ({
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/components/common/LazyImage.vue', () => ({
|
||||||
|
default: {
|
||||||
|
name: 'LazyImage',
|
||||||
|
template:
|
||||||
|
'<img :src="src" :alt="alt" :class="imageClass" :style="imageStyle" draggable="false" />',
|
||||||
|
props: ['src', 'alt', 'imageClass', 'imageStyle']
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@vueuse/core', () => ({
|
vi.mock('@vueuse/core', () => ({
|
||||||
useMouseInElement: () => ({
|
useMouseInElement: () => ({
|
||||||
elementX: ref(50),
|
elementX: ref(50),
|
||||||
@@ -35,23 +44,24 @@ describe('CompareSliderThumbnail', () => {
|
|||||||
|
|
||||||
it('renders both base and overlay images', () => {
|
it('renders both base and overlay images', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const images = wrapper.findAll('img')
|
const lazyImages = wrapper.findAllComponents({ name: 'LazyImage' })
|
||||||
expect(images.length).toBe(2)
|
expect(lazyImages.length).toBe(2)
|
||||||
expect(images[0].attributes('src')).toBe('/base-image.jpg')
|
expect(lazyImages[0].props('src')).toBe('/base-image.jpg')
|
||||||
expect(images[1].attributes('src')).toBe('/overlay-image.jpg')
|
expect(lazyImages[1].props('src')).toBe('/overlay-image.jpg')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies correct alt text to both images', () => {
|
it('applies correct alt text to both images', () => {
|
||||||
const wrapper = mountThumbnail({ alt: 'Custom Alt Text' })
|
const wrapper = mountThumbnail({ alt: 'Custom Alt Text' })
|
||||||
const images = wrapper.findAll('img')
|
const lazyImages = wrapper.findAllComponents({ name: 'LazyImage' })
|
||||||
expect(images[0].attributes('alt')).toBe('Custom Alt Text')
|
expect(lazyImages[0].props('alt')).toBe('Custom Alt Text')
|
||||||
expect(images[1].attributes('alt')).toBe('Custom Alt Text')
|
expect(lazyImages[1].props('alt')).toBe('Custom Alt Text')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies clip-path style to overlay image', () => {
|
it('applies clip-path style to overlay image', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const overlay = wrapper.findAll('img')[1]
|
const overlayLazyImage = wrapper.findAllComponents({ name: 'LazyImage' })[1]
|
||||||
expect(overlay.attributes('style')).toContain('clip-path')
|
const imageStyle = overlayLazyImage.props('imageStyle')
|
||||||
|
expect(imageStyle.clipPath).toContain('inset')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders slider divider', () => {
|
it('renders slider divider', () => {
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ vi.mock('@/components/templates/thumbnails/BaseThumbnail.vue', () => ({
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/components/common/LazyImage.vue', () => ({
|
||||||
|
default: {
|
||||||
|
name: 'LazyImage',
|
||||||
|
template:
|
||||||
|
'<img :src="src" :alt="alt" :class="imageClass" :style="imageStyle" draggable="false" />',
|
||||||
|
props: ['src', 'alt', 'imageClass', 'imageStyle']
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
describe('DefaultThumbnail', () => {
|
describe('DefaultThumbnail', () => {
|
||||||
const mountThumbnail = (props = {}) => {
|
const mountThumbnail = (props = {}) => {
|
||||||
return mount(DefaultThumbnail, {
|
return mount(DefaultThumbnail, {
|
||||||
@@ -25,9 +34,9 @@ describe('DefaultThumbnail', () => {
|
|||||||
|
|
||||||
it('renders image with correct src and alt', () => {
|
it('renders image with correct src and alt', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.attributes('src')).toBe('/test-image.jpg')
|
expect(lazyImage.props('src')).toBe('/test-image.jpg')
|
||||||
expect(img.attributes('alt')).toBe('Test Image')
|
expect(lazyImage.props('alt')).toBe('Test Image')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies scale transform when hovered', () => {
|
it('applies scale transform when hovered', () => {
|
||||||
@@ -35,35 +44,43 @@ describe('DefaultThumbnail', () => {
|
|||||||
isHovered: true,
|
isHovered: true,
|
||||||
hoverZoom: 10
|
hoverZoom: 10
|
||||||
})
|
})
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.attributes('style')).toContain('scale(1.1)')
|
expect(lazyImage.props('imageStyle')).toEqual({ transform: 'scale(1.1)' })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does not apply scale transform when not hovered', () => {
|
it('does not apply scale transform when not hovered', () => {
|
||||||
const wrapper = mountThumbnail({
|
const wrapper = mountThumbnail({
|
||||||
isHovered: false
|
isHovered: false
|
||||||
})
|
})
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.attributes('style')).toBeUndefined()
|
expect(lazyImage.props('imageStyle')).toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies video styling for video type', () => {
|
it('applies video styling for video type', () => {
|
||||||
const wrapper = mountThumbnail({
|
const wrapper = mountThumbnail({
|
||||||
isVideo: true
|
isVideo: true
|
||||||
})
|
})
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.classes()).toContain('w-full')
|
const imageClass = lazyImage.props('imageClass')
|
||||||
expect(img.classes()).toContain('h-full')
|
const classString = Array.isArray(imageClass)
|
||||||
expect(img.classes()).toContain('object-cover')
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('w-full')
|
||||||
|
expect(classString).toContain('h-full')
|
||||||
|
expect(classString).toContain('object-cover')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies image styling for non-video type', () => {
|
it('applies image styling for non-video type', () => {
|
||||||
const wrapper = mountThumbnail({
|
const wrapper = mountThumbnail({
|
||||||
isVideo: false
|
isVideo: false
|
||||||
})
|
})
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.classes()).toContain('max-w-full')
|
const imageClass = lazyImage.props('imageClass')
|
||||||
expect(img.classes()).toContain('object-contain')
|
const classString = Array.isArray(imageClass)
|
||||||
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('max-w-full')
|
||||||
|
expect(classString).toContain('object-contain')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies correct styling for webp images', () => {
|
it('applies correct styling for webp images', () => {
|
||||||
@@ -71,8 +88,12 @@ describe('DefaultThumbnail', () => {
|
|||||||
src: '/test-video.webp',
|
src: '/test-video.webp',
|
||||||
isVideo: true
|
isVideo: true
|
||||||
})
|
})
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.classes()).toContain('object-cover')
|
const imageClass = lazyImage.props('imageClass')
|
||||||
|
const classString = Array.isArray(imageClass)
|
||||||
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('object-cover')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('image is not draggable', () => {
|
it('image is not draggable', () => {
|
||||||
@@ -83,11 +104,15 @@ describe('DefaultThumbnail', () => {
|
|||||||
|
|
||||||
it('applies transition classes', () => {
|
it('applies transition classes', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const img = wrapper.find('img')
|
const lazyImage = wrapper.findComponent({ name: 'LazyImage' })
|
||||||
expect(img.classes()).toContain('transform-gpu')
|
const imageClass = lazyImage.props('imageClass')
|
||||||
expect(img.classes()).toContain('transition-transform')
|
const classString = Array.isArray(imageClass)
|
||||||
expect(img.classes()).toContain('duration-300')
|
? imageClass.join(' ')
|
||||||
expect(img.classes()).toContain('ease-out')
|
: imageClass
|
||||||
|
expect(classString).toContain('transform-gpu')
|
||||||
|
expect(classString).toContain('transition-transform')
|
||||||
|
expect(classString).toContain('duration-300')
|
||||||
|
expect(classString).toContain('ease-out')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('passes correct props to BaseThumbnail', () => {
|
it('passes correct props to BaseThumbnail', () => {
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ vi.mock('@/components/templates/thumbnails/BaseThumbnail.vue', () => ({
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/components/common/LazyImage.vue', () => ({
|
||||||
|
default: {
|
||||||
|
name: 'LazyImage',
|
||||||
|
template:
|
||||||
|
'<img :src="src" :alt="alt" :class="imageClass" :style="imageStyle" draggable="false" />',
|
||||||
|
props: ['src', 'alt', 'imageClass', 'imageStyle']
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
describe('HoverDissolveThumbnail', () => {
|
describe('HoverDissolveThumbnail', () => {
|
||||||
const mountThumbnail = (props = {}) => {
|
const mountThumbnail = (props = {}) => {
|
||||||
return mount(HoverDissolveThumbnail, {
|
return mount(HoverDissolveThumbnail, {
|
||||||
@@ -27,31 +36,39 @@ describe('HoverDissolveThumbnail', () => {
|
|||||||
|
|
||||||
it('renders both base and overlay images', () => {
|
it('renders both base and overlay images', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const images = wrapper.findAll('img')
|
const lazyImages = wrapper.findAllComponents({ name: 'LazyImage' })
|
||||||
expect(images.length).toBe(2)
|
expect(lazyImages.length).toBe(2)
|
||||||
expect(images[0].attributes('src')).toBe('/base-image.jpg')
|
expect(lazyImages[0].props('src')).toBe('/base-image.jpg')
|
||||||
expect(images[1].attributes('src')).toBe('/overlay-image.jpg')
|
expect(lazyImages[1].props('src')).toBe('/overlay-image.jpg')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies correct alt text to both images', () => {
|
it('applies correct alt text to both images', () => {
|
||||||
const wrapper = mountThumbnail({ alt: 'Custom Alt Text' })
|
const wrapper = mountThumbnail({ alt: 'Custom Alt Text' })
|
||||||
const images = wrapper.findAll('img')
|
const lazyImages = wrapper.findAllComponents({ name: 'LazyImage' })
|
||||||
expect(images[0].attributes('alt')).toBe('Custom Alt Text')
|
expect(lazyImages[0].props('alt')).toBe('Custom Alt Text')
|
||||||
expect(images[1].attributes('alt')).toBe('Custom Alt Text')
|
expect(lazyImages[1].props('alt')).toBe('Custom Alt Text')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('makes overlay image visible when hovered', () => {
|
it('makes overlay image visible when hovered', () => {
|
||||||
const wrapper = mountThumbnail({ isHovered: true })
|
const wrapper = mountThumbnail({ isHovered: true })
|
||||||
const overlayImage = wrapper.findAll('img')[1]
|
const overlayLazyImage = wrapper.findAllComponents({ name: 'LazyImage' })[1]
|
||||||
expect(overlayImage.classes()).toContain('opacity-100')
|
const imageClass = overlayLazyImage.props('imageClass')
|
||||||
expect(overlayImage.classes()).not.toContain('opacity-0')
|
const classString = Array.isArray(imageClass)
|
||||||
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('opacity-100')
|
||||||
|
expect(classString).not.toContain('opacity-0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('makes overlay image hidden when not hovered', () => {
|
it('makes overlay image hidden when not hovered', () => {
|
||||||
const wrapper = mountThumbnail({ isHovered: false })
|
const wrapper = mountThumbnail({ isHovered: false })
|
||||||
const overlayImage = wrapper.findAll('img')[1]
|
const overlayLazyImage = wrapper.findAllComponents({ name: 'LazyImage' })[1]
|
||||||
expect(overlayImage.classes()).toContain('opacity-0')
|
const imageClass = overlayLazyImage.props('imageClass')
|
||||||
expect(overlayImage.classes()).not.toContain('opacity-100')
|
const classString = Array.isArray(imageClass)
|
||||||
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('opacity-0')
|
||||||
|
expect(classString).not.toContain('opacity-100')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('passes isHovered prop to BaseThumbnail', () => {
|
it('passes isHovered prop to BaseThumbnail', () => {
|
||||||
@@ -62,21 +79,33 @@ describe('HoverDissolveThumbnail', () => {
|
|||||||
|
|
||||||
it('applies transition classes to overlay image', () => {
|
it('applies transition classes to overlay image', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const overlayImage = wrapper.findAll('img')[1]
|
const overlayLazyImage = wrapper.findAllComponents({ name: 'LazyImage' })[1]
|
||||||
expect(overlayImage.classes()).toContain('transition-opacity')
|
const imageClass = overlayLazyImage.props('imageClass')
|
||||||
expect(overlayImage.classes()).toContain('duration-300')
|
const classString = Array.isArray(imageClass)
|
||||||
|
? imageClass.join(' ')
|
||||||
|
: imageClass
|
||||||
|
expect(classString).toContain('transition-opacity')
|
||||||
|
expect(classString).toContain('duration-300')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('applies correct positioning to both images', () => {
|
it('applies correct positioning to both images', () => {
|
||||||
const wrapper = mountThumbnail()
|
const wrapper = mountThumbnail()
|
||||||
const images = wrapper.findAll('img')
|
const lazyImages = wrapper.findAllComponents({ name: 'LazyImage' })
|
||||||
|
|
||||||
// Check base image
|
// Check base image
|
||||||
expect(images[0].classes()).toContain('absolute')
|
const baseImageClass = lazyImages[0].props('imageClass')
|
||||||
expect(images[0].classes()).toContain('inset-0')
|
const baseClassString = Array.isArray(baseImageClass)
|
||||||
|
? baseImageClass.join(' ')
|
||||||
|
: baseImageClass
|
||||||
|
expect(baseClassString).toContain('absolute')
|
||||||
|
expect(baseClassString).toContain('inset-0')
|
||||||
|
|
||||||
// Check overlay image
|
// Check overlay image
|
||||||
expect(images[1].classes()).toContain('absolute')
|
const overlayImageClass = lazyImages[1].props('imageClass')
|
||||||
expect(images[1].classes()).toContain('inset-0')
|
const overlayClassString = Array.isArray(overlayImageClass)
|
||||||
|
? overlayImageClass.join(' ')
|
||||||
|
: overlayImageClass
|
||||||
|
expect(overlayClassString).toContain('absolute')
|
||||||
|
expect(overlayClassString).toContain('inset-0')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user