Skip to main content
Glama

MCP Bridge Server

user.test.ts6.1 kB
import { jest } from '@jest/globals'; import { join } from 'path'; import { mkdtemp, rm } from 'fs/promises'; import { tmpdir } from 'os'; import { UserManager } from '../../src/identity/user.js'; import { PersistentStorage } from '../../src/storage/persistentStorage.js'; import { IdentityError, IdentityErrorType } from '../../src/identity/types.js'; import { defaultProvider as machineIdProvider } from '../../src/identity/platform/index.js'; // Mock machine ID provider const mockMachineId = '00000000-0000-0000-0000-000000000000'; jest.spyOn(machineIdProvider, 'getId').mockResolvedValue(mockMachineId); jest.spyOn(machineIdProvider, 'validate').mockImplementation((id: string) => { return /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i.test(id); }); describe('UserManager', () => { let tempDir: string; let storage: PersistentStorage; let userManager: UserManager; beforeEach(async () => { // Create temp directory tempDir = await mkdtemp(join(tmpdir(), 'mcp-test-')); // Initialize storage storage = new PersistentStorage({ directory: tempDir, encryption: { enabled: false } }); await storage.initialize(); // Create and initialize user manager userManager = new UserManager({ storage, userDataPath: join(tempDir, 'users') }); await userManager.initialize(); }); afterEach(async () => { // Clean up temp directory await rm(tempDir, { recursive: true, force: true }); }); describe('createUser', () => { it('should create user with machine ID', async () => { const machineId = mockMachineId; const user = await userManager.createUser(machineId); expect(user).toBeDefined(); expect(user.id).toHaveLength(16); expect(user.machineIds).toContain(machineId); expect(user.created).toBeInstanceOf(Date); expect(user.lastSeen).toBeInstanceOf(Date); expect(user.sessions).toHaveLength(0); expect(user.preferences).toBeDefined(); expect(user.preferences.defaultClientType).toBe('claude'); }); it('should create user without machine ID', async () => { const user = await userManager.createUser(); expect(user).toBeDefined(); expect(user.id).toHaveLength(16); expect(user.machineIds).toHaveLength(1); expect(machineIdProvider.validate(user.machineIds[0])).toBe(true); }); it('should fail with invalid machine ID', async () => { await expect(userManager.createUser('invalid-id')) .rejects .toThrow(IdentityError); }); }); describe('getUser', () => { it('should get existing user', async () => { const created = await userManager.createUser(); const retrieved = await userManager.getUser(created.id); expect(retrieved).toEqual(created); }); it('should fail for non-existent user', async () => { await expect(userManager.getUser('non-existent')) .rejects .toThrow(IdentityErrorType.USER_NOT_FOUND); }); }); describe('getUserByMachine', () => { it('should get user by machine ID', async () => { const machineId = await machineIdProvider.getId(); const created = await userManager.createUser(machineId); const retrieved = await userManager.getUserByMachine(machineId); expect(retrieved).toEqual(created); }); it('should fail for unknown machine ID', async () => { await expect(userManager.getUserByMachine('unknown')) .rejects .toThrow(IdentityErrorType.USER_NOT_FOUND); }); }); describe('updateUser', () => { it('should update user preferences', async () => { const user = await userManager.createUser(); const updated = await userManager.updateUser(user.id, { preferences: { ...user.preferences, autoStartClients: true } }); expect(updated.preferences.autoStartClients).toBe(true); expect(updated.lastSeen).not.toEqual(user.lastSeen); }); it('should add machine ID', async () => { const user = await userManager.createUser(); const newMachineId = 'new-machine-id'; const updated = await userManager.updateUser(user.id, { machineIds: [...user.machineIds, newMachineId] }); expect(updated.machineIds).toContain(newMachineId); }); it('should fail with invalid updates', async () => { const user = await userManager.createUser(); await expect(userManager.updateUser(user.id, { id: '' // Invalid ID })) .rejects .toThrow(IdentityErrorType.USER_INVALID); }); }); describe('deleteUser', () => { it('should delete existing user', async () => { const user = await userManager.createUser(); await userManager.deleteUser(user.id); await expect(userManager.getUser(user.id)) .rejects .toThrow(IdentityErrorType.USER_NOT_FOUND); }); it('should fail for non-existent user', async () => { await expect(userManager.deleteUser('non-existent')) .rejects .toThrow(IdentityErrorType.USER_NOT_FOUND); }); }); describe('validation', () => { it('should validate user ID format', async () => { const userManager = new UserManager({ storage, userDataPath: join(tempDir, 'users'), validationRules: { userId: { pattern: /^[0-9a-f]{16}$/ } } }); const user = await userManager.createUser(); expect(user.id).toMatch(/^[0-9a-f]{16}$/); }); it('should validate machine IDs', async () => { const user = await userManager.createUser(); expect(user.machineIds.every(id => machineIdProvider.validate(id))) .toBe(true); }); it('should validate preferences', async () => { const user = await userManager.createUser(); await expect(userManager.updateUser(user.id, { preferences: { defaultClientType: 'invalid' as any } })) .rejects .toThrow(IdentityErrorType.USER_INVALID); }); }); });

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/glassBead-tc/SubspaceDomain'

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