Skip to main content
Glama
providers.test.tsโ€ข8.05 kB
import { describe, it, expect, jest, beforeEach } from '@jest/globals'; // Mock OpenAI BEFORE importing the provider const mockCreate = jest.fn(); jest.mock('openai', () => { const MockOpenAI = jest.fn().mockImplementation(() => ({ chat: { completions: { create: mockCreate, }, }, })); return { __esModule: true, default: MockOpenAI, }; }); // Mock config manager and logger jest.mock('../src/config/config'); jest.mock('../src/utils/logger'); // NOW import the modules after setting up mocks import { DuckProvider } from '../src/providers/provider'; import { ProviderManager } from '../src/providers/manager'; import { ConfigManager } from '../src/config/config'; describe('DuckProvider', () => { let provider: DuckProvider; beforeEach(() => { jest.clearAllMocks(); // Setup mock response mockCreate.mockResolvedValue({ choices: [{ message: { content: 'Mocked response' }, finish_reason: 'stop', }], usage: { prompt_tokens: 10, completion_tokens: 20, total_tokens: 30, }, model: 'mock-model', }); provider = new DuckProvider('test', 'Test Duck', { apiKey: 'test-key', baseURL: 'https://api.test.com/v1', model: 'test-model', temperature: 0.7, }); // Override the method on the actual instance since Jest ESM mocking isn't working provider['client'].chat.completions.create = mockCreate; }); it('should create a provider instance', () => { expect(provider).toBeDefined(); expect(provider.name).toBe('test'); expect(provider.nickname).toBe('Test Duck'); }); it('should get provider info', () => { const info = provider.getInfo(); expect(info).toEqual({ name: 'test', nickname: 'Test Duck', model: 'test-model', baseURL: 'https://api.test.com/v1', hasApiKey: true, }); }); it('should send chat request', async () => { console.log('Starting chat request test'); console.log('Mock create has been called:', mockCreate.mock.calls.length, 'times'); const response = await provider.chat({ messages: [ { role: 'user', content: 'Hello', timestamp: new Date() }, ], }); console.log('Chat response received:', response); expect(response).toBeDefined(); expect(response.content).toBe('Mocked response'); expect(response.usage).toBeDefined(); expect(response.model).toBe('test-model'); }); it('should use correct parameters for o1 models', async () => { mockCreate.mockClear(); const testProvider = new DuckProvider('test', 'Test Duck', { apiKey: 'test-key', baseURL: 'https://api.test.com/v1', model: 'o1', }); // Override the method on the actual instance since Jest ESM mocking isn't working testProvider['client'].chat.completions.create = mockCreate; await testProvider.chat({ messages: [{ role: 'user', content: 'Hello', timestamp: new Date() }], model: 'o1', }); expect(mockCreate).toHaveBeenCalledTimes(1); const calls = (mockCreate as any).mock.calls; expect(calls.length).toBeGreaterThan(0); const callParams = calls[0][0]; // o1 models should NOT have temperature or token limits expect(callParams).not.toHaveProperty('temperature'); }); it('should use correct parameters for GPT-5 models', async () => { mockCreate.mockClear(); const testProvider = new DuckProvider('test', 'Test Duck', { apiKey: 'test-key', baseURL: 'https://api.test.com/v1', model: 'gpt-5', }); // Override the method on the actual instance since Jest ESM mocking isn't working testProvider['client'].chat.completions.create = mockCreate; await testProvider.chat({ messages: [{ role: 'user', content: 'Hello', timestamp: new Date() }], model: 'gpt-5', }); expect(mockCreate).toHaveBeenCalledTimes(1); const calls = (mockCreate as any).mock.calls; expect(calls.length).toBeGreaterThan(0); const callParams = calls[0][0]; // GPT-5 models should NOT have temperature or token limits expect(callParams).not.toHaveProperty('temperature'); }); it('should use correct parameters for non-o1 models', async () => { mockCreate.mockClear(); const testProvider = new DuckProvider('test', 'Test Duck', { apiKey: 'test-key', baseURL: 'https://api.test.com/v1', model: 'gpt-4', }); // Override the method on the actual instance since Jest ESM mocking isn't working testProvider['client'].chat.completions.create = mockCreate; await testProvider.chat({ messages: [{ role: 'user', content: 'Hello', timestamp: new Date() }], model: 'gpt-4', }); expect(mockCreate).toHaveBeenCalledTimes(1); const calls = (mockCreate as any).mock.calls; expect(calls.length).toBeGreaterThan(0); const callParams = calls[0][0]; // non-o1 models should have temperature but no token limits expect(callParams).toHaveProperty('temperature'); }); }); describe('ProviderManager', () => { let manager: ProviderManager; let mockConfigManager: jest.Mocked<ConfigManager>; beforeEach(() => { jest.clearAllMocks(); // Setup mock response mockCreate.mockResolvedValue({ choices: [{ message: { content: 'Mocked response' }, finish_reason: 'stop', }], usage: { prompt_tokens: 10, completion_tokens: 20, total_tokens: 30, }, model: 'mock-model', }); mockConfigManager = { getConfig: jest.fn().mockReturnValue({ providers: { test1: { api_key: 'key1', base_url: 'https://api1.test.com/v1', default_model: 'model1', nickname: 'Duck 1', models: ['model1'], }, test2: { api_key: 'key2', base_url: 'https://api2.test.com/v1', default_model: 'model2', nickname: 'Duck 2', models: ['model2'], }, }, default_provider: 'test1', cache_ttl: 300, enable_failover: true, default_temperature: 0.7, }), } as any; manager = new ProviderManager(mockConfigManager); // Override the client method on all providers in the manager const provider1 = manager.getProvider('test1'); const provider2 = manager.getProvider('test2'); provider1['client'].chat.completions.create = mockCreate; provider2['client'].chat.completions.create = mockCreate; }); it('should initialize providers from config', () => { const providers = manager.getProviderNames(); expect(providers).toContain('test1'); expect(providers).toContain('test2'); }); it('should get a specific provider', () => { const provider = manager.getProvider('test1'); expect(provider).toBeDefined(); expect(provider.name).toBe('test1'); }); it('should get default provider when no name specified', () => { const provider = manager.getProvider(); expect(provider).toBeDefined(); expect(provider.name).toBe('test1'); }); it('should throw error for non-existent provider', () => { expect(() => manager.getProvider('nonexistent')).toThrow( 'Duck "nonexistent" not found in the pond' ); }); it('should ask a duck', async () => { const response = await manager.askDuck('test1', 'Hello'); expect(response).toBeDefined(); expect(response.provider).toBe('test1'); expect(response.content).toBe('Mocked response'); }); it('should compare multiple ducks', async () => { const responses = await manager.compareDucks('Hello', ['test1', 'test2']); expect(responses).toHaveLength(2); expect(responses[0].provider).toBe('test1'); expect(responses[1].provider).toBe('test2'); }); it('should run duck council', async () => { const responses = await manager.duckCouncil('Hello'); expect(responses).toHaveLength(2); }); });

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/nesquikm/mcp-rubber-duck'

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