Skip to main content
Glama

1MCP Server

streamableSessionRepository.test.ts12.4 kB
import { AUTH_CONFIG } from '@src/constants.js'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { StreamableSessionRepository } from './streamableSessionRepository.js'; // Mock FileStorageService const mockFileStorageService = { writeData: vi.fn(), readData: vi.fn(), deleteData: vi.fn(), }; describe('StreamableSessionRepository', () => { let repository: StreamableSessionRepository; beforeEach(() => { vi.resetAllMocks(); repository = new StreamableSessionRepository(mockFileStorageService as any); }); describe('create', () => { it('should create a new streamable session with config', () => { // Arrange const sessionId = 'stream-test-session-id'; const config = { tags: ['filesystem', 'network'], tagFilterMode: 'simple-or' as const, enablePagination: true, presetName: 'test-preset', }; // Act repository.create(sessionId, config); // Assert expect(mockFileStorageService.writeData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, expect.objectContaining({ tags: ['filesystem', 'network'], tagFilterMode: 'simple-or', enablePagination: true, presetName: 'test-preset', expires: expect.any(Number), createdAt: expect.any(Number), lastAccessedAt: expect.any(Number), }), ); }); it('should serialize complex objects to JSON strings', () => { // Arrange const sessionId = 'stream-test-session-id'; const tagExpression = { type: 'or' as const, children: [] }; const tagQuery = { tags: ['test'] }; const config = { tagExpression, tagQuery, }; // Act repository.create(sessionId, config); // Assert expect(mockFileStorageService.writeData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, expect.objectContaining({ tagExpression: JSON.stringify(tagExpression), tagQuery: JSON.stringify(tagQuery), }), ); }); it('should set TTL for session expiration', () => { // Arrange const sessionId = 'stream-test-session-id'; const config = { tags: ['test'] }; const now = Date.now(); // Act repository.create(sessionId, config); // Assert const callArgs = mockFileStorageService.writeData.mock.calls[0][2]; expect(callArgs.expires).toBeGreaterThanOrEqual(now + AUTH_CONFIG.SERVER.STREAMABLE_SESSION.TTL_MS); expect(callArgs.createdAt).toBeGreaterThanOrEqual(now); expect(callArgs.lastAccessedAt).toBeGreaterThanOrEqual(now); }); }); describe('get', () => { it('should retrieve and parse session configuration', () => { // Arrange const sessionId = 'stream-test-session-id'; const storedData = { tags: ['filesystem'], tagExpression: JSON.stringify({ type: 'or', children: [] }), tagQuery: JSON.stringify({ tags: ['test'] }), tagFilterMode: 'simple-or' as const, enablePagination: true, presetName: 'test-preset', customTemplate: 'custom', expires: Date.now() + 1000, createdAt: Date.now(), lastAccessedAt: Date.now(), }; mockFileStorageService.readData.mockReturnValue(storedData); // Act const result = repository.get(sessionId); // Assert expect(mockFileStorageService.readData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, ); expect(result).toEqual({ tags: ['filesystem'], tagExpression: { type: 'or', children: [] }, tagQuery: { tags: ['test'] }, tagFilterMode: 'simple-or', enablePagination: true, presetName: 'test-preset', customTemplate: 'custom', }); }); it('should return null when session not found', () => { // Arrange const sessionId = 'non-existent-session'; mockFileStorageService.readData.mockReturnValue(null); // Act const result = repository.get(sessionId); // Assert expect(result).toBeNull(); }); it('should handle undefined optional fields', () => { // Arrange const sessionId = 'stream-test-session-id'; const storedData = { expires: Date.now() + 1000, createdAt: Date.now(), lastAccessedAt: Date.now(), }; mockFileStorageService.readData.mockReturnValue(storedData); // Act const result = repository.get(sessionId); // Assert expect(result).toEqual({ tags: undefined, tagExpression: undefined, tagQuery: undefined, tagFilterMode: undefined, enablePagination: undefined, presetName: undefined, customTemplate: undefined, }); }); }); describe('updateAccess', () => { it('should update lastAccessedAt and extend expiration', () => { // Arrange const sessionId = 'stream-test-session-id'; const now = Date.now(); const storedData = { tags: ['test'], expires: now + 1000, createdAt: now - 10000, lastAccessedAt: now - 5000, }; mockFileStorageService.readData.mockReturnValue(storedData); // Act repository.updateAccess(sessionId); // Assert expect(mockFileStorageService.readData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, ); expect(mockFileStorageService.writeData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, expect.objectContaining({ lastAccessedAt: expect.any(Number), expires: expect.any(Number), }), ); const updatedData = mockFileStorageService.writeData.mock.calls[0][2]; expect(updatedData.lastAccessedAt).toBeGreaterThanOrEqual(now); expect(updatedData.expires).toBeGreaterThanOrEqual(now + AUTH_CONFIG.SERVER.STREAMABLE_SESSION.TTL_MS); }); it('should not update if session does not exist', () => { // Arrange const sessionId = 'non-existent-session'; mockFileStorageService.readData.mockReturnValue(null); // Act repository.updateAccess(sessionId); // Assert expect(mockFileStorageService.readData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, ); expect(mockFileStorageService.writeData).not.toHaveBeenCalled(); }); }); describe('delete', () => { it('should delete session by ID', () => { // Arrange const sessionId = 'stream-test-session-id'; mockFileStorageService.deleteData.mockReturnValue(true); // Act const result = repository.delete(sessionId); // Assert expect(mockFileStorageService.deleteData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, ); expect(result).toBe(true); }); it('should return false if session does not exist', () => { // Arrange const sessionId = 'non-existent-session'; mockFileStorageService.deleteData.mockReturnValue(false); // Act const result = repository.delete(sessionId); // Assert expect(result).toBe(false); }); }); describe('updateAccessThrottled', () => { const sessionId = 'stream-test-session-id'; const now = Date.now(); const storedData = { tags: ['test'], expires: now + 1000, createdAt: now - 10000, lastAccessedAt: now - 5000, }; beforeEach(() => { mockFileStorageService.readData.mockReturnValue(storedData); vi.clearAllMocks(); }); it('should persist after reaching request threshold', () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; // Act - trigger exactly the request threshold for (let i = 0; i < policy.REQUESTS; i++) { repository.updateAccess(sessionId); } // Assert - should have persisted once expect(mockFileStorageService.writeData).toHaveBeenCalledTimes(1); expect(mockFileStorageService.writeData).toHaveBeenCalledWith( AUTH_CONFIG.SERVER.STREAMABLE_SESSION.FILE_PREFIX, sessionId, expect.objectContaining({ lastAccessedAt: expect.any(Number), expires: expect.any(Number), }), ); }); it('should persist after reaching time threshold', async () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; let mockTime = now; vi.spyOn(Date, 'now').mockImplementation(() => mockTime); // Act - single request, then advance time past threshold repository.updateAccess(sessionId); // Clear the mock to track only the second call mockFileStorageService.writeData.mockClear(); mockTime = now + policy.INTERVAL_MS + 1000; // Past threshold repository.updateAccess(sessionId); // Assert - should have persisted due to time threshold expect(mockFileStorageService.writeData).toHaveBeenCalledTimes(1); // Cleanup vi.spyOn(Date, 'now').mockRestore(); }); it('should use whichever trigger fires first', () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; let mockTime = now; vi.spyOn(Date, 'now').mockImplementation(() => mockTime); // Act - advance time past threshold, then make requests mockTime = now + policy.INTERVAL_MS + 1000; repository.updateAccess(sessionId); // Assert - should have persisted due to time threshold (not waiting for request threshold) expect(mockFileStorageService.writeData).toHaveBeenCalledTimes(1); // Cleanup vi.spyOn(Date, 'now').mockRestore(); }); it('should reset counters after persistence', () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; // Act - trigger persistence, then make more requests for (let i = 0; i < policy.REQUESTS; i++) { repository.updateAccess(sessionId); } // Reset mock to track new calls mockFileStorageService.writeData.mockClear(); // Make more requests (should not persist yet) for (let i = 0; i < policy.REQUESTS - 1; i++) { repository.updateAccess(sessionId); } // Assert - should not have persisted again yet expect(mockFileStorageService.writeData).not.toHaveBeenCalled(); }); it('should always update in-memory timestamps regardless of persistence', () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; // Act - make requests below threshold for (let i = 0; i < policy.REQUESTS - 1; i++) { repository.updateAccess(sessionId); } // Assert - should not have persisted but in-memory state should be updated expect(mockFileStorageService.writeData).not.toHaveBeenCalled(); // Note: We can't directly test private state, but the behavior is verified // by the fact that the next request will trigger persistence }); it('should handle concurrent updates to same session', () => { // Arrange const policy = AUTH_CONFIG.SERVER.STREAMABLE_SESSION.SAVE_POLICY; // Act - simulate concurrent updates const promises = []; for (let i = 0; i < policy.REQUESTS; i++) { promises.push(Promise.resolve(repository.updateAccess(sessionId))); } Promise.all(promises); // Assert - should have persisted once (not multiple times) expect(mockFileStorageService.writeData).toHaveBeenCalledTimes(1); }); it('should not persist if session does not exist', () => { // Arrange mockFileStorageService.readData.mockReturnValue(null); // Act repository.updateAccess(sessionId); // Assert - should not have persisted expect(mockFileStorageService.writeData).not.toHaveBeenCalled(); }); }); describe('stopPeriodicFlush', () => { it('should stop periodic flush without errors', () => { // Act & Assert - should not throw expect(() => repository.stopPeriodicFlush()).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/1mcp-app/agent'

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