Skip to main content
Glama

n8n-MCP

by 88-888
resource-similarity-service.test.ts8 kB
/** * Tests for ResourceSimilarityService */ import { describe, it, expect, beforeEach } from 'vitest'; import { ResourceSimilarityService } from '../../../src/services/resource-similarity-service'; import { NodeRepository } from '../../../src/database/node-repository'; import { createTestDatabase } from '../../utils/database-utils'; describe('ResourceSimilarityService', () => { let service: ResourceSimilarityService; let repository: NodeRepository; let testDb: any; beforeEach(async () => { testDb = await createTestDatabase(); repository = testDb.nodeRepository; service = new ResourceSimilarityService(repository); // Add test node with resources const testNode = { nodeType: 'nodes-base.googleDrive', packageName: 'n8n-nodes-base', displayName: 'Google Drive', description: 'Access Google Drive', category: 'transform', style: 'declarative' as const, isAITool: false, isTrigger: false, isWebhook: false, isVersioned: true, version: '1', properties: [ { name: 'resource', type: 'options', options: [ { value: 'file', name: 'File' }, { value: 'folder', name: 'Folder' }, { value: 'drive', name: 'Shared Drive' }, { value: 'fileFolder', name: 'File & Folder' } ] } ], operations: [], credentials: [] }; repository.saveNode(testNode); // Add Slack node for testing different patterns const slackNode = { nodeType: 'nodes-base.slack', packageName: 'n8n-nodes-base', displayName: 'Slack', description: 'Send messages to Slack', category: 'communication', style: 'declarative' as const, isAITool: false, isTrigger: false, isWebhook: false, isVersioned: true, version: '2', properties: [ { name: 'resource', type: 'options', options: [ { value: 'channel', name: 'Channel' }, { value: 'message', name: 'Message' }, { value: 'user', name: 'User' }, { value: 'file', name: 'File' }, { value: 'star', name: 'Star' } ] } ], operations: [], credentials: [] }; repository.saveNode(slackNode); }); afterEach(async () => { if (testDb) { await testDb.cleanup(); } }); describe('findSimilarResources', () => { it('should find exact match', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'file', 5 ); expect(suggestions).toHaveLength(0); // No suggestions for valid resource }); it('should suggest singular form for plural input', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'files', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('file'); expect(suggestions[0].confidence).toBeGreaterThanOrEqual(0.9); expect(suggestions[0].reason).toContain('singular'); }); it('should suggest singular form for folders', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'folders', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('folder'); expect(suggestions[0].confidence).toBeGreaterThanOrEqual(0.9); }); it('should handle typos with Levenshtein distance', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'flie', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('file'); expect(suggestions[0].confidence).toBeGreaterThan(0.7); }); it('should handle combined resources', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'fileAndFolder', 5 ); expect(suggestions.length).toBeGreaterThan(0); // Should suggest 'fileFolder' (the actual combined resource) const fileFolderSuggestion = suggestions.find(s => s.value === 'fileFolder'); expect(fileFolderSuggestion).toBeDefined(); }); it('should return empty array for node not found', () => { const suggestions = service.findSimilarResources( 'nodes-base.nonexistent', 'resource', 5 ); expect(suggestions).toEqual([]); }); }); describe('plural/singular detection', () => { it('should handle regular plurals (s)', () => { const suggestions = service.findSimilarResources( 'nodes-base.slack', 'channels', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('channel'); }); it('should handle plural ending in es', () => { const suggestions = service.findSimilarResources( 'nodes-base.slack', 'messages', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('message'); }); it('should handle plural ending in ies', () => { // Test with a hypothetical 'entities' -> 'entity' conversion const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'entities', 5 ); // Should not crash and provide some suggestions expect(suggestions).toBeDefined(); }); }); describe('node-specific patterns', () => { it('should apply Google Drive specific patterns', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'sharedDrives', 5 ); expect(suggestions.length).toBeGreaterThan(0); const driveSuggestion = suggestions.find(s => s.value === 'drive'); expect(driveSuggestion).toBeDefined(); }); it('should apply Slack specific patterns', () => { const suggestions = service.findSimilarResources( 'nodes-base.slack', 'users', 5 ); expect(suggestions.length).toBeGreaterThan(0); expect(suggestions[0].value).toBe('user'); }); }); describe('similarity calculation', () => { it('should rank exact matches highest', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'file', 5 ); expect(suggestions).toHaveLength(0); // Exact match, no suggestions }); it('should rank substring matches high', () => { const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'fil', 5 ); expect(suggestions.length).toBeGreaterThan(0); const fileSuggestion = suggestions.find(s => s.value === 'file'); expect(fileSuggestion).toBeDefined(); expect(fileSuggestion!.confidence).toBeGreaterThanOrEqual(0.7); }); }); describe('caching', () => { it('should cache results for repeated queries', () => { // First call const suggestions1 = service.findSimilarResources( 'nodes-base.googleDrive', 'files', 5 ); // Second call with same params const suggestions2 = service.findSimilarResources( 'nodes-base.googleDrive', 'files', 5 ); expect(suggestions1).toEqual(suggestions2); }); it('should clear cache when requested', () => { // Add to cache service.findSimilarResources( 'nodes-base.googleDrive', 'test', 5 ); // Clear cache service.clearCache(); // This would fetch fresh data (behavior is the same, just uncached) const suggestions = service.findSimilarResources( 'nodes-base.googleDrive', 'test', 5 ); expect(suggestions).toBeDefined(); }); }); });

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