Skip to main content
Glama

n8n-MCP

by 88-888
chat-trigger-validation.test.tsβ€’9.9 kB
/** * Integration Tests: Chat Trigger Validation * * Tests Chat Trigger validation against real n8n instance. */ import { describe, it, expect, beforeEach, afterEach, afterAll } from 'vitest'; import { createTestContext, TestContext, createTestWorkflowName } from '../n8n-api/utils/test-context'; import { getTestN8nClient } from '../n8n-api/utils/n8n-client'; import { N8nApiClient } from '../../../src/services/n8n-api-client'; import { cleanupOrphanedWorkflows } from '../n8n-api/utils/cleanup-helpers'; import { createMcpContext } from '../n8n-api/utils/mcp-context'; import { InstanceContext } from '../../../src/types/instance-context'; import { handleValidateWorkflow } from '../../../src/mcp/handlers-n8n-manager'; import { getNodeRepository, closeNodeRepository } from '../n8n-api/utils/node-repository'; import { NodeRepository } from '../../../src/database/node-repository'; import { ValidationResponse } from '../n8n-api/types/mcp-responses'; import { createChatTriggerNode, createAIAgentNode, createLanguageModelNode, createRespondNode, createAIConnection, createMainConnection, mergeConnections, createAIWorkflow } from './helpers'; import { WorkflowNode } from '../../../src/types/n8n-api'; describe('Integration: Chat Trigger Validation', () => { let context: TestContext; let client: N8nApiClient; let mcpContext: InstanceContext; let repository: NodeRepository; beforeEach(async () => { context = createTestContext(); client = getTestN8nClient(); mcpContext = createMcpContext(); repository = await getNodeRepository(); }); afterEach(async () => { await context.cleanup(); }); afterAll(async () => { await closeNodeRepository(); if (!process.env.CI) { await cleanupOrphanedWorkflows(); } }); // ====================================================================== // TEST 1: Streaming to Non-AI-Agent // ====================================================================== it('should detect streaming to non-AI-Agent', async () => { const chatTrigger = createChatTriggerNode({ name: 'Chat Trigger', responseMode: 'streaming' }); // Regular node (not AI Agent) const regularNode: WorkflowNode = { id: 'set-1', name: 'Set', type: 'n8n-nodes-base.set', typeVersion: 3.4, position: [450, 300], parameters: { assignments: { assignments: [] } } }; const workflow = createAIWorkflow( [chatTrigger, regularNode], createMainConnection('Chat Trigger', 'Set'), { name: createTestWorkflowName('Chat Trigger - Wrong Target'), tags: ['mcp-integration-test', 'ai-validation'] } ); const created = await client.createWorkflow(workflow); context.trackWorkflow(created.id!); const response = await handleValidateWorkflow( { id: created.id }, repository, mcpContext ); expect(response.success).toBe(true); const data = response.data as ValidationResponse; expect(data.valid).toBe(false); expect(data.errors).toBeDefined(); const errorCodes = data.errors!.map(e => e.details?.code || e.code); expect(errorCodes).toContain('STREAMING_WRONG_TARGET'); const errorMessages = data.errors!.map(e => e.message).join(' '); expect(errorMessages).toMatch(/streaming.*AI Agent/i); }); // ====================================================================== // TEST 2: Missing Connections // ====================================================================== it('should detect missing connections', async () => { const chatTrigger = createChatTriggerNode({ name: 'Chat Trigger' }); const workflow = createAIWorkflow( [chatTrigger], {}, // No connections { name: createTestWorkflowName('Chat Trigger - No Connections'), tags: ['mcp-integration-test', 'ai-validation'] } ); const created = await client.createWorkflow(workflow); context.trackWorkflow(created.id!); const response = await handleValidateWorkflow( { id: created.id }, repository, mcpContext ); expect(response.success).toBe(true); const data = response.data as ValidationResponse; expect(data.valid).toBe(false); expect(data.errors).toBeDefined(); const errorCodes = data.errors!.map(e => e.details?.code || e.code); expect(errorCodes).toContain('MISSING_CONNECTIONS'); }); // ====================================================================== // TEST 3: Valid Streaming Setup // ====================================================================== it('should validate valid streaming setup', async () => { const chatTrigger = createChatTriggerNode({ name: 'Chat Trigger', responseMode: 'streaming' }); const languageModel = createLanguageModelNode('openai', { name: 'OpenAI Chat Model' }); const agent = createAIAgentNode({ name: 'AI Agent', text: 'You are a helpful assistant' // No main output connections - streaming mode }); const workflow = createAIWorkflow( [chatTrigger, languageModel, agent], mergeConnections( createMainConnection('Chat Trigger', 'AI Agent'), createAIConnection('OpenAI Chat Model', 'AI Agent', 'ai_languageModel') // NO main output from AI Agent ), { name: createTestWorkflowName('Chat Trigger - Valid Streaming'), tags: ['mcp-integration-test', 'ai-validation'] } ); const created = await client.createWorkflow(workflow); context.trackWorkflow(created.id!); const response = await handleValidateWorkflow( { id: created.id }, repository, mcpContext ); expect(response.success).toBe(true); const data = response.data as ValidationResponse; expect(data.valid).toBe(true); expect(data.errors).toBeUndefined(); expect(data.summary.errorCount).toBe(0); }); // ====================================================================== // TEST 4: LastNode Mode (Default) // ====================================================================== it('should validate lastNode mode with AI Agent', async () => { const chatTrigger = createChatTriggerNode({ name: 'Chat Trigger', responseMode: 'lastNode' }); const languageModel = createLanguageModelNode('openai', { name: 'OpenAI Chat Model' }); const agent = createAIAgentNode({ name: 'AI Agent', text: 'You are a helpful assistant' }); const respond = createRespondNode({ name: 'Respond to Webhook' }); const workflow = createAIWorkflow( [chatTrigger, languageModel, agent, respond], mergeConnections( createMainConnection('Chat Trigger', 'AI Agent'), createAIConnection('OpenAI Chat Model', 'AI Agent', 'ai_languageModel'), createMainConnection('AI Agent', 'Respond to Webhook') ), { name: createTestWorkflowName('Chat Trigger - LastNode Mode'), tags: ['mcp-integration-test', 'ai-validation'] } ); const created = await client.createWorkflow(workflow); context.trackWorkflow(created.id!); const response = await handleValidateWorkflow( { id: created.id }, repository, mcpContext ); expect(response.success).toBe(true); const data = response.data as ValidationResponse; // Should be valid (lastNode mode allows main output) expect(data.valid).toBe(true); // May have info suggestion about using streaming if (data.info) { const streamingSuggestion = data.info.find((i: any) => i.message.toLowerCase().includes('streaming') ); // This is optional - just checking the suggestion exists if present if (streamingSuggestion) { expect(streamingSuggestion.severity).toBe('info'); } } }); // ====================================================================== // TEST 5: Streaming Agent with Output Connection (Error) // ====================================================================== it('should detect streaming agent with output connection', async () => { const chatTrigger = createChatTriggerNode({ name: 'Chat Trigger', responseMode: 'streaming' }); const languageModel = createLanguageModelNode('openai', { name: 'OpenAI Chat Model' }); const agent = createAIAgentNode({ name: 'AI Agent', text: 'You are a helpful assistant' }); const respond = createRespondNode({ name: 'Respond to Webhook' }); const workflow = createAIWorkflow( [chatTrigger, languageModel, agent, respond], mergeConnections( createMainConnection('Chat Trigger', 'AI Agent'), createAIConnection('OpenAI Chat Model', 'AI Agent', 'ai_languageModel'), createMainConnection('AI Agent', 'Respond to Webhook') // ERROR in streaming mode ), { name: createTestWorkflowName('Chat Trigger - Streaming With Output'), tags: ['mcp-integration-test', 'ai-validation'] } ); const created = await client.createWorkflow(workflow); context.trackWorkflow(created.id!); const response = await handleValidateWorkflow( { id: created.id }, repository, mcpContext ); expect(response.success).toBe(true); const data = response.data as ValidationResponse; expect(data.valid).toBe(false); expect(data.errors).toBeDefined(); // Should detect streaming agent has output const streamingErrors = data.errors!.filter(e => { const code = e.details?.code || e.code; return code === 'STREAMING_AGENT_HAS_OUTPUT' || e.message.toLowerCase().includes('streaming'); }); expect(streamingErrors.length).toBeGreaterThan(0); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/88-888/n8n-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server