UNPKG

serper-search-scrape-mcp-server

Version:

Serper MCP Server supporting search and webpage scraping

165 lines (164 loc) 6.68 kB
import { SerperSearchTools } from '../search-tool.js'; import { SerperClient } from '../../services/serper-client.js'; // Mock SerperClient jest.mock('../../services/serper-client.js'); describe('SerperSearchTools', () => { let mockSerperClient; let searchTools; beforeEach(() => { mockSerperClient = new SerperClient('mock-key'); searchTools = new SerperSearchTools(mockSerperClient); }); describe('search', () => { const mockSearchParams = { q: 'test query', gl: 'us', hl: 'en' }; const mockSearchResult = { searchParameters: { q: 'test query', gl: 'us', hl: 'en' }, organic: [ { title: 'Test Result', link: 'https://test.com', snippet: 'Test snippet', position: 1 } ] }; it('should call SerperClient.search with correct parameters', async () => { mockSerperClient.search.mockResolvedValueOnce(mockSearchResult); const result = await searchTools.search(mockSearchParams); expect(mockSerperClient.search).toHaveBeenCalledWith(mockSearchParams); expect(result).toEqual(mockSearchResult); }); it('should handle optional parameters correctly', async () => { const paramsWithOptional = { ...mockSearchParams, num: 5, tbs: 'qdr:d', location: 'New York', autocorrect: true }; mockSerperClient.search.mockResolvedValueOnce({ ...mockSearchResult, searchParameters: paramsWithOptional }); const result = await searchTools.search(paramsWithOptional); expect(mockSerperClient.search).toHaveBeenCalledWith(paramsWithOptional); expect(result.searchParameters).toEqual(paramsWithOptional); }); it('should handle errors from SerperClient', async () => { const error = new Error('API Error'); mockSerperClient.search.mockRejectedValueOnce(error); await expect(searchTools.search(mockSearchParams)) .rejects .toThrow(error); }); }); describe('batchSearch', () => { const mockBatchParams = [ { q: 'query1', gl: 'us', hl: 'en' }, { q: 'query2', gl: 'uk', hl: 'en' } ]; const mockBatchResult = [ { searchParameters: { q: 'query1', gl: 'us', hl: 'en' }, organic: [{ title: 'Result 1', link: 'https://test1.com', position: 1, snippet: 'Test snippet 1' }] }, { searchParameters: { q: 'query2', gl: 'uk', hl: 'en' }, organic: [{ title: 'Result 2', link: 'https://test2.com', position: 1, snippet: 'Test snippet 2' }] } ]; it('should call SerperClient.batchSearch with correct parameters', async () => { mockSerperClient.batchSearch.mockResolvedValueOnce(mockBatchResult); const result = await searchTools.batchSearch(mockBatchParams); expect(mockSerperClient.batchSearch).toHaveBeenCalledWith(mockBatchParams); expect(result).toEqual(mockBatchResult); }); it('should handle errors from SerperClient in batch search', async () => { const error = new Error('Batch API Error'); mockSerperClient.batchSearch.mockRejectedValueOnce(error); await expect(searchTools.batchSearch(mockBatchParams)) .rejects .toThrow(error); }); }); describe('Integration Tests', () => { // Note: These tests require a valid API key and will make real API calls // They are disabled by default and should be run manually when needed const realClient = new SerperClient(process.env.SERPER_API_KEY || ''); const realSearchTools = new SerperSearchTools(realClient); describe('search', () => { it.skip('should perform a real search with all optional parameters', async () => { const params = { q: 'Latest AI developments', gl: 'us', hl: 'en', num: 5, tbs: 'qdr:d', location: 'Silicon Valley', autocorrect: true }; const result = await realSearchTools.search(params); expect(result).toBeDefined(); expect(result.searchParameters).toEqual(params); expect(Array.isArray(result.organic)).toBe(true); expect(result.organic.length).toBeLessThanOrEqual(params.num || 10); }, 10000); }); describe('batchSearch', () => { it.skip('should perform a real batch search with varied parameters', async () => { const batchParams = [ { q: 'Web Development 2024', gl: 'us', hl: 'en', num: 3, tbs: 'qdr:m' }, { q: 'Cloud Computing Trends', gl: 'uk', hl: 'en', num: 3, location: 'London' } ]; const result = await realSearchTools.batchSearch(batchParams); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); expect(result.length).toBe(2); // Check first query results expect(result[0].searchParameters).toEqual(batchParams[0]); expect(result[0].organic.length).toBeLessThanOrEqual(batchParams[0].num || 10); // Check second query results expect(result[1].searchParameters).toEqual(batchParams[1]); expect(result[1].organic.length).toBeLessThanOrEqual(batchParams[1].num || 10); }, 15000); }); }); });