Skip to main content
Glama
onyxApi.test.ts11.4 kB
/** * Unit tests for the OnyxApiService */ import nock from 'nock'; import { OnyxApiService } from '../../services/onyxApi.js'; import { OnyxConfig } from '../../types/index.js'; // Mock config for testing const mockConfig: OnyxConfig = { apiUrl: 'http://test-api.com/api', apiToken: 'test-token', }; describe('OnyxApiService', () => { let onyxApiService: OnyxApiService; beforeEach(() => { // Create service instance onyxApiService = new OnyxApiService(mockConfig); // Disable real HTTP requests nock.disableNetConnect(); }); afterEach(() => { // Clean up nock after each test nock.cleanAll(); nock.enableNetConnect(); }); describe('searchOnyx', () => { it('should make a POST request to the search endpoint with correct parameters', async () => { // Mock the search API response const mockResponse = { documents: [ { document_id: 'doc1', chunk_ind: 1, semantic_identifier: 'Test Document', blurb: 'Test blurb', source_type: 'test', score: 0.95, }, ], }; // Set up the mock nock('http://test-api.com') .post('/api/admin/search') .reply(200, mockResponse); // Call the method const result = await onyxApiService.searchOnyx('test query', [], 1, 2); // Verify the result expect(result).toEqual(mockResponse.documents); }); it('should include document sets in the request when provided', async () => { // Mock the search API response const mockResponse = { documents: [ { document_id: 'doc1', chunk_ind: 1, semantic_identifier: 'Test Document', blurb: 'Test blurb', source_type: 'test', score: 0.95, }, ], }; // Set up the mock nock('http://test-api.com') .post('/api/admin/search') .reply(200, mockResponse); // Call the method with document sets const result = await onyxApiService.searchOnyx('test query', ['Test Set']); // Verify the result expect(result).toEqual(mockResponse.documents); }); it('should throw an error when the API request fails', async () => { // Set up the mock to return an error nock('http://test-api.com') .post('/api/admin/search') .reply(500, { error: 'Internal server error' }); // Call the method and expect it to throw await expect(onyxApiService.searchOnyx('test query')).rejects.toThrow( 'Failed to search Onyx' ); }); }); describe('fetchDocumentChunk', () => { it('should make a GET request to the chunk-info endpoint with correct parameters', async () => { // Mock the chunk-info API response const mockResponse = { content: 'Test chunk content', num_tokens: 10, }; // Set up the mock nock('http://test-api.com') .get('/api/document/chunk-info') .query({ document_id: 'doc1', chunk_id: 1, }) .reply(200, mockResponse); // Call the method const result = await onyxApiService.fetchDocumentChunk('doc1', 1); // Verify the result expect(result).toEqual(mockResponse.content); }); it('should return empty string when the API request fails', async () => { // Set up the mock to return an error nock('http://test-api.com') .get('/api/document/chunk-info') .query({ document_id: 'doc1', chunk_id: 1, }) .reply(500, { error: 'Internal server error' }); // Call the method const result = await onyxApiService.fetchDocumentChunk('doc1', 1); // Verify the result expect(result).toEqual(''); }); }); describe('fetchDocumentContent', () => { it('should fetch document size info and then all chunks', async () => { // Mock the document-size-info API response const mockSizeResponse = { num_chunks: 2, total_tokens: 20 }; // Mock the chunk-info API responses const mockChunk1Response = { content: 'Chunk 1 content', num_tokens: 10 }; const mockChunk2Response = { content: 'Chunk 2 content', num_tokens: 10 }; // Set up the mocks nock('http://test-api.com') .get('/api/document/document-size-info') .query({ document_id: 'doc1' }) .reply(200, mockSizeResponse); nock('http://test-api.com') .get('/api/document/chunk-info') .query({ document_id: 'doc1', chunk_id: 0 }) .reply(200, mockChunk1Response); nock('http://test-api.com') .get('/api/document/chunk-info') .query({ document_id: 'doc1', chunk_id: 1 }) .reply(200, mockChunk2Response); // Call the method const result = await onyxApiService.fetchDocumentContent('doc1'); // Verify the result expect(result).toContain(mockChunk1Response.content); expect(result).toContain(mockChunk2Response.content); }); it('should return empty string when the API request fails', async () => { // Set up the mock to return an error nock('http://test-api.com') .get('/api/document/document-size-info') .query({ document_id: 'doc1' }) .reply(500, { error: 'Internal server error' }); // Call the method const result = await onyxApiService.fetchDocumentContent('doc1'); // Verify the result expect(result).toEqual(''); }); }); describe('createChatSession', () => { it('should make a POST request to create a chat session', async () => { // Mock the create-chat-session API response const mockResponse = { chat_session_id: 'test-session-id' }; // Set up the mock nock('http://test-api.com') .post('/api/chat/create-chat-session') .reply(200, mockResponse); // Call the method const result = await onyxApiService.createChatSession(15); // Verify the result expect(result).toEqual(mockResponse.chat_session_id); }); it('should throw an error when the API request fails', async () => { // Set up the mock to return an error nock('http://test-api.com') .post('/api/chat/create-chat-session') .reply(500, { error: 'Internal server error' }); // Call the method and expect it to throw await expect(onyxApiService.createChatSession(15)).rejects.toThrow( 'Failed to create chat session' ); }); }); describe('sendChatMessage', () => { it('should make a POST request to send a chat message and parse JSON response', async () => { // Mock the send-message API response (single JSON) const mockResponse = JSON.stringify({ answer: 'Test answer', documents: [ { document_id: 'doc1', semantic_identifier: 'Test Document 1' }, { document_id: 'doc2', semantic_identifier: 'Test Document 2' } ] }); // Set up the mock nock('http://test-api.com') .post('/api/chat/send-message') .reply(200, mockResponse); // Call the method const result = await onyxApiService.sendChatMessage('test-session-id', 'test query'); // Verify the result expect(result.answer).toEqual('Test answer'); expect(result.documents).toHaveLength(2); expect(result.documents[0].document_id).toEqual('doc1'); }); it('should handle JSON lines format response', async () => { // Mock the send-message API response (JSON lines) const mockResponse = '{"answer_piece":"Part 1 of answer"}\n' + '{"answer_piece":"Part 2 of answer"}\n' + '{"top_documents":[{"document_id":"doc1","semantic_identifier":"Test Document 1"}]}'; // Set up the mock nock('http://test-api.com') .post('/api/chat/send-message') .reply(200, mockResponse); // Call the method const result = await onyxApiService.sendChatMessage('test-session-id', 'test query'); // Verify the result expect(result.answer).toEqual('Part 1 of answerPart 2 of answer'); expect(result.documents).toHaveLength(1); expect(result.documents[0].document_id).toEqual('doc1'); }); it('should throw an error when the API request fails', async () => { // Set up the mock to return an error nock('http://test-api.com') .post('/api/chat/send-message') .reply(500, { error: 'Internal server error' }); // Call the method and expect it to throw await expect(onyxApiService.sendChatMessage('test-session-id', 'test query')).rejects.toThrow( 'Error chatting with Onyx' ); }); }); describe('buildContext', () => { it('should build a formatted context string from search results and contents', () => { // Test data const results = [ { document_id: 'doc1', chunk_ind: 1, semantic_identifier: 'Test Document 1', score: 0.95, link: 'http://example.com/doc1', blurb: 'Test blurb 1', source_type: 'test' }, { document_id: 'doc2', chunk_ind: 2, semantic_identifier: 'Test Document 2', score: 0.85, link: undefined, blurb: 'Test blurb 2', source_type: 'test' } ]; const contents = [ 'Content for document 1', 'Content for document 2' ]; // Call the method const result = onyxApiService.buildContext(results, contents); // Verify the result expect(result).toContain('# Test Document 1'); expect(result).toContain('Source: http://example.com/doc1'); expect(result).toContain('Relevance Score: 0.95'); expect(result).toContain('Content for document 1'); expect(result).toContain('# Test Document 2'); expect(result).toContain('Source: doc2'); expect(result).toContain('Relevance Score: 0.85'); expect(result).toContain('Content for document 2'); }); it('should skip results with no content', () => { // Test data const results = [ { document_id: 'doc1', chunk_ind: 1, semantic_identifier: 'Test Document 1', score: 0.95, link: 'http://example.com/doc1', blurb: 'Test blurb 1', source_type: 'test' }, { document_id: 'doc2', chunk_ind: 2, semantic_identifier: 'Test Document 2', score: 0.85, link: 'http://example.com/doc2', blurb: 'Test blurb 2', source_type: 'test' } ]; const contents = [ 'Content for document 1', '' // Empty content for second document ]; // Call the method const result = onyxApiService.buildContext(results, contents); // Verify the result expect(result).toContain('# Test Document 1'); expect(result).toContain('Content for document 1'); // Should not contain document 2 info expect(result).not.toContain('# Test Document 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/lupuletic/onyx-mcp-server'

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