Skip to main content
Glama

1MCP Server

versionsFormatter.test.ts11.6 kB
import { ServerVersionsResponse } from '@src/domains/registry/types.js'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { formatServerVersions } from './versionsFormatter.js'; // Mock console.table to capture table output const mockConsoleTable = vi.fn(); vi.stubGlobal('console', { ...console, table: mockConsoleTable }); // Mock chalk to capture color formatting vi.mock('chalk', () => { const createChalkMock = (color: string) => { const mockFn = vi.fn((text: string) => { const result = `${color.toUpperCase()}:${text}`; // Create a new object that can have properties added const resultObj = Object.assign(result, { bold: vi.fn((boldText: string) => `${color.toUpperCase()}:BOLD:${boldText}`), }); // Ensure it's a string, not an array return String(resultObj); }); // Add chained methods to the function itself (mockFn as any).bold = vi.fn((text: string) => `${color.toUpperCase()}:BOLD:${text}`); return mockFn; }; const chalkMock = { cyan: createChalkMock('cyan'), yellow: createChalkMock('yellow'), red: createChalkMock('red'), gray: createChalkMock('gray'), white: createChalkMock('white'), green: createChalkMock('green'), bold: createChalkMock('bold'), }; // Add dynamic property access support const proxy = new Proxy(chalkMock, { get(target, prop) { if (prop in target) { return target[prop as keyof typeof target]; } // Return a default mock for any other color return createChalkMock(prop as string); }, }); return { default: proxy, }; }); describe('versionsFormatter', () => { let mockVersionsResponse: ServerVersionsResponse; beforeEach(() => { vi.clearAllMocks(); mockVersionsResponse = { name: 'test-server', serverId: 'test-server-id', versions: [ { version: '1.2.0', status: 'active', isLatest: true, publishedAt: '2023-02-01T00:00:00Z', updatedAt: '2023-02-01T00:00:00Z', }, { version: '1.1.0', status: 'active', isLatest: false, publishedAt: '2023-01-15T00:00:00Z', updatedAt: '2023-01-16T00:00:00Z', }, { version: '1.0.0', status: 'deprecated', isLatest: false, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, { version: '0.9.0', status: 'archived', isLatest: false, publishedAt: '2022-12-01T00:00:00Z', updatedAt: '2022-12-01T00:00:00Z', }, ], }; }); describe('formatServerVersions', () => { it('should format versions in JSON format', () => { const result = formatServerVersions(mockVersionsResponse, 'json'); expect(result).toBe(JSON.stringify(mockVersionsResponse, null, 2)); }); it('should format versions in table format by default', () => { const result = formatServerVersions(mockVersionsResponse); expect(result).toContain('Versions for test-server (4 total):'); expect(mockConsoleTable).toHaveBeenCalledTimes(1); // Check that the table was called with proper data const tableData = mockConsoleTable.mock.calls[0][0]; expect(tableData).toHaveLength(4); expect(tableData[0]).toEqual({ Version: '1.2.0', Status: 'active', Latest: 'Yes', Published: expect.any(String), Updated: expect.any(String), }); }); it('should format versions in table format explicitly', () => { const result = formatServerVersions(mockVersionsResponse, 'table'); expect(result).toContain('Versions for test-server (4 total):'); expect(mockConsoleTable).toHaveBeenCalledTimes(1); }); it('should format versions in detailed format', () => { const result = formatServerVersions(mockVersionsResponse, 'detailed'); // Should be wrapped in boxen expect(result).toContain('test-server'); expect(result).toContain('4 versions'); expect(result).toContain('1.2.0'); expect(result).toContain('[LATEST]'); expect(result).toContain('● active'); expect(result).toContain('● deprecated'); expect(result).toContain('● archived'); expect(result).toContain('Server Information:'); expect(result).toContain('Server ID: test-server-id'); }); it('should handle empty versions array', () => { const emptyVersionsResponse: ServerVersionsResponse = { name: 'empty-server', serverId: 'empty-server-id', versions: [], }; const tableResult = formatServerVersions(emptyVersionsResponse, 'table'); expect(tableResult).toContain('No versions found for server: empty-server'); const detailedResult = formatServerVersions(emptyVersionsResponse, 'detailed'); expect(detailedResult).toContain('YELLOW:No versions found for server: empty-server'); }); it('should sort versions by published date (newest first)', () => { // Mix up the order to test sorting const unsortedVersionsResponse: ServerVersionsResponse = { name: 'test-server', serverId: 'test-server-id', versions: [ { version: '1.0.0', status: 'deprecated', isLatest: false, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, { version: '1.2.0', status: 'active', isLatest: true, publishedAt: '2023-02-01T00:00:00Z', updatedAt: '2023-02-01T00:00:00Z', }, { version: '1.1.0', status: 'active', isLatest: false, publishedAt: '2023-01-15T00:00:00Z', updatedAt: '2023-01-16T00:00:00Z', }, ], }; formatServerVersions(unsortedVersionsResponse, 'table'); const tableData = mockConsoleTable.mock.calls[0][0]; expect(tableData[0].Version).toBe('1.2.0'); // Newest first expect(tableData[1].Version).toBe('1.1.0'); expect(tableData[2].Version).toBe('1.0.0'); // Oldest last }); it('should show "Yes" for latest version and "No" for others', () => { formatServerVersions(mockVersionsResponse, 'table'); const tableData = mockConsoleTable.mock.calls[0][0]; expect(tableData[0].Latest).toBe('Yes'); // 1.2.0 expect(tableData[1].Latest).toBe('No'); // 1.1.0 expect(tableData[2].Latest).toBe('No'); // 1.0.0 expect(tableData[3].Latest).toBe('No'); // 0.9.0 }); it('should handle versions with same published and updated dates', () => { const versionsWithSameDates: ServerVersionsResponse = { name: 'test-server', serverId: 'test-server-id', versions: [ { version: '1.0.0', status: 'active', isLatest: true, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, ], }; const result = formatServerVersions(versionsWithSameDates, 'detailed'); // Should not show duplicate date information expect(result).toContain('Published:'); expect(result).toContain('1.0.0'); }); it('should show different published and updated dates', () => { const versionsWithDifferentDates: ServerVersionsResponse = { name: 'test-server', serverId: 'test-server-id', versions: [ { version: '1.1.0', status: 'active', isLatest: true, publishedAt: '2023-01-15T00:00:00Z', updatedAt: '2023-01-16T00:00:00Z', }, ], }; const result = formatServerVersions(versionsWithDifferentDates, 'detailed'); expect(result).toContain('Published:'); expect(result).toContain('Updated:'); }); it('should count active and deprecated versions correctly', () => { const result = formatServerVersions(mockVersionsResponse, 'detailed'); expect(result).toContain('Active Versions: 2'); // 1.2.0 and 1.1.0 expect(result).toContain('Deprecated Versions: 1'); // 1.0.0 }); it('should handle single version', () => { const singleVersionResponse: ServerVersionsResponse = { name: 'single-version-server', serverId: 'single-version-id', versions: [ { version: '1.0.0', status: 'active', isLatest: true, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, ], }; const tableResult = formatServerVersions(singleVersionResponse, 'table'); expect(tableResult).toContain('Versions for single-version-server (1 total):'); const detailedResult = formatServerVersions(singleVersionResponse, 'detailed'); expect(detailedResult).toContain('CYAN:BOLD:single-version-serverGRAY: (1 version)'); }); it('should handle all archived versions', () => { const archivedVersionsResponse: ServerVersionsResponse = { name: 'archived-server', serverId: 'archived-server-id', versions: [ { version: '0.1.0', status: 'archived', isLatest: false, publishedAt: '2022-01-01T00:00:00Z', updatedAt: '2022-01-01T00:00:00Z', }, ], }; const result = formatServerVersions(archivedVersionsResponse, 'detailed'); expect(result).toContain('Active Versions: 0'); expect(result).toContain('Deprecated Versions: 0'); expect(result).toContain('● archived'); }); it('should handle versions with unknown status', () => { const unknownStatusVersionsResponse: ServerVersionsResponse = { name: 'unknown-status-server', serverId: 'unknown-status-id', versions: [ { version: '1.0.0', status: 'unknown' as any, isLatest: true, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, ], }; const result = formatServerVersions(unknownStatusVersionsResponse, 'detailed'); expect(result).toContain('● unknown'); }); it('should handle invalid date formats gracefully', () => { const invalidDateVersionsResponse: ServerVersionsResponse = { name: 'invalid-date-server', serverId: 'invalid-date-id', versions: [ { version: '1.0.0', status: 'active', isLatest: true, publishedAt: 'invalid-date', updatedAt: 'invalid-date', }, ], }; expect(() => { formatServerVersions(invalidDateVersionsResponse, 'table'); }).not.toThrow(); expect(() => { formatServerVersions(invalidDateVersionsResponse, 'detailed'); }).not.toThrow(); }); it('should handle missing server ID', () => { const noServerIdResponse: ServerVersionsResponse = { name: 'no-id-server', serverId: '', versions: [ { version: '1.0.0', status: 'active', isLatest: true, publishedAt: '2023-01-01T00:00:00Z', updatedAt: '2023-01-01T00:00:00Z', }, ], }; const result = formatServerVersions(noServerIdResponse, 'detailed'); expect(result).toContain('Server ID:'); }); }); });

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