integration.test.ts•6.06 kB
import { describe, it, expect } from '@jest/globals';
// Integration test demonstrating the new granular operations concept
describe('N8n MCP Granular Operations Integration', () => {
it('should have all required MCP tools defined', () => {
// Test that all required tool names are included in the expected tools
const expectedTools = [
'list_workflows',
'get_workflow',
'create_workflow',
'update_workflow',
'delete_workflow',
'activate_workflow',
'deactivate_workflow',
'create_node',
'update_node',
'connect_nodes',
'delete_node',
'set_node_position'
];
// This test verifies that our implementation includes all expected tools
// In a real MCP server, these would be registered and available for use
expect(expectedTools).toHaveLength(12);
expect(expectedTools).toContain('create_node');
expect(expectedTools).toContain('update_node');
expect(expectedTools).toContain('connect_nodes');
expect(expectedTools).toContain('delete_node');
expect(expectedTools).toContain('set_node_position');
});
it('should validate incremental workflow modification flow', () => {
// This test demonstrates the expected flow for incremental modifications:
// 1. create_node - Add a webhook node
// 2. create_node - Add a set node
// 3. connect_nodes - Connect webhook to set
// 4. update_node - Modify set node parameters
// 5. set_node_position - Reposition nodes
// 6. delete_node - Remove a node if needed
const mockFlow = [
{
operation: 'create_node',
request: {
workflowId: 1,
type: 'n8n-nodes-base.webhook',
name: 'Webhook Trigger',
params: { httpMethod: 'POST', path: 'data' }
},
expectedResponse: { nodeId: expect.stringMatching(/^node_\d+_[a-z0-9]+$/) }
},
{
operation: 'create_node',
request: {
workflowId: 1,
type: 'n8n-nodes-base.set',
name: 'Process Data'
},
expectedResponse: { nodeId: expect.stringMatching(/^node_\d+_[a-z0-9]+$/) }
},
{
operation: 'connect_nodes',
request: {
workflowId: 1,
from: { nodeId: 'webhook-node-id' },
to: { nodeId: 'set-node-id' }
},
expectedResponse: { ok: true }
},
{
operation: 'update_node',
request: {
workflowId: 1,
nodeId: 'set-node-id',
params: { values: { string: [{ name: 'processed', value: 'true' }] } }
},
expectedResponse: { nodeId: 'set-node-id' }
},
{
operation: 'set_node_position',
request: {
workflowId: 1,
nodeId: 'set-node-id',
x: 450,
y: 300
},
expectedResponse: { ok: true }
}
];
// Verify the flow structure is correct
expect(mockFlow).toHaveLength(5);
expect(mockFlow[0].operation).toBe('create_node');
expect(mockFlow[2].operation).toBe('connect_nodes');
expect(mockFlow[4].operation).toBe('set_node_position');
// Each operation should have the correct structure
mockFlow.forEach(step => {
expect(step.request.workflowId).toBe(1);
expect(step.expectedResponse).toBeDefined();
});
});
it('should demonstrate agent-driven workflow building', () => {
// This demonstrates how an AI agent might use the granular operations
// to build a workflow step by step
const agentActions = [
// Step 1: Create initial webhook trigger
{
tool: 'create_node',
params: {
workflowId: 1,
type: 'n8n-nodes-base.webhook',
name: 'Data Receiver',
params: { httpMethod: 'POST', path: 'webhook' },
position: [100, 200]
},
purpose: 'Set up data ingestion endpoint'
},
// Step 2: Create data processing node
{
tool: 'create_node',
params: {
workflowId: 1,
type: 'n8n-nodes-base.code',
name: 'Process Input',
params: { jsCode: 'return [{ processed: true, data: $input.all() }];' },
position: [300, 200]
},
purpose: 'Transform incoming data'
},
// Step 3: Connect the nodes
{
tool: 'connect_nodes',
params: {
workflowId: 1,
from: { nodeId: 'webhook-node-id' },
to: { nodeId: 'code-node-id' }
},
purpose: 'Establish data flow'
},
// Step 4: Update processing logic based on requirements
{
tool: 'update_node',
params: {
workflowId: 1,
nodeId: 'code-node-id',
params: {
jsCode: 'return [{ processed: true, timestamp: new Date(), data: $input.all() }];'
}
},
purpose: 'Add timestamp to processed data'
},
// Step 5: Adjust layout for better visualization
{
tool: 'set_node_position',
params: {
workflowId: 1,
nodeId: 'code-node-id',
x: 350,
y: 180
},
purpose: 'Optimize visual layout'
}
];
// Verify the agent action structure
expect(agentActions).toHaveLength(5);
// Each action should have proper structure
agentActions.forEach(action => {
expect(action.tool).toBeDefined();
expect(action.params).toBeDefined();
expect(action.params.workflowId).toBe(1);
expect(action.purpose).toBeDefined();
});
// Verify the sequence follows logical workflow building patterns
expect(agentActions[0].tool).toBe('create_node'); // Start with trigger
expect(agentActions[1].tool).toBe('create_node'); // Add processing
expect(agentActions[2].tool).toBe('connect_nodes'); // Connect them
expect(agentActions[3].tool).toBe('update_node'); // Refine processing
expect(agentActions[4].tool).toBe('set_node_position'); // Optimize layout
});
});