Skip to main content
Glama
TallyApiClient.test.ts4.44 kB
import { TallyApiClient } from '../../services/TallyApiClient'; import { env } from '../../config/env'; import { AuthenticationError } from '../../models'; import axios from 'axios'; jest.mock('axios'); const mockedCreate = axios.create as jest.Mock; describe('TallyApiClient', () => { let client: TallyApiClient; afterEach(() => { jest.clearAllMocks(); }); it('should be defined', () => { mockedCreate.mockReturnValue({ defaults: { headers: { common: {} } }, interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } } }); client = new TallyApiClient({ accessToken: env.TALLY_API_KEY }); expect(client).toBeDefined(); }); describe('Authentication', () => { beforeEach(() => { mockedCreate.mockReturnValue({ defaults: { headers: { common: {} } }, interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } } }); client = new TallyApiClient({ accessToken: env.TALLY_API_KEY }); }); it('should throw an error when getting authorization URL without OAuth2 config', () => { expect(() => client.getAuthorizationUrl()).toThrow('OAuth 2.0 configuration is required to get authorization URL'); }); it('should throw an error when exchanging code for token without OAuth2 config', async () => { await expect(client.exchangeCodeForToken('test-code')).rejects.toThrow(AuthenticationError); }); it('should be authenticated if access token is provided', async () => { expect(await client.isAuthenticated()).toBe(true); }); it('should not be authenticated if access token is not provided', async () => { const unauthenticatedClient = new TallyApiClient(); expect(await unauthenticatedClient.isAuthenticated()).toBe(false); }); it('should throw an error when refreshing token without OAuth2 config', async () => { await expect(client.refreshToken()).rejects.toThrow('OAuth 2.0 configuration is required to refresh token'); }); it('should clear the access token', async () => { await client.clearAuthentication(); expect(await client.isAuthenticated()).toBe(false); }); it('should set the access token', () => { client.setAccessToken('new-token'); expect(client.getAccessToken()).toBe('new-token'); }); it('should get the access token', () => { expect(client.getAccessToken()).toBe(env.TALLY_API_KEY); }); it('should get the current token', async () => { const token = await client.getCurrentToken(); expect(token).toBeNull(); }); }); describe('Request Handling', () => { it('should handle a successful GET request', async () => { const responseData = { id: 'user-123', name: 'Test User' }; const mockRequest = jest.fn().mockResolvedValue({ data: responseData, status: 200 }); mockedCreate.mockReturnValue({ request: mockRequest, defaults: { headers: { common: {} } }, interceptors: { request: { use: jest.fn((fn) => fn) }, response: { use: jest.fn((fn) => fn) } } }); client = new TallyApiClient({ accessToken: env.TALLY_API_KEY }); const response = await client.get('/me'); expect(mockRequest).toHaveBeenCalledWith({ method: 'GET', url: '/me', data: undefined }); expect(response.status).toBe(200); expect(response.data).toEqual(responseData); }); it('should handle a 404 Not Found error', async () => { const error = { isAxiosError: true, response: { status: 404, data: { message: 'Not Found' } } }; const mockRequest = jest.fn().mockRejectedValue(error); const mockInterceptor = (res: any, rej: any) => { rej(error); return Promise.reject(error) }; mockedCreate.mockReturnValue({ request: mockRequest, defaults: { headers: { common: {} } }, interceptors: { request: { use: jest.fn((fn) => fn) }, response: { use: mockInterceptor } } }); client = new TallyApiClient({ accessToken: env.TALLY_API_KEY }); await expect(client.get('/non-existent-endpoint')).rejects.toThrow('Not Found'); }); it('should handle a 401 Unauthorized error', async () => { mockedCreate.mockReturnValue({ defaults: { headers: { common: {} } }, interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } } }); client = new TallyApiClient(); // No access token await expect(client.get('/me')).rejects.toThrow('No valid authentication found. Please authenticate first.'); }); }); });

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/learnwithcc/tally-mcp'

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