Skip to main content
Glama
handlers.spec.ts7.78 kB
import { describe, it, expect, beforeEach, afterEach, jest, } from '@jest/globals'; global.fetch = jest.fn() as jest.MockedFunction<typeof fetch>; const mockFetch = fetch as jest.MockedFunction<typeof fetch>; describe('Handler functions', () => { beforeEach(() => { jest.clearAllMocks(); process.env['TBA_API_KEY'] = 'test-api-key'; }); afterEach(() => { delete process.env['TBA_API_KEY']; }); describe('handleToolCall', () => { it('should handle get_team tool', async () => { const mockTeamData = { key: 'frc86', team_number: 86, name: 'Team Resistance', city: 'Jacksonville', state_prov: 'Florida', country: 'USA', }; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockTeamData, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_team', { team_key: 'frc86', }); expect(result.content).toBeDefined(); expect(result.content[0]!.type).toBe('text'); const parsedContent = JSON.parse(result.content[0]!.text); expect(parsedContent.key).toBe('frc86'); expect(parsedContent.team_number).toBe(86); }); it('should handle get_team_events tool', async () => { const mockEvents = [ { key: '2024hop', name: 'Hopper Division', event_code: 'hop', event_type: 3, start_date: '2024-04-16', end_date: '2024-04-19', year: 2024, event_type_string: 'Championship Division', }, ]; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockEvents, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_team_events', { team_key: 'frc86', year: 2024, }); expect(result.content).toBeDefined(); expect(result.content[0]!.type).toBe('text'); const parsedContent = JSON.parse(result.content[0]!.text); expect(Array.isArray(parsedContent)).toBe(true); expect(parsedContent.length).toBe(1); }); it('should handle get_status tool', async () => { const mockStatus = { current_season: 2025, max_season: 2025, is_datafeed_down: false, down_events: [], ios: { latest_app_version: 123, min_app_version: 120, }, android: { latest_app_version: 456, min_app_version: 450, }, max_team_page: 189, }; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockStatus, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_status', {}); expect(result.content).toBeDefined(); expect(result.content[0]!.type).toBe('text'); const parsedContent = JSON.parse(result.content[0]!.text); expect(parsedContent.current_season).toBe(2025); }); it('should throw error for invalid team key format', async () => { const { handleToolCall } = await import('../src/handlers.js'); await expect( handleToolCall('get_team', { team_key: 'invalid', }), ).rejects.toThrow(); }); it('should throw error for invalid year', async () => { const { handleToolCall } = await import('../src/handlers.js'); await expect( handleToolCall('get_team_events', { team_key: 'frc86', year: 1990, // Before 1992 }), ).rejects.toThrow(); }); it('should throw error for missing required parameters', async () => { const { handleToolCall } = await import('../src/handlers.js'); await expect( handleToolCall('get_team_events', { team_key: 'frc86', // missing year parameter }), ).rejects.toThrow(); }); it('should throw error for unknown tool name', async () => { const { handleToolCall } = await import('../src/handlers.js'); await expect(handleToolCall('unknown_tool', {})).rejects.toThrow( 'Unknown tool: unknown_tool', ); }); it('should handle get_teams tool with pagination', async () => { const mockTeams = [ { key: 'frc86', team_number: 86, name: 'Team Resistance', }, { key: 'frc254', team_number: 254, name: 'The Cheesy Poofs', }, ]; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockTeams, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_teams', { page_num: 0, }); expect(result.content).toBeDefined(); const parsedContent = JSON.parse(result.content[0]!.text); expect(Array.isArray(parsedContent)).toBe(true); }); it('should handle get_event tool', async () => { const mockEvent = { key: '2024hop', name: 'Hopper Division', event_code: 'hop', event_type: 3, start_date: '2024-04-16', end_date: '2024-04-19', year: 2024, event_type_string: 'Championship Division', }; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockEvent, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_event', { event_key: '2024hop', }); expect(result.content).toBeDefined(); const parsedContent = JSON.parse(result.content[0]!.text); expect(parsedContent.key).toBe('2024hop'); }); it('should handle API errors gracefully', async () => { mockFetch.mockResolvedValueOnce({ ok: false, status: 404, statusText: 'Not Found', } as Response); const { handleToolCall } = await import('../src/handlers.js'); await expect( handleToolCall('get_team', { team_key: 'frc999999', }), ).rejects.toThrow('TBA API request failed: 404 Not Found'); }); it('should handle get_match tool', async () => { const mockMatch = { key: '2024hop_qm112', comp_level: 'qm', set_number: 1, match_number: 112, alliances: { red: { score: 214, team_keys: ['frc86', 'frc230', 'frc2960'], }, blue: { score: 165, team_keys: ['frc781', 'frc3814', 'frc1153'], }, }, event_key: '2024hop', }; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => mockMatch, } as Response); const { handleToolCall } = await import('../src/handlers.js'); const result = await handleToolCall('get_match', { match_key: '2024hop_qm112', }); expect(result.content).toBeDefined(); const parsedContent = JSON.parse(result.content[0]!.text); expect(parsedContent.key).toBe('2024hop_qm112'); }); it('should validate response data against schema', async () => { const invalidTeamData = { key: 'frc86', // missing required 'name' field team_number: 86, }; mockFetch.mockResolvedValueOnce({ ok: true, json: async () => invalidTeamData, } as Response); const { handleToolCall } = await import('../src/handlers.js'); await expect( handleToolCall('get_team', { team_key: 'frc86', }), ).rejects.toThrow(); }); }); });

Latest Blog Posts

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/withinfocus/tba'

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