Skip to main content
Glama

Context Continuation MCP Server

by core3-coder
session-tracker.test.ts6.97 kB
import { SessionTracker } from '../src/session-tracker'; import { SessionInfo } from '../src/types'; import { promises as fs } from 'fs'; import path from 'path'; import { tmpdir } from 'os'; // Mock fs module for testing jest.mock('fs', () => ({ promises: { mkdir: jest.fn(), writeFile: jest.fn(), readFile: jest.fn(), readdir: jest.fn(), access: jest.fn(), }, })); describe('SessionTracker', () => { let sessionTracker: SessionTracker; let mockProjectPath: string; const mockFs = fs as jest.Mocked<typeof fs>; beforeEach(() => { sessionTracker = new SessionTracker(); mockProjectPath = '/tmp/test-project'; jest.clearAllMocks(); }); afterEach(() => { jest.clearAllMocks(); }); describe('startSession', () => { it('should start a new session successfully', async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); const session = await sessionTracker.startSession(mockProjectPath, 'Test Session'); expect(session.id).toBeDefined(); expect(session.projectPath).toBe(mockProjectPath); expect(session.sessionName).toBe('Test Session'); expect(session.status).toBe('active'); expect(session.tokenCount).toBe(0); expect(session.messageCount).toBe(0); expect(session.startTime).toBeInstanceOf(Date); }); it('should throw error if session already active', async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath, 'First Session'); await expect(sessionTracker.startSession(mockProjectPath, 'Second Session')) .rejects.toThrow('Session already active'); }); it('should create context directory structure', async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath); expect(mockFs.mkdir).toHaveBeenCalledWith( path.join(mockProjectPath, '.context'), { recursive: true } ); expect(mockFs.mkdir).toHaveBeenCalledWith( path.join(mockProjectPath, '.context', 'sessions'), { recursive: true } ); expect(mockFs.mkdir).toHaveBeenCalledWith( path.join(mockProjectPath, '.context', 'progress'), { recursive: true } ); }); it('should create default config if not exists', async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath); const configPath = path.join(mockProjectPath, '.context', 'config.json'); expect(mockFs.writeFile).toHaveBeenCalledWith( configPath, expect.any(String) ); }); }); describe('endSession', () => { beforeEach(async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath, 'Test Session'); }); it('should end session successfully', async () => { await sessionTracker.endSession('Test summary'); const currentSession = sessionTracker.getCurrentSession(); expect(currentSession).toBeNull(); }); it('should throw error if no active session', async () => { await sessionTracker.endSession(); await expect(sessionTracker.endSession()) .rejects.toThrow('No active session to end'); }); it('should write session file when ending', async () => { await sessionTracker.endSession('Test summary'); expect(mockFs.writeFile).toHaveBeenCalledWith( expect.stringContaining('session_'), expect.stringContaining('Test summary'), 'utf8' ); }); }); describe('addMessage', () => { beforeEach(async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath, 'Test Session'); }); it('should add message to active session', () => { sessionTracker.addMessage('Test message', 'user', 10); const session = sessionTracker.getCurrentSession(); expect(session?.messageCount).toBe(1); expect(session?.tokenCount).toBe(10); }); it('should throw error if no active session', async () => { await sessionTracker.endSession(); expect(() => { sessionTracker.addMessage('Test message', 'user', 10); }).toThrow('No active session'); }); it('should accumulate tokens and message counts', () => { sessionTracker.addMessage('First message', 'user', 10); sessionTracker.addMessage('Second message', 'assistant', 15); const session = sessionTracker.getCurrentSession(); expect(session?.messageCount).toBe(2); expect(session?.tokenCount).toBe(25); }); }); describe('getCurrentSession', () => { it('should return null when no session active', () => { const session = sessionTracker.getCurrentSession(); expect(session).toBeNull(); }); it('should return current session when active', async () => { mockFs.mkdir.mockResolvedValue(undefined); mockFs.access.mockRejectedValue(new Error('File not found')); mockFs.writeFile.mockResolvedValue(undefined); await sessionTracker.startSession(mockProjectPath, 'Test Session'); const session = sessionTracker.getCurrentSession(); expect(session).not.toBeNull(); expect(session?.sessionName).toBe('Test Session'); }); }); describe('getSessions', () => { it('should return empty array when no sessions directory', async () => { mockFs.readdir.mockRejectedValue(new Error('Directory not found')); const sessions = await sessionTracker.getSessions(mockProjectPath); expect(sessions).toEqual([]); }); it('should return sessions from directory', async () => { const mockFiles = ['session_123_2025-05-31.md', 'session_456_2025-06-01.md', 'other.txt']; mockFs.readdir.mockResolvedValue(mockFiles as any); mockFs.readFile.mockResolvedValue(` # Session 123 **Project:** test **Start Time:** 2025-05-31 10:00:00 **End Time:** 2025-05-31 11:00:00 **Messages:** 5 **Total Tokens:** 100 **Session Name:** Test Session `); const sessions = await sessionTracker.getSessions(mockProjectPath); expect(sessions).toHaveLength(2); }); }); });

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/core3-coder/context-continue-mcp'

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