test: address tag migration review feedback

This commit is contained in:
dante01yoon
2026-05-04 16:01:14 +09:00
parent f5a669ff0d
commit d4636ff17d
5 changed files with 80 additions and 40 deletions

View File

@@ -28,17 +28,19 @@ describe('SearchFilterChip', () => {
expect(screen.getByText('I')).toBeInTheDocument()
})
it('applies semantic badge class for input type', () => {
renderChip({ text: 'CLIP', badge: 'I', badgeClass: 'i-badge' })
const badge = screen.getByText('I')
expect(badge.className).toContain('bg-green-500')
})
it('applies semantic badge class for output type', () => {
renderChip({ text: 'IMAGE', badge: 'O', badgeClass: 'o-badge' })
const badge = screen.getByText('O')
expect(badge.className).toContain('bg-red-500')
})
it.each([
['input type', 'I', 'i-badge', 'bg-green-500'],
['output type', 'O', 'o-badge', 'bg-red-500'],
['combo type', 'C', 'c-badge', 'bg-blue-500'],
['seed type', 'S', 's-badge', 'bg-yellow-500']
])(
'applies semantic badge class for %s',
(_, badgeText, badgeClass, color) => {
renderChip({ text: 'CLIP', badge: badgeText, badgeClass })
const badge = screen.getByText(badgeText)
expect(badge.className).toContain(color)
}
)
it('shows remove button and emits remove on click', async () => {
const user = userEvent.setup()

View File

@@ -47,10 +47,10 @@
</template>
<script setup lang="ts">
import ChipTag from '@/components/chip/Tag.vue'
import Tag from 'primevue/tag'
import { computed } from 'vue'
import ChipTag from '@/components/chip/Tag.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'

View File

@@ -1,10 +1,12 @@
import { render, screen } from '@testing-library/vue'
import userEvent from '@testing-library/user-event'
import { createTestingPinia } from '@pinia/testing'
import { describe, expect, it } from 'vitest'
import { createI18n } from 'vue-i18n'
import { DownloadStatus } from '@comfyorg/comfyui-electron-types'
import { useElectronDownloadStore } from '@/stores/electronDownloadStore'
import type { ElectronDownload } from '@/stores/electronDownloadStore'
import DownloadItem from './DownloadItem.vue'
@@ -19,46 +21,80 @@ const i18n = createI18n({
cancelled: 'Cancelled',
pause: 'Pause',
resume: 'Resume',
cancel: 'Cancel'
cancel: 'Cancel',
error: 'Error'
}
}
}
})
function renderDownloadItem(download: ElectronDownload) {
return render(DownloadItem, {
function createDownload(
status: DownloadStatus,
url = 'http://example.com/model.bin'
): ElectronDownload {
return {
url,
filename: 'model.bin',
savePath: '/models/checkpoints/model.bin',
status
}
}
function renderDownloadItem(
download: ElectronDownload,
initialDownloads: ElectronDownload[] = []
) {
const pinia = createTestingPinia({
initialState: {
downloads: { downloads: initialDownloads }
}
})
const view = render(DownloadItem, {
props: { download },
global: {
plugins: [createTestingPinia(), i18n],
plugins: [pinia, i18n],
stubs: {
ProgressBar: true
}
}
})
return {
...view,
electronDownloadStore: useElectronDownloadStore()
}
}
describe('DownloadItem', () => {
it('shows cancelled tag with remove button for cancelled downloads', () => {
renderDownloadItem({
url: 'http://example.com/model.bin',
filename: 'model.bin',
savePath: '/models/checkpoints/model.bin',
status: DownloadStatus.CANCELLED
})
renderDownloadItem(createDownload(DownloadStatus.CANCELLED))
expect(screen.getByText('Cancelled')).toBeInTheDocument()
expect(screen.getByRole('button', { name: 'Remove' })).toBeInTheDocument()
})
it('shows cancelled tag for error downloads', () => {
renderDownloadItem({
url: 'http://example.com/model.bin',
filename: 'model.bin',
savePath: '/models/checkpoints/model.bin',
status: DownloadStatus.ERROR
})
it('removes cancelled downloads from the store', async () => {
const user = userEvent.setup()
const cancelledDownload = createDownload(DownloadStatus.CANCELLED)
const pausedDownload = createDownload(
DownloadStatus.PAUSED,
'http://example.com/other-model.bin'
)
const { electronDownloadStore } = renderDownloadItem(cancelledDownload, [
cancelledDownload,
pausedDownload
])
expect(screen.getByText('Cancelled')).toBeInTheDocument()
await user.click(screen.getByRole('button', { name: 'Remove' }))
expect(electronDownloadStore.downloads).toEqual([pausedDownload])
})
it('shows error tag for error downloads', () => {
renderDownloadItem(createDownload(DownloadStatus.ERROR))
expect(screen.getByText('Error')).toBeInTheDocument()
})
it('does not show cancelled tag for in-progress downloads', () => {
@@ -71,15 +107,11 @@ describe('DownloadItem', () => {
})
expect(screen.queryByText('Cancelled')).not.toBeInTheDocument()
expect(screen.queryByText('Error')).not.toBeInTheDocument()
})
it('displays file path label', () => {
renderDownloadItem({
url: 'http://example.com/model.bin',
filename: 'model.bin',
savePath: '/models/checkpoints/model.bin',
status: DownloadStatus.CANCELLED
})
renderDownloadItem(createDownload(DownloadStatus.CANCELLED))
expect(screen.getByText('checkpoints/model.bin')).toBeInTheDocument()
})

View File

@@ -5,7 +5,13 @@
</div>
<div v-if="['cancelled', 'error'].includes(download.status ?? '')">
<Tag
:label="t('electronFileDownload.cancelled')"
:label="
t(
download.status === 'error'
? 'electronFileDownload.error'
: 'electronFileDownload.cancelled'
)
"
class="mt-2 bg-red-700 text-sm font-light"
removable
@remove="handleRemoveDownload"
@@ -67,10 +73,9 @@
<script setup lang="ts">
import ProgressBar from 'primevue/progressbar'
import Tag from '@/components/chip/Tag.vue'
import { useI18n } from 'vue-i18n'
import Tag from '@/components/chip/Tag.vue'
import Button from '@/components/ui/button/Button.vue'
import { useElectronDownloadStore } from '@/stores/electronDownloadStore'
import type { ElectronDownload } from '@/stores/electronDownloadStore'

View File

@@ -1188,7 +1188,8 @@
"paused": "Paused",
"resume": "Resume Download",
"cancel": "Cancel Download",
"cancelled": "Cancelled"
"cancelled": "Cancelled",
"error": "Error"
},
"maskEditor": {
"title": "Mask Editor",