Skip to main content
Glama

n8n-MCP

by 88-888
example-generator.test.tsโ€ข14.5 kB
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { ExampleGenerator } from '@/services/example-generator'; import type { NodeExamples } from '@/services/example-generator'; // Mock the database vi.mock('better-sqlite3'); describe('ExampleGenerator', () => { beforeEach(() => { vi.clearAllMocks(); }); describe('getExamples', () => { it('should return curated examples for HTTP Request node', () => { const examples = ExampleGenerator.getExamples('nodes-base.httpRequest'); expect(examples).toHaveProperty('minimal'); expect(examples).toHaveProperty('common'); expect(examples).toHaveProperty('advanced'); // Check minimal example expect(examples.minimal).toEqual({ url: 'https://api.example.com/data' }); // Check common example has required fields expect(examples.common).toMatchObject({ method: 'POST', url: 'https://api.example.com/users', sendBody: true, contentType: 'json' }); // Check advanced example has error handling expect(examples.advanced).toMatchObject({ method: 'POST', onError: 'continueRegularOutput', retryOnFail: true, maxTries: 3 }); }); it('should return curated examples for Webhook node', () => { const examples = ExampleGenerator.getExamples('nodes-base.webhook'); expect(examples.minimal).toMatchObject({ path: 'my-webhook', httpMethod: 'POST' }); expect(examples.common).toMatchObject({ responseMode: 'lastNode', responseData: 'allEntries', responseCode: 200 }); }); it('should return curated examples for Code node', () => { const examples = ExampleGenerator.getExamples('nodes-base.code'); expect(examples.minimal).toMatchObject({ language: 'javaScript', jsCode: 'return [{json: {result: "success"}}];' }); expect(examples.common?.jsCode).toContain('items.map'); expect(examples.common?.jsCode).toContain('DateTime.now()'); expect(examples.advanced?.jsCode).toContain('try'); expect(examples.advanced?.jsCode).toContain('catch'); }); it('should generate basic examples for unconfigured nodes', () => { const essentials = { required: [ { name: 'url', type: 'string' }, { name: 'method', type: 'options', options: [{ value: 'GET' }, { value: 'POST' }] } ], common: [ { name: 'timeout', type: 'number' } ] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ url: 'https://api.example.com', method: 'GET' }); expect(examples.common).toBeUndefined(); expect(examples.advanced).toBeUndefined(); }); it('should use common property if no required fields exist', () => { const essentials = { required: [], common: [ { name: 'name', type: 'string' } ] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ name: 'John Doe' }); }); it('should return empty minimal object if no essentials provided', () => { const examples = ExampleGenerator.getExamples('nodes-base.unknownNode'); expect(examples.minimal).toEqual({}); }); }); describe('special example nodes', () => { it('should provide webhook processing example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.webhookProcessing'); expect(examples.minimal?.jsCode).toContain('const webhookData = items[0].json.body'); expect(examples.minimal?.jsCode).toContain('// โŒ WRONG'); expect(examples.minimal?.jsCode).toContain('// โœ… CORRECT'); }); it('should provide data transformation examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.dataTransform'); expect(examples.minimal?.jsCode).toContain('CSV-like data to JSON'); expect(examples.minimal?.jsCode).toContain('split'); }); it('should provide aggregation example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.aggregation'); expect(examples.minimal?.jsCode).toContain('items.reduce'); expect(examples.minimal?.jsCode).toContain('totalAmount'); }); it('should provide JMESPath filtering example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.jmespathFiltering'); expect(examples.minimal?.jsCode).toContain('$jmespath'); expect(examples.minimal?.jsCode).toContain('`100`'); // Backticks for numeric literals expect(examples.minimal?.jsCode).toContain('โœ… CORRECT'); }); it('should provide Python example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.pythonExample'); expect(examples.minimal?.pythonCode).toContain('_input.all()'); expect(examples.minimal?.pythonCode).toContain('to_py()'); expect(examples.minimal?.pythonCode).toContain('import json'); }); it('should provide AI tool example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.aiTool'); expect(examples.minimal?.mode).toBe('runOnceForEachItem'); expect(examples.minimal?.jsCode).toContain('calculate discount'); expect(examples.minimal?.jsCode).toContain('$json.quantity'); }); it('should provide crypto usage example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.crypto'); expect(examples.minimal?.jsCode).toContain("require('crypto')"); expect(examples.minimal?.jsCode).toContain('randomBytes'); expect(examples.minimal?.jsCode).toContain('createHash'); }); it('should provide static data example', () => { const examples = ExampleGenerator.getExamples('nodes-base.code.staticData'); expect(examples.minimal?.jsCode).toContain('$getWorkflowStaticData'); expect(examples.minimal?.jsCode).toContain('processCount'); }); }); describe('database node examples', () => { it('should provide PostgreSQL examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.postgres'); expect(examples.minimal).toMatchObject({ operation: 'executeQuery', query: 'SELECT * FROM users LIMIT 10' }); expect(examples.advanced?.query).toContain('ON CONFLICT'); expect(examples.advanced?.retryOnFail).toBe(true); }); it('should provide MongoDB examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.mongoDb'); expect(examples.minimal).toMatchObject({ operation: 'find', collection: 'users' }); expect(examples.common).toMatchObject({ operation: 'findOneAndUpdate', options: { upsert: true, returnNewDocument: true } }); }); it('should provide MySQL examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.mySql'); expect(examples.minimal?.query).toContain('SELECT * FROM products'); expect(examples.common?.operation).toBe('insert'); }); }); describe('communication node examples', () => { it('should provide Slack examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.slack'); expect(examples.minimal).toMatchObject({ resource: 'message', operation: 'post', channel: '#general', text: 'Hello from n8n!' }); expect(examples.common?.attachments).toBeDefined(); expect(examples.common?.retryOnFail).toBe(true); }); it('should provide Email examples', () => { const examples = ExampleGenerator.getExamples('nodes-base.emailSend'); expect(examples.minimal).toMatchObject({ fromEmail: 'sender@example.com', toEmail: 'recipient@example.com', subject: 'Test Email' }); expect(examples.common?.html).toContain('<h1>Welcome!</h1>'); }); }); describe('error handling patterns', () => { it('should provide modern error handling patterns', () => { const examples = ExampleGenerator.getExamples('error-handling.modern-patterns'); expect(examples.minimal).toMatchObject({ onError: 'continueRegularOutput' }); expect(examples.advanced).toMatchObject({ onError: 'stopWorkflow', retryOnFail: true, maxTries: 3 }); }); it('should provide API retry patterns', () => { const examples = ExampleGenerator.getExamples('error-handling.api-with-retry'); expect(examples.common?.retryOnFail).toBe(true); expect(examples.common?.maxTries).toBe(5); expect(examples.common?.alwaysOutputData).toBe(true); }); it('should provide database error patterns', () => { const examples = ExampleGenerator.getExamples('error-handling.database-patterns'); expect(examples.common).toMatchObject({ retryOnFail: true, maxTries: 3, onError: 'stopWorkflow' }); }); it('should provide webhook error patterns', () => { const examples = ExampleGenerator.getExamples('error-handling.webhook-patterns'); expect(examples.minimal?.alwaysOutputData).toBe(true); expect(examples.common?.responseCode).toBe(200); }); }); describe('getTaskExample', () => { it('should return minimal example for basic task', () => { const example = ExampleGenerator.getTaskExample('nodes-base.httpRequest', 'basic'); expect(example).toEqual({ url: 'https://api.example.com/data' }); }); it('should return common example for typical task', () => { const example = ExampleGenerator.getTaskExample('nodes-base.httpRequest', 'typical'); expect(example).toMatchObject({ method: 'POST', sendBody: true }); }); it('should return advanced example for complex task', () => { const example = ExampleGenerator.getTaskExample('nodes-base.httpRequest', 'complex'); expect(example).toMatchObject({ retryOnFail: true, maxTries: 3 }); }); it('should default to common example for unknown task', () => { const example = ExampleGenerator.getTaskExample('nodes-base.httpRequest', 'unknown'); expect(example).toMatchObject({ method: 'POST' // This is from common example }); }); it('should return undefined for unknown node type', () => { const example = ExampleGenerator.getTaskExample('nodes-base.unknownNode', 'basic'); expect(example).toBeUndefined(); }); }); describe('default value generation', () => { it('should generate appropriate defaults for different property types', () => { const essentials = { required: [ { name: 'url', type: 'string' }, { name: 'port', type: 'number' }, { name: 'enabled', type: 'boolean' }, { name: 'method', type: 'options', options: [{ value: 'GET' }, { value: 'POST' }] }, { name: 'data', type: 'json' } ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ url: 'https://api.example.com', port: 80, enabled: false, method: 'GET', data: '{\n "key": "value"\n}' }); }); it('should use property defaults when available', () => { const essentials = { required: [ { name: 'timeout', type: 'number', default: 5000 }, { name: 'retries', type: 'number', default: 3 } ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ timeout: 5000, retries: 3 }); }); it('should generate context-aware string defaults', () => { const essentials = { required: [ { name: 'fromEmail', type: 'string' }, { name: 'toEmail', type: 'string' }, { name: 'webhookPath', type: 'string' }, { name: 'username', type: 'string' }, { name: 'apiKey', type: 'string' }, { name: 'query', type: 'string' }, { name: 'collection', type: 'string' } ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ fromEmail: 'sender@example.com', toEmail: 'recipient@example.com', webhookPath: 'my-webhook', username: 'John Doe', apiKey: 'myKey', query: 'SELECT * FROM table_name LIMIT 10', collection: 'users' }); }); it('should use placeholder as fallback for string defaults', () => { const essentials = { required: [ { name: 'customField', type: 'string', placeholder: 'Enter custom value' } ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ customField: 'Enter custom value' }); }); }); describe('edge cases', () => { it('should handle empty essentials object', () => { const essentials = { required: [], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({}); }); it('should handle properties with missing options', () => { const essentials = { required: [ { name: 'choice', type: 'options' } // No options array ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ choice: '' }); }); it('should handle collection and fixedCollection types', () => { const essentials = { required: [ { name: 'headers', type: 'collection' }, { name: 'options', type: 'fixedCollection' } ], common: [] }; const examples = ExampleGenerator.getExamples('nodes-base.unknownNode', essentials); expect(examples.minimal).toEqual({ headers: {}, options: {} }); }); }); });

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