Skip to main content
Glama

NervusDB MCP Server

Official
by nervusdb
queryExecutor.spec.ts4.94 kB
import { describe, it, expect, vi } from 'vitest'; import { QueryExecutor } from '../../../src/domain/query/queryExecutor.js'; import { ValidationError } from '../../../src/domain/shared/errors.js'; describe('QueryExecutor', () => { const mockDb = { find: vi.fn(), close: vi.fn(), cypher: vi.fn(), }; describe('execute', () => { it('should execute typed query successfully', async () => { const executor = new QueryExecutor(); const mockResults = [ { subject: 'project:test', predicate: 'CONTAINS', object: 'file:test.ts' }, { subject: 'project:test', predicate: 'CONTAINS', object: 'file:test2.ts' }, ]; mockDb.find.mockReturnValue({ all: vi.fn().mockResolvedValue(mockResults) }); const query = { type: 'typed' as const, filter: { predicate: 'CONTAINS' }, options: { limit: 10, offset: 0 }, }; const result = await executor.execute(mockDb as any, query); expect(result.facts).toHaveLength(2); expect(result.count).toBe(2); expect(result.hasMore).toBe(false); expect(mockDb.find).toHaveBeenCalledWith({ predicate: 'CONTAINS' }); }); it('should handle pagination correctly', async () => { const executor = new QueryExecutor(); const mockResults = Array.from({ length: 15 }, (_, i) => ({ subject: 'project:test', predicate: 'CONTAINS', object: `file:test${i}.ts`, })); mockDb.find.mockReturnValue({ all: vi.fn().mockResolvedValue(mockResults) }); const query = { type: 'typed' as const, filter: { predicate: 'CONTAINS' }, options: { limit: 10, offset: 0 }, }; const result = await executor.execute(mockDb as any, query); expect(result.facts).toHaveLength(10); expect(result.hasMore).toBe(true); }); it('should apply offset correctly', async () => { const executor = new QueryExecutor(); const mockResults = Array.from({ length: 15 }, (_, i) => ({ subject: 'project:test', predicate: 'CONTAINS', object: `file:test${i}.ts`, })); mockDb.find.mockReturnValue({ all: vi.fn().mockResolvedValue(mockResults) }); const query = { type: 'typed' as const, filter: { predicate: 'CONTAINS' }, options: { limit: 5, offset: 10 }, }; const result = await executor.execute(mockDb as any, query); expect(result.facts).toHaveLength(5); expect(result.facts[0].object).toBe('file:test10.ts'); expect(result.hasMore).toBe(false); }); it('should throw ValidationError for empty filter', async () => { const executor = new QueryExecutor(); const query = { type: 'typed' as const, filter: {}, }; await expect(executor.execute(mockDb as any, query)).rejects.toThrow(ValidationError); }); it('should execute raw Cypher queries successfully', async () => { const executor = new QueryExecutor(); const mockCypherResult = { records: [ { subject: 'file:test.ts', predicate: 'DEFINES', object: 'function:test' }, { subject: 'file:test2.ts', predicate: 'DEFINES', object: 'function:test2' }, ], summary: { statement: 'MATCH (s)-[r:DEFINES]->(o) RETURN s, r, o', parameters: {}, resultAvailableAfter: 5, resultConsumedAfter: 10, statementType: 'READ_ONLY' as const, }, }; mockDb.cypher.mockResolvedValue(mockCypherResult); const query = { type: 'raw' as const, cypher: 'MATCH (s)-[r:DEFINES]->(o) RETURN s, r, o', }; const result = await executor.execute(mockDb as any, query); expect(result.facts).toHaveLength(2); expect(result.count).toBe(2); expect(result.hasMore).toBe(false); expect(mockDb.cypher).toHaveBeenCalledWith( 'MATCH (s)-[r:DEFINES]->(o) RETURN s, r, o', {}, { readonly: true }, ); }); it('should include object properties in results', async () => { const executor = new QueryExecutor(); const mockResults = [ { subject: 'project:test', predicate: 'CONTAINS', object: 'file:test.ts', objectProperties: { path: 'src/test.ts', length: 100 }, }, ]; mockDb.find.mockReturnValue({ all: vi.fn().mockResolvedValue(mockResults) }); const query = { type: 'typed' as const, filter: { predicate: 'CONTAINS' }, }; const result = await executor.execute(mockDb as any, query); expect(result.facts[0].properties).toEqual({ path: 'src/test.ts', length: 100 }); }); it('should throw on invalid request format', async () => { const executor = new QueryExecutor(); await expect(executor.execute(mockDb as any, { invalid: 'query' })).rejects.toThrow(); }); }); });

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/nervusdb/nervusdb-mcp'

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