Skip to main content
Glama
clean-database-manager-enhanced.test.ts6.75 kB
/** * Database Manager Coverage Tests * Target: Increase coverage from 51.61% to 80%+ * Focus: Database switching, schema validation, error recovery * Lines: 95-109, 112-125 in clean-database-manager.ts */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { CleanDatabaseManager } from '../../../src/infrastructure/database/clean-database-manager'; import { Neo4jDriverManager } from '../../../src/infrastructure/database/neo4j-driver'; import { SessionFactory } from '../../../src/infrastructure/database/session-factory'; import { IndexManager } from '../../../src/infrastructure/database/index-manager'; // Mock dependencies vi.mock('../../../src/infrastructure/database/neo4j-driver'); vi.mock('../../../src/infrastructure/database/session-factory'); vi.mock('../../../src/infrastructure/database/index-manager'); describe('CleanDatabaseManager - Enhanced Coverage', () => { let databaseManager: CleanDatabaseManager; let mockDriverManager: any; let mockSessionFactory: any; let mockSession: any; let mockIndexManager: any; beforeEach(() => { // Reset mocks vi.clearAllMocks(); // Setup mock session mockSession = { run: vi.fn(), close: vi.fn().mockResolvedValue(undefined) }; // Setup mock driver manager mockDriverManager = { getCurrentDatabase: vi.fn().mockReturnValue({ database: 'test-db' }), switchDatabase: vi.fn(), close: vi.fn().mockResolvedValue(undefined) }; // Setup mock session factory mockSessionFactory = { createSession: vi.fn().mockReturnValue(mockSession), createSystemSession: vi.fn().mockReturnValue(mockSession) }; // Setup mock index manager mockIndexManager = { hasRequiredSchema: vi.fn().mockResolvedValue(true), initializeSchema: vi.fn().mockResolvedValue(undefined) }; (Neo4jDriverManager as any).mockImplementation(() => mockDriverManager); (SessionFactory as any).mockImplementation(() => mockSessionFactory); (IndexManager as any).mockImplementation(() => mockIndexManager); databaseManager = new CleanDatabaseManager(mockDriverManager, mockSessionFactory); }); afterEach(async () => { await databaseManager.close(); }); describe('Database Existence Validation', () => { it('should detect existing database correctly', async () => { // Mock SHOW DATABASES query returning results mockSession.run = vi.fn().mockResolvedValue({ records: [{ get: vi.fn().mockReturnValue('existing-db') }] }); const result = await databaseManager.switchDatabase('existing-db'); expect(result.currentDatabase).toBe('existing-db'); expect(result.created).toBe(false); expect(mockSession.run).toHaveBeenCalledWith( 'SHOW DATABASES YIELD name WHERE name = $name', { name: 'existing-db' } ); }); it('should handle SHOW DATABASES query failure gracefully', async () => { // Mock SHOW DATABASES query throwing error (older Neo4j versions) mockSession.run = vi.fn().mockRejectedValue(new Error('SHOW DATABASES not supported')); // Should assume database exists and continue const result = await databaseManager.switchDatabase('assumed-existing'); expect(result.currentDatabase).toBe('assumed-existing'); }); }); describe('Database Creation Logic', () => { it('should create new database when it does not exist', async () => { // Mock database doesn't exist mockSession.run = vi.fn() .mockResolvedValueOnce({ records: [] }) // SHOW DATABASES returns empty .mockResolvedValueOnce({}); // CREATE DATABASE succeeds const result = await databaseManager.switchDatabase('new-db'); expect(result.created).toBe(true); expect(result.currentDatabase).toBe('new-db'); expect(mockSession.run).toHaveBeenCalledWith( 'CREATE DATABASE $name IF NOT EXISTS', { name: 'new-db' } ); }); it('should handle database creation failure gracefully', async () => { mockSession.run = vi.fn() .mockResolvedValueOnce({ records: [] }) // Database doesn't exist .mockRejectedValueOnce(new Error('Permission denied')); // CREATE fails // Should continue despite creation failure const result = await databaseManager.switchDatabase('failed-create'); expect(result.currentDatabase).toBe('failed-create'); expect(result.created).toBe(true); // Still reports created attempt }); }); describe('Database Name Validation', () => { it('should normalize questionable database names', async () => { const problematicNames = [ { input: 'invalid@name', expected: 'invalidname' }, // @ gets removed { input: 'invalid name', expected: 'invalid-name' }, // space becomes hyphen { input: 'UPPERCASE', expected: 'uppercase' }, // normalized to lowercase ]; for (const { input, expected } of problematicNames) { const result = await databaseManager.switchDatabase(input); expect(result.currentDatabase).toBe(expected); expect(result.previousDatabase).toBe('test-db'); expect(typeof result.created).toBe('boolean'); } }); it('should accept valid database names', async () => { const validNames = [ 'lowercase', 'with-hyphens', 'with_underscores', 'with.dots', 'mixed123numbers' ]; // Mock existing databases mockSession.run = vi.fn().mockResolvedValue({ records: [{}] // Database exists }); for (const validName of validNames) { await expect(databaseManager.switchDatabase(validName)) .resolves.not.toThrow(); } }); }); describe('Same Database Optimization', () => { it('should optimize when switching to same database', async () => { mockDriverManager.getCurrentDatabase = vi.fn().mockReturnValue({ database: 'current-db' }); mockIndexManager.hasRequiredSchema = vi.fn().mockResolvedValue(true); const result = await databaseManager.switchDatabase('current-db'); expect(result.previousDatabase).toBe('current-db'); expect(result.currentDatabase).toBe('current-db'); expect(result.created).toBe(false); }); }); describe('getCurrentDatabase Method', () => { it('should return current database from driver manager', () => { mockDriverManager.getCurrentDatabase = vi.fn().mockReturnValue({ database: 'current-test-db' }); const result = databaseManager.getCurrentDatabase(); expect(result.database).toBe('current-test-db'); expect(mockDriverManager.getCurrentDatabase).toHaveBeenCalled(); }); }); });

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/sylweriusz/mcp-neo4j-memory-server'

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