/** * @vitest-environment node */ import { describe, expect, it } from 'vitest' import { dedupeOverlappingWorkflowSearchMatches, workflowSearchMatchMatchesQuery, } from '@/lib/workflows/search-replace/resources/resolvers' import type { WorkflowSearchMatch } from '@/lib/workflows/search-replace/types' function createMatch(overrides: Partial): WorkflowSearchMatch { return { id: 'match', blockId: 'block-1', blockName: 'Block', blockType: 'function', subBlockId: 'code', canonicalSubBlockId: 'code', subBlockType: 'code', valuePath: [], target: { kind: 'subblock' }, kind: 'text', rawValue: '', searchText: '', editable: true, navigable: true, protected: false, ...overrides, } } describe('dedupeOverlappingWorkflowSearchMatches', () => { it('keeps the narrower text hit when a partial literal query overlaps an inline reference', () => { const textMatch = createMatch({ id: 'text-partial', kind: 'text', rawValue: ''", range: { start: 8, end: 16 }, }) const referenceMatch = createMatch({ id: 'workflow-reference', kind: 'workflow-reference', rawValue: '', searchText: 'start.hello', range: { start: 8, end: 21 }, resource: { kind: 'workflow-reference', token: '', key: 'start.hello' }, }) expect(dedupeOverlappingWorkflowSearchMatches([textMatch, referenceMatch])).toEqual([textMatch]) }) it('keeps the inline reference when it covers the same span as a text hit', () => { const textMatch = createMatch({ id: 'text-full', kind: 'text', rawValue: '', searchText: "return ''", range: { start: 8, end: 21 }, }) const referenceMatch = createMatch({ id: 'workflow-reference', kind: 'workflow-reference', rawValue: '', searchText: 'start.hello', range: { start: 8, end: 21 }, resource: { kind: 'workflow-reference', token: '', key: 'start.hello' }, }) expect(dedupeOverlappingWorkflowSearchMatches([textMatch, referenceMatch])).toEqual([ referenceMatch, ]) }) it('uses kind priority rather than iteration order for equal-span non-text matches', () => { const workflowReferenceMatch = createMatch({ id: 'workflow-reference', kind: 'workflow-reference', rawValue: '{{API_KEY}}', searchText: 'API_KEY', range: { start: 0, end: 11 }, resource: { kind: 'workflow-reference', token: '{{API_KEY}}', key: 'API_KEY' }, }) const environmentMatch = createMatch({ id: 'environment', kind: 'environment', rawValue: '{{API_KEY}}', searchText: 'API_KEY', range: { start: 0, end: 11 }, resource: { kind: 'environment', token: '{{API_KEY}}', key: 'API_KEY' }, }) expect( dedupeOverlappingWorkflowSearchMatches([workflowReferenceMatch, environmentMatch]) ).toEqual([workflowReferenceMatch]) expect( dedupeOverlappingWorkflowSearchMatches([environmentMatch, workflowReferenceMatch]) ).toEqual([workflowReferenceMatch]) }) it('does not collapse matches from different fields', () => { const firstMatch = createMatch({ id: 'first', range: { start: 0, end: 4 }, valuePath: ['first'], }) const secondMatch = createMatch({ id: 'second', range: { start: 0, end: 4 }, valuePath: ['second'], }) expect(dedupeOverlappingWorkflowSearchMatches([firstMatch, secondMatch])).toEqual([ firstMatch, secondMatch, ]) }) }) describe('workflowSearchMatchMatchesQuery', () => { it('does not keep structured resource matches alive from only block or field label text', () => { const selectorMatch = createMatch({ id: 'selector-resource', blockName: 'Testy', fieldTitle: 'Select Presentation', subBlockId: 'presentationId', subBlockType: 'file-selector', kind: 'file', rawValue: 'opaque-presentation-id', searchText: 'opaque-presentation-id', range: undefined, resource: { kind: 'file', key: 'opaque-presentation-id' }, }) expect( workflowSearchMatchMatchesQuery({ ...selectorMatch, displayLabel: 'Gucci Case' }, 'Test') ).toBe(false) expect( workflowSearchMatchMatchesQuery({ ...selectorMatch, displayLabel: 'Gucci Case' }, 'Gucci') ).toBe(true) }) })