From 10a3cdcaca357b924d4169be62504b747802bfb7 Mon Sep 17 00:00:00 2001 From: czlonkowski <56956555+czlonkowski@users.noreply.github.com> Date: Mon, 1 Dec 2025 18:40:51 +0100 Subject: [PATCH] test: add missing test coverage for PR #461 improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added test for AI Agent validation positive case (tools properly connected) - Added 3 tests for expectedFormat on resourceLocator properties Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tests/unit/services/property-filter.test.ts | 69 +++++++++++++++++++ .../workflow-validator-comprehensive.test.ts | 31 +++++++++ 2 files changed, 100 insertions(+) diff --git a/tests/unit/services/property-filter.test.ts b/tests/unit/services/property-filter.test.ts index fa8d008..2f34e44 100644 --- a/tests/unit/services/property-filter.test.ts +++ b/tests/unit/services/property-filter.test.ts @@ -406,5 +406,74 @@ describe('PropertyFilter', () => { const complex = result.common.find(p => p.name === 'complex'); expect(complex?.default).toBeUndefined(); }); + + it('should add expectedFormat for resourceLocator type properties', () => { + const properties = [ + { + name: 'channel', + type: 'resourceLocator', + displayName: 'Channel', + description: 'The channel to send message to', + modes: [ + { name: 'list', displayName: 'From List' }, + { name: 'id', displayName: 'By ID' }, + { name: 'url', displayName: 'By URL' } + ], + default: { mode: 'list', value: '' } + } + ]; + + const result = PropertyFilter.getEssentials(properties, 'nodes-base.slack'); + + const channelProp = result.common.find(p => p.name === 'channel'); + expect(channelProp).toBeDefined(); + expect(channelProp?.expectedFormat).toBeDefined(); + expect(channelProp?.expectedFormat?.structure).toEqual({ + mode: 'string', + value: 'string' + }); + expect(channelProp?.expectedFormat?.modes).toEqual(['list', 'id', 'url']); + expect(channelProp?.expectedFormat?.example).toBeDefined(); + expect(channelProp?.expectedFormat?.example.mode).toBe('id'); + expect(channelProp?.expectedFormat?.example.value).toBeDefined(); + }); + + it('should handle resourceLocator without modes array', () => { + const properties = [ + { + name: 'resource', + type: 'resourceLocator', + displayName: 'Resource', + default: { mode: 'id', value: 'test-123' } + } + ]; + + const result = PropertyFilter.getEssentials(properties, 'nodes-base.unknownNode'); + + const resourceProp = result.common.find(p => p.name === 'resource'); + expect(resourceProp?.expectedFormat).toBeDefined(); + // Should default to common modes + expect(resourceProp?.expectedFormat?.modes).toEqual(['list', 'id']); + expect(resourceProp?.expectedFormat?.example.value).toBe('test-123'); + }); + + it('should handle resourceLocator with no default value', () => { + const properties = [ + { + name: 'item', + type: 'resourceLocator', + displayName: 'Item', + modes: [{ name: 'search' }, { name: 'id' }] + } + ]; + + const result = PropertyFilter.getEssentials(properties, 'nodes-base.unknownNode'); + + const itemProp = result.common.find(p => p.name === 'item'); + expect(itemProp?.expectedFormat).toBeDefined(); + expect(itemProp?.expectedFormat?.modes).toEqual(['search', 'id']); + // Should use fallback value + expect(itemProp?.expectedFormat?.example.value).toBe('your-resource-id'); + }); }); }); \ No newline at end of file diff --git a/tests/unit/services/workflow-validator-comprehensive.test.ts b/tests/unit/services/workflow-validator-comprehensive.test.ts index 55440d4..4cce02b 100644 --- a/tests/unit/services/workflow-validator-comprehensive.test.ts +++ b/tests/unit/services/workflow-validator-comprehensive.test.ts @@ -1329,6 +1329,37 @@ describe('WorkflowValidator - Comprehensive Tests', () => { expect(result.warnings.some(w => w.message.includes('AI Agent has no tools connected'))).toBe(true); }); + it('should NOT warn about AI agents WITH tools properly connected', async () => { + const workflow = { + nodes: [ + { + id: '1', + name: 'Calculator Tool', + type: 'n8n-nodes-base.httpRequest', + position: [100, 100], + parameters: {} + }, + { + id: '2', + name: 'Agent', + type: '@n8n/n8n-nodes-langchain.agent', + position: [300, 100], + parameters: {} + } + ], + connections: { + 'Calculator Tool': { + ai_tool: [[{ node: 'Agent', type: 'ai_tool', index: 0 }]] + } + } + } as any; + + const result = await validator.validateWorkflow(workflow as any); + + // Should NOT have warning about missing tools + expect(result.warnings.some(w => w.message.includes('AI Agent has no tools connected'))).toBe(false); + }); + it('should suggest community package setting for AI tools', async () => { const workflow = { nodes: [