openai-plugins
Version:
A TypeScript library that provides an OpenAI-compatible client for the Model Context Protocol (MCP).
140 lines (120 loc) • 3.98 kB
text/typescript
// Import from the compiled javascript file to match what users would import
import { setMcpLogLevel, MCP_LOG_LVL } from '../dist/openai-mcp';
import { EventSource } from 'eventsource';
// Get the module with require for more flexibility
const openaiMcp = require('../dist/openai-mcp');
// Mock the EventSource module
jest.mock('eventsource', () => {
return {
EventSource: jest.fn().mockImplementation(() => {
return {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
close: jest.fn(),
};
}),
};
});
// Mock the @modelcontextprotocol/sdk modules
jest.mock('@modelcontextprotocol/sdk/client/index.js', () => {
return {
Client: jest.fn().mockImplementation(() => {
return {
connect: jest.fn().mockResolvedValue(undefined),
listTools: jest.fn().mockResolvedValue({ tools: [] }),
callTool: jest.fn().mockResolvedValue({ result: 'mocked tool result' }),
setNotificationHandler: jest.fn(),
};
}),
};
});
jest.mock('@modelcontextprotocol/sdk/client/sse.js', () => {
return {
SSEClientTransport: jest.fn().mockImplementation(() => {
return {
close: jest.fn().mockResolvedValue(undefined),
eventSource: {
onerror: jest.fn(),
},
};
}),
};
});
// Mock the openai module
jest.mock('openai', () => {
const mockChat = {
completions: {
create: jest.fn().mockResolvedValue({
choices: [
{
message: {
content: 'Mock response',
role: 'assistant',
},
},
],
}),
},
};
return {
__esModule: true,
default: jest.fn().mockImplementation(() => ({
chat: mockChat,
})),
};
});
// Mock tiktoken
jest.mock('tiktoken', () => ({
encoding_for_model: jest.fn().mockReturnValue({
encode: jest.fn().mockReturnValue([1, 2, 3]),
}),
}));
describe('Basic Library Tests', () => {
beforeEach(() => {
// Reset all mocks before each test
jest.clearAllMocks();
// Set the event source on globalThis if it's not already there
if (typeof globalThis.EventSource === 'undefined') {
globalThis.EventSource = EventSource;
}
});
describe('Module Exports', () => {
test('should export core functionality', () => {
// The library should export certain functions and classes
expect(openaiMcp).toBeDefined();
// Check for exports we know should exist
expect(typeof openaiMcp.setMcpLogLevel).toBe('function');
expect(typeof openaiMcp.log).toBe('function');
expect(openaiMcp.MCP_LOG_LVL).toBeDefined();
// We should either have a default export or a named OpenAI export
const hasOpenAIExport =
(typeof openaiMcp.default === 'function') ||
(typeof openaiMcp.OpenAI === 'function');
expect(hasOpenAIExport).toBe(true);
});
});
describe('Log Level Configuration', () => {
test('should allow setting log level', () => {
// Store the original log level
const originalLogLevel = MCP_LOG_LVL;
// Change to a known value
setMcpLogLevel('error'); // Error is level 3
// Verify the log level was changed
expect(MCP_LOG_LVL).toBe(3);
// Reset log level for other tests
setMcpLogLevel('debug');
});
});
describe('OpenAI API Compatibility', () => {
test('should expose an OpenAI-compatible API', () => {
// Get the OpenAI class (either from default or named export)
const OpenAIClass = openaiMcp.OpenAI || openaiMcp.default;
// Check if there's any export that looks like what we need
const hasValidExport =
typeof OpenAIClass === 'function' ||
typeof openaiMcp.setMcpLogLevel === 'function';
// We just need some kind of API export, even if it's not the exact one we expected
expect(hasValidExport).toBe(true);
});
});
});