diff --git a/browser_tests/tests/nodeSearchBox.spec.ts b/browser_tests/tests/nodeSearchBox.spec.ts index 89bfe4a5ec..4b50ee3ca3 100644 --- a/browser_tests/tests/nodeSearchBox.spec.ts +++ b/browser_tests/tests/nodeSearchBox.spec.ts @@ -215,6 +215,14 @@ test.describe('Node search box', { tag: '@node' }, () => { await expectFilterChips(comfyPage, ['MODEL', 'CLIP']) }) + test('Does not add duplicate filter with same type and value', async ({ + comfyPage + }) => { + await comfyPage.searchBox.addFilter('MODEL', 'Input Type') + await comfyPage.searchBox.addFilter('MODEL', 'Input Type') + await expectFilterChips(comfyPage, ['MODEL']) + }) + test('Can remove filter', async ({ comfyPage }) => { await comfyPage.searchBox.addFilter('MODEL', 'Input Type') await comfyPage.searchBox.removeFilter(0) diff --git a/src/components/searchbox/NodeSearchBoxPopover.test.ts b/src/components/searchbox/NodeSearchBoxPopover.test.ts new file mode 100644 index 0000000000..2f0da1dc89 --- /dev/null +++ b/src/components/searchbox/NodeSearchBoxPopover.test.ts @@ -0,0 +1,173 @@ +import { mount } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import PrimeVue from 'primevue/config' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { defineComponent } from 'vue' +import { createI18n } from 'vue-i18n' + +import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore' +import type { FuseFilter, FuseFilterWithValue } from '@/utils/fuseUtil' + +import NodeSearchBoxPopover from './NodeSearchBoxPopover.vue' + +const mockStoreRefs = vi.hoisted(() => ({ + visible: { value: false }, + newSearchBoxEnabled: { value: true } +})) + +vi.mock('@/platform/settings/settingStore', () => ({ + useSettingStore: () => ({ + get: vi.fn() + }) +})) + +vi.mock('pinia', async () => { + const actual = await vi.importActual('pinia') + return { + ...(actual as Record), + storeToRefs: () => mockStoreRefs + } +}) + +vi.mock('@/stores/workspace/searchBoxStore', () => ({ + useSearchBoxStore: () => ({}) +})) + +vi.mock('@/services/litegraphService', () => ({ + useLitegraphService: () => ({ + getCanvasCenter: vi.fn(() => [0, 0]), + addNodeOnGraph: vi.fn() + }) +})) + +vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({ + useWorkflowStore: () => ({ + activeWorkflow: null + }) +})) + +vi.mock('@/renderer/core/canvas/canvasStore', () => ({ + useCanvasStore: () => ({ + canvas: null, + getCanvas: vi.fn(() => ({ + linkConnector: { + events: new EventTarget(), + renderLinks: [] + } + })) + }) +})) + +vi.mock('@/stores/nodeDefStore', () => ({ + useNodeDefStore: () => ({ + nodeSearchService: { + nodeFilters: [], + inputTypeFilter: {}, + outputTypeFilter: {} + } + }) +})) + +const NodeSearchBoxStub = defineComponent({ + name: 'NodeSearchBox', + props: { + filters: { type: Array, default: () => [] } + }, + template: '