Skip to main content
Glama
node-validator.test.ts7.6 kB
import { describe, it, expect } from '@jest/globals'; import { validateNodeConfig, validateCredentials, validateFullNodeConfig } from '../node-validator.js'; describe('Node Validator', () => { describe('validateNodeConfig', () => { it('should validate valid HTTP Request configuration', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'GET', url: 'https://api.example.com/data', authentication: 'none', }); expect(result.valid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should catch missing required parameters for HTTP Request', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', { authentication: 'none', // missing required 'method' and 'url' }); expect(result.valid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); const methodError = result.errors.find(e => e.property === 'method'); expect(methodError).toBeDefined(); expect(methodError?.code).toBe('MISSING_REQUIRED'); expect(methodError?.message).toContain('Required property'); const urlError = result.errors.find(e => e.property === 'url'); expect(urlError).toBeDefined(); expect(urlError?.code).toBe('MISSING_REQUIRED'); }); it('should catch invalid enum values for HTTP Request method', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'INVALID_METHOD', url: 'https://api.example.com', authentication: 'none', }); expect(result.valid).toBe(false); const methodError = result.errors.find(e => e.property === 'method'); expect(methodError).toBeDefined(); expect(methodError?.code).toBe('INVALID_ENUM'); expect(methodError?.message).toContain('must be one of'); }); it('should validate valid Webhook configuration', () => { const result = validateNodeConfig('n8n-nodes-base.webhook', { httpMethod: 'POST', path: 'my-webhook', authentication: 'none', responseMode: 'onReceived', }); expect(result.valid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should catch missing required parameters for Webhook', () => { const result = validateNodeConfig('n8n-nodes-base.webhook', { authentication: 'none', // missing required 'httpMethod' and 'path' }); expect(result.valid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); const methodError = result.errors.find(e => e.property === 'httpMethod'); expect(methodError).toBeDefined(); expect(methodError?.code).toBe('MISSING_REQUIRED'); const pathError = result.errors.find(e => e.property === 'path'); expect(pathError).toBeDefined(); expect(pathError?.code).toBe('MISSING_REQUIRED'); }); it('should return error for unknown node type', () => { const result = validateNodeConfig('unknown-node-type', {}); expect(result.valid).toBe(false); expect(result.errors).toHaveLength(1); expect(result.errors[0].property).toBe('type'); expect(result.errors[0].code).toBe('INVALID_TYPE'); expect(result.errors[0].message).toContain('Unknown node type'); }); it('should handle conditional properties with displayOptions', () => { // Test sendBody property that only shows for POST/PUT/PATCH methods const resultWithPost = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'POST', url: 'https://api.example.com', sendBody: true, contentType: 'json', }); expect(resultWithPost.valid).toBe(true); // contentType should be ignored for GET requests due to displayOptions const resultWithGet = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'GET', url: 'https://api.example.com', sendBody: false, // contentType should be ignored since sendBody is false }); expect(resultWithGet.valid).toBe(true); }); it('should validate type constraints', () => { // Test string type validation const stringResult = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'GET', url: 123, // should be string authentication: 'none', }); expect(stringResult.valid).toBe(false); const urlError = stringResult.errors.find(e => e.property === 'url'); expect(urlError?.code).toBe('INVALID_TYPE'); expect(urlError?.expected).toBe('string'); }); }); describe('validateCredentials', () => { it('should pass when no credentials are required', () => { const errors = validateCredentials('n8n-nodes-base.noOp', {}); expect(errors).toHaveLength(0); }); it('should pass when required credentials are provided', () => { // Note: our test node types don't mark credentials as required // This is a basic test structure const errors = validateCredentials('n8n-nodes-base.httpRequest', { httpBasicAuth: 'my-basic-auth', }); expect(errors).toHaveLength(0); }); it('should handle unknown node type gracefully', () => { const errors = validateCredentials('unknown-node-type', {}); expect(errors).toHaveLength(0); }); }); describe('validateFullNodeConfig', () => { it('should validate both parameters and credentials', () => { const result = validateFullNodeConfig( 'n8n-nodes-base.httpRequest', { method: 'GET', url: 'https://api.example.com', authentication: 'basicAuth', }, { httpBasicAuth: 'my-auth-credential', } ); expect(result.valid).toBe(true); expect(result.errors).toHaveLength(0); }); it('should catch both parameter and credential errors', () => { const result = validateFullNodeConfig( 'n8n-nodes-base.httpRequest', { method: 'INVALID_METHOD', // missing required url }, {} // missing credentials if required ); expect(result.valid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); // Should have parameter validation errors const paramErrors = result.errors.filter(e => e.code === 'INVALID_ENUM' || e.code === 'MISSING_REQUIRED'); expect(paramErrors.length).toBeGreaterThan(0); }); }); describe('Edge Cases', () => { it('should handle empty parameters object', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', {}); expect(result.valid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); }); it('should handle null and undefined values', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', { method: null, url: undefined, authentication: 'none', }); expect(result.valid).toBe(false); expect(result.errors.length).toBeGreaterThan(0); }); it('should handle boolean type validation', () => { const result = validateNodeConfig('n8n-nodes-base.httpRequest', { method: 'POST', url: 'https://api.example.com', sendBody: 'true', // should be boolean }); expect(result.valid).toBe(false); const boolError = result.errors.find(e => e.property === 'sendBody'); expect(boolError?.code).toBe('INVALID_TYPE'); expect(boolError?.expected).toBe('boolean'); }); }); });

Latest Blog Posts

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/get2knowio/n8n-mcp'

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