Skip to main content
Glama

Cut-Copy-Paste Clipboard Server

database.test.ts•5.18 kB
import { DatabaseManager } from '../database.js'; import { existsSync, rmSync, statSync } from 'fs'; import { join, dirname } from 'path'; import { tmpdir } from 'os'; describe('DatabaseManager', () => { let dbPath: string; let dbManager: DatabaseManager; beforeEach(() => { // Create a unique temp database in a subdirectory for each test // This ensures DatabaseManager creates the directory with secure permissions const testDir = join(tmpdir(), `mcp-test-${Date.now()}`); dbPath = join(testDir, 'clipboard.db'); }); afterEach(() => { if (dbManager) { dbManager.close(); } // Clean up test directory and all contents (database + key file) const testDir = dirname(dbPath); if (existsSync(testDir)) { rmSync(testDir, { recursive: true, force: true }); } }); describe('initialization', () => { it('should create database file at specified path', () => { dbManager = new DatabaseManager(dbPath); expect(existsSync(dbPath)).toBe(true); const keyPath = dbManager.getEncryptionKeyPath(); expect(keyPath).toBeTruthy(); if (keyPath) { expect(existsSync(keyPath)).toBe(true); } }); it('should create all required tables', () => { dbManager = new DatabaseManager(dbPath); const db = dbManager.getConnection(); const tables = db .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'`) .all() as { name: string }[]; const tableNames = tables.map((t) => t.name); expect(tableNames).toContain('sessions'); expect(tableNames).toContain('clipboard_buffer'); expect(tableNames).toContain('operations_log'); expect(tableNames).toContain('paste_history'); }); it('should enable foreign key constraints', () => { dbManager = new DatabaseManager(dbPath); const db = dbManager.getConnection(); const result = db.prepare('PRAGMA foreign_keys').get() as { foreign_keys: number }; expect(result.foreign_keys).toBe(1); }); it('should create required indexes', () => { dbManager = new DatabaseManager(dbPath); const db = dbManager.getConnection(); const indexes = db .prepare(`SELECT name FROM sqlite_master WHERE type='index' AND name LIKE 'idx_%'`) .all() as { name: string }[]; const indexNames = indexes.map((i) => i.name); expect(indexNames).toContain('idx_sessions_last_activity'); expect(indexNames).toContain('idx_operations_log_session'); expect(indexNames).toContain('idx_paste_history_session'); expect(indexNames).toContain('idx_paste_history_undone'); }); it('should enforce secure filesystem permissions', () => { dbManager = new DatabaseManager(dbPath); if (process.platform !== 'win32') { const dirMode = statSync(dirname(dbPath)).mode & 0o777; const dbMode = statSync(dbPath).mode & 0o777; expect(dirMode).toBe(0o700); expect(dbMode).toBe(0o600); const keyPath = dbManager.getEncryptionKeyPath(); if (keyPath) { const keyMode = statSync(keyPath).mode & 0o777; expect(keyMode).toBe(0o600); } } }); }); describe('transactions', () => { beforeEach(() => { dbManager = new DatabaseManager(dbPath); }); it('should commit successful transactions', () => { const db = dbManager.getConnection(); const timestamp = Date.now(); dbManager.transaction(() => { db.prepare( `INSERT INTO sessions (session_id, created_at, last_activity) VALUES (?, ?, ?)` ).run('test-session', timestamp, timestamp); }); const session = db.prepare('SELECT * FROM sessions WHERE session_id = ?').get('test-session'); expect(session).toBeDefined(); }); it('should rollback failed transactions', () => { const db = dbManager.getConnection(); const timestamp = Date.now(); try { dbManager.transaction(() => { db.prepare( `INSERT INTO sessions (session_id, created_at, last_activity) VALUES (?, ?, ?)` ).run('test-session', timestamp, timestamp); throw new Error('Test error'); }); } catch (error) { // Expected error } const session = db.prepare('SELECT * FROM sessions WHERE session_id = ?').get('test-session'); expect(session).toBeUndefined(); }); }); describe('connection management', () => { it('should provide access to underlying database connection', () => { dbManager = new DatabaseManager(dbPath); const db = dbManager.getConnection(); expect(db).toBeDefined(); expect(typeof db.prepare).toBe('function'); }); it('should close database connection', () => { dbManager = new DatabaseManager(dbPath); expect(() => dbManager.close()).not.toThrow(); }); it('should expose 32-byte encryption key', () => { dbManager = new DatabaseManager(dbPath); const key = dbManager.getEncryptionKey(); expect(key).toBeInstanceOf(Buffer); expect(key.length).toBe(32); }); }); });

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/Pr0j3c7t0dd-Ltd/cut-copy-paste-mcp'

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