Skip to main content
Glama

Cut-Copy-Paste Clipboard Server

clipboard-manager.test.ts•10.4 kB
import { ClipboardManager } from '../clipboard-manager.js'; import { DatabaseManager } from '../database.js'; import { existsSync, rmSync } from 'fs'; import { join } from 'path'; import { tmpdir } from 'os'; describe('ClipboardManager', () => { let dbPath: string; let dbManager: DatabaseManager; let clipboardManager: ClipboardManager; beforeEach(() => { const uniqueId = `${Date.now()}-${process.pid}-${Math.random().toString(36).slice(2, 9)}`; dbPath = join(tmpdir(), `test-clipboard-${uniqueId}.db`); dbManager = new DatabaseManager(dbPath); clipboardManager = new ClipboardManager(dbManager); // Create a test session const db = dbManager.getConnection(); const timestamp = Date.now(); db.prepare('INSERT INTO sessions (session_id, created_at, last_activity) VALUES (?, ?, ?)').run( 'test-session-1', timestamp, timestamp ); }); afterEach(() => { if (dbManager) { dbManager.close(); const keyPath = dbManager.getEncryptionKeyPath(); if (keyPath && existsSync(keyPath)) { rmSync(keyPath); } } if (existsSync(dbPath)) { rmSync(dbPath); } }); describe('Store Clipboard Content - RED', () => { it('should store encrypted content for session', () => { clipboardManager.setClipboard('test-session-1', { content: 'line 1\nline 2\nline 3', sourceFile: '/path/to/file.ts', startLine: 5, endLine: 7, operationType: 'copy', }); const db = dbManager.getConnection(); const clipboard = db .prepare('SELECT * FROM clipboard_buffer WHERE session_id = ?') .get('test-session-1') as any; expect(clipboard).toBeDefined(); expect(clipboard.content).toBe('[encrypted]'); expect(clipboard.encrypted_payload).toBeDefined(); expect(clipboard.encryption_iv).toBeDefined(); expect(clipboard.encryption_tag).toBeDefined(); }); it('should include source metadata', () => { clipboardManager.setClipboard('test-session-1', { content: 'test content', sourceFile: '/path/to/source.ts', startLine: 10, endLine: 15, operationType: 'copy', }); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard?.startLine).toBe(10); expect(clipboard?.endLine).toBe(15); expect(clipboard?.sourceFile).toBe('/path/to/source.ts'); }); it('should overwrite previous clipboard', () => { clipboardManager.setClipboard('test-session-1', { content: 'first content', sourceFile: '/first.ts', startLine: 1, endLine: 1, operationType: 'copy', }); clipboardManager.setClipboard('test-session-1', { content: 'second content', sourceFile: '/second.ts', startLine: 2, endLine: 2, operationType: 'cut', }); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard?.content).toBe('second content'); expect(clipboard?.sourceFile).toBe('/second.ts'); expect(clipboard?.operationType).toBe('cut'); }); it('should distinguish copy vs cut', () => { clipboardManager.setClipboard('test-session-1', { content: 'test', sourceFile: '/test.ts', startLine: 1, endLine: 1, operationType: 'cut', }); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard?.operationType).toBe('cut'); }); it('should record timestamp', () => { const beforeSet = Date.now(); clipboardManager.setClipboard('test-session-1', { content: 'test', sourceFile: '/test.ts', startLine: 1, endLine: 1, operationType: 'copy', }); const afterSet = Date.now(); const db = dbManager.getConnection(); const clipboard = db .prepare('SELECT * FROM clipboard_buffer WHERE session_id = ?') .get('test-session-1') as any; expect(clipboard.copied_at).toBeGreaterThanOrEqual(beforeSet); expect(clipboard.copied_at).toBeLessThanOrEqual(afterSet); }); }); describe('Retrieve Clipboard Content - RED', () => { it('should retrieve clipboard for session', () => { const db = dbManager.getConnection(); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('test-session-1', 'retrieved content', '/source.ts', 5, 10, Date.now(), 'copy'); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard).toBeDefined(); expect(clipboard?.content).toBe('retrieved content'); expect(clipboard?.sourceFile).toBe('/source.ts'); expect(clipboard?.startLine).toBe(5); expect(clipboard?.endLine).toBe(10); }); it('should retrieve encrypted clipboard for session', () => { clipboardManager.setClipboard('test-session-1', { content: 'secret', sourceFile: '/secret.ts', startLine: 4, endLine: 8, operationType: 'copy', }); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard?.content).toBe('secret'); expect(clipboard?.sourceFile).toBe('/secret.ts'); expect(clipboard?.startLine).toBe(4); expect(clipboard?.endLine).toBe(8); }); it('should return null if clipboard empty', () => { const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard).toBeNull(); }); it('should include all metadata', () => { const db = dbManager.getConnection(); const copiedAt = Date.now(); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('test-session-1', 'content', '/file.ts', 1, 5, copiedAt, 'cut'); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard?.operationType).toBe('cut'); expect(clipboard?.copiedAt).toBe(copiedAt); }); it('should not return clipboard from other sessions', () => { const db = dbManager.getConnection(); const timestamp = Date.now(); db.prepare( 'INSERT INTO sessions (session_id, created_at, last_activity) VALUES (?, ?, ?)' ).run('other-session', timestamp, timestamp); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('other-session', 'other content', '/other.ts', 1, 1, Date.now(), 'copy'); const clipboard = clipboardManager.getClipboard('test-session-1'); expect(clipboard).toBeNull(); }); }); describe('Clear Clipboard - RED', () => { it('should clear clipboard for session', () => { const db = dbManager.getConnection(); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('test-session-1', 'content', '/file.ts', 1, 1, Date.now(), 'copy'); clipboardManager.clearClipboard('test-session-1'); const clipboard = db .prepare('SELECT * FROM clipboard_buffer WHERE session_id = ?') .get('test-session-1'); expect(clipboard).toBeUndefined(); }); it('should not affect other sessions', () => { const db = dbManager.getConnection(); const timestamp = Date.now(); db.prepare( 'INSERT INTO sessions (session_id, created_at, last_activity) VALUES (?, ?, ?)' ).run('other-session', timestamp, timestamp); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('test-session-1', 'content1', '/file1.ts', 1, 1, Date.now(), 'copy'); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('other-session', 'content2', '/file2.ts', 1, 1, Date.now(), 'copy'); clipboardManager.clearClipboard('test-session-1'); const otherClipboard = db .prepare('SELECT * FROM clipboard_buffer WHERE session_id = ?') .get('other-session'); expect(otherClipboard).toBeDefined(); }); it('should not error if clipboard already empty', () => { expect(() => { clipboardManager.clearClipboard('test-session-1'); }).not.toThrow(); }); }); describe('Has Content - RED', () => { it('should return true if clipboard has content', () => { const db = dbManager.getConnection(); db.prepare( `INSERT INTO clipboard_buffer (session_id, content, source_file, start_line, end_line, copied_at, operation_type) VALUES (?, ?, ?, ?, ?, ?, ?)` ).run('test-session-1', 'content', '/file.ts', 1, 1, Date.now(), 'copy'); expect(clipboardManager.hasContent('test-session-1')).toBe(true); }); it('should return false if clipboard is empty', () => { expect(clipboardManager.hasContent('test-session-1')).toBe(false); }); }); describe('Content Size Limit - RED', () => { it('should enforce maximum content size', () => { const largeContent = 'x'.repeat(11 * 1024 * 1024); // 11MB expect(() => { clipboardManager.setClipboard('test-session-1', { content: largeContent, sourceFile: '/file.ts', startLine: 1, endLine: 1000, operationType: 'copy', }); }).toThrow('exceeds maximum size'); }); it('should accept content under size limit', () => { const okContent = 'x'.repeat(5 * 1024 * 1024); // 5MB expect(() => { clipboardManager.setClipboard('test-session-1', { content: okContent, sourceFile: '/file.ts', startLine: 1, endLine: 1000, operationType: 'copy', }); }).not.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/Pr0j3c7t0dd-Ltd/cut-copy-paste-mcp'

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