mcp-memory-libsql

by spences10
Verified
import { AttachmentIndexService } from '../../../modules/attachments/index-service.js'; import { AttachmentCleanupService } from '../../../modules/attachments/cleanup-service.js'; import { AttachmentResponseTransformer } from '../../../modules/attachments/response-transformer.js'; describe('Attachment System', () => { let indexService: AttachmentIndexService; let cleanupService: AttachmentCleanupService; let responseTransformer: AttachmentResponseTransformer; beforeEach(() => { // Reset singleton instance for test isolation // @ts-expect-error - Accessing private static for testing AttachmentIndexService.instance = undefined; indexService = AttachmentIndexService.getInstance(); cleanupService = new AttachmentCleanupService(indexService); responseTransformer = new AttachmentResponseTransformer(indexService); }); afterEach(() => { cleanupService.stop(); jest.clearAllTimers(); }); describe('AttachmentIndexService', () => { it('should store and retrieve attachment metadata', () => { const messageId = 'msg123'; const attachment = { id: 'att123', name: 'test.pdf', mimeType: 'application/pdf', size: 1024 }; indexService.addAttachment(messageId, attachment); const metadata = indexService.getMetadata(messageId, 'test.pdf'); expect(metadata).toBeDefined(); expect(metadata?.originalId).toBe('att123'); expect(metadata?.filename).toBe('test.pdf'); expect(metadata?.mimeType).toBe('application/pdf'); expect(metadata?.size).toBe(1024); }); it('should handle size limits', () => { // Add max entries + 1 for (let i = 0; i < 257; i++) { indexService.addAttachment(`msg${i}`, { id: `att${i}`, name: 'test.pdf', mimeType: 'application/pdf', size: 1024 }); } // Size should be maintained at or below max expect(indexService.size).toBeLessThanOrEqual(256); }); it('should handle expiry', () => { const messageId = 'msg123'; const attachment = { id: 'att123', name: 'test.pdf', mimeType: 'application/pdf', size: 1024 }; // Add attachment indexService.addAttachment(messageId, attachment); // Mock time passing jest.useFakeTimers(); jest.advanceTimersByTime(3600000 + 1000); // 1 hour + 1 second // Attempt to retrieve expired attachment const metadata = indexService.getMetadata(messageId, 'test.pdf'); expect(metadata).toBeUndefined(); jest.useRealTimers(); }); }); describe('AttachmentCleanupService', () => { it('should start and stop cleanup service', () => { cleanupService.start(); expect(cleanupService.getCurrentInterval()).toBe(300000); // Base interval cleanupService.stop(); expect(cleanupService.getCurrentInterval()).toBe(300000); }); }); describe('AttachmentResponseTransformer', () => { it('should transform attachments to simplified format', () => { const messageId = 'msg123'; const fullResponse = { id: messageId, attachments: [{ id: 'att123', name: 'test.pdf', mimeType: 'application/pdf', size: 1024 }] }; // Store attachment metadata indexService.addAttachment(messageId, fullResponse.attachments[0]); // Transform response const simplified = responseTransformer.transformResponse(fullResponse); expect(simplified).toEqual({ id: messageId, attachments: [{ name: 'test.pdf' }] }); }); it('should handle responses without attachments', () => { const response = { id: 'msg123', subject: 'Test' }; const simplified = responseTransformer.transformResponse(response); expect(simplified).toEqual(response); }); }); describe('Integration', () => { it('should maintain attachment metadata through transform cycle', () => { const messageId = 'msg123'; const originalAttachment = { id: 'att123', name: 'test.pdf', mimeType: 'application/pdf', size: 1024 }; // Add attachment and transform response indexService.addAttachment(messageId, originalAttachment); const transformed = responseTransformer.transformResponse({ id: messageId, attachments: [originalAttachment] }); // Verify simplified format expect(transformed.attachments?.[0]).toEqual({ name: 'test.pdf' }); // Verify original metadata is preserved const metadata = indexService.getMetadata(messageId, 'test.pdf'); expect(metadata).toEqual({ messageId, filename: 'test.pdf', originalId: 'att123', mimeType: 'application/pdf', size: 1024, timestamp: expect.any(Number) }); }); it('should notify activity without error', () => { cleanupService.start(); cleanupService.notifyActivity(); // Should not throw cleanupService.stop(); }); }); });