import { jest } from '@jest/globals';
import searchService from '../src/services/searchService.js';
// Mock Puppeteer
jest.mock('puppeteer', () => ({
launch: jest.fn().mockResolvedValue({
newPage: jest.fn().mockResolvedValue({
setUserAgent: jest.fn(),
setViewport: jest.fn(),
goto: jest.fn(),
waitForSelector: jest.fn(),
evaluate: jest.fn().mockResolvedValue([]),
close: jest.fn()
}),
close: jest.fn()
})
}));
// Mock Axios
jest.mock('axios', () => ({
get: jest.fn().mockResolvedValue({
data: '<html><body><div class="result"><a class="result__title">Test Result</a></div></body></html>'
})
}));
// Mock Cheerio
jest.mock('cheerio', () => ({
load: jest.fn().mockReturnValue({
find: jest.fn().mockReturnValue({
each: jest.fn(),
text: jest.fn().mockReturnValue('Test Title'),
attr: jest.fn().mockReturnValue('https://example.com')
}),
text: jest.fn().mockReturnValue('Test content'),
attr: jest.fn().mockReturnValue('Test description')
})
}));
describe('SearchService', () => {
beforeEach(() => {
jest.clearAllMocks();
});
describe('getRandomUserAgent', () => {
it('should return a valid user agent', () => {
const userAgent = searchService.getRandomUserAgent();
expect(typeof userAgent).toBe('string');
expect(userAgent.length).toBeGreaterThan(0);
});
});
describe('searchGoogle', () => {
it('should perform Google search successfully', async () => {
const mockPage = {
setUserAgent: jest.fn(),
setViewport: jest.fn(),
goto: jest.fn(),
waitForSelector: jest.fn(),
evaluate: jest.fn().mockResolvedValue([
{
title: 'Test Result',
url: 'https://example.com',
snippet: 'Test snippet',
rank: 1
}
]),
close: jest.fn()
};
const mockBrowser = {
newPage: jest.fn().mockResolvedValue(mockPage)
};
searchService.browser = mockBrowser;
const result = await searchService.searchGoogle('test query', 5);
expect(result).toHaveProperty('engine', 'Google');
expect(result).toHaveProperty('query', 'test query');
expect(result).toHaveProperty('results');
expect(result.results).toHaveLength(1);
expect(mockPage.close).toHaveBeenCalled();
});
it('should handle Google search errors', async () => {
const mockPage = {
setUserAgent: jest.fn(),
setViewport: jest.fn(),
goto: jest.fn().mockRejectedValue(new Error('Network error')),
close: jest.fn()
};
const mockBrowser = {
newPage: jest.fn().mockResolvedValue(mockPage)
};
searchService.browser = mockBrowser;
await expect(searchService.searchGoogle('test query')).rejects.toThrow('Google search failed: Network error');
});
});
describe('searchBing', () => {
it('should perform Bing search successfully', async () => {
const mockPage = {
setUserAgent: jest.fn(),
setViewport: jest.fn(),
goto: jest.fn(),
waitForSelector: jest.fn(),
evaluate: jest.fn().mockResolvedValue([
{
title: 'Bing Result',
url: 'https://bing.example.com',
snippet: 'Bing snippet',
rank: 1
}
]),
close: jest.fn()
};
const mockBrowser = {
newPage: jest.fn().mockResolvedValue(mockPage)
};
searchService.browser = mockBrowser;
const result = await searchService.searchBing('test query', 5);
expect(result).toHaveProperty('engine', 'Google');
expect(result).toHaveProperty('query', 'test query');
expect(result).toHaveProperty('results');
expect(result.results).toHaveLength(1);
expect(mockPage.close).toHaveBeenCalled();
});
});
describe('searchDuckDuckGo', () => {
it('should perform DuckDuckGo search successfully', async () => {
const result = await searchService.searchDuckDuckGo('test query', 5);
expect(result).toHaveProperty('engine', 'DuckDuckGo');
expect(result).toHaveProperty('query', 'test query');
expect(result).toHaveProperty('results');
});
});
describe('multiSearch', () => {
it('should perform multi-engine search', async () => {
const mockPage = {
setUserAgent: jest.fn(),
setViewport: jest.fn(),
goto: jest.fn(),
waitForSelector: jest.fn(),
evaluate: jest.fn().mockResolvedValue([]),
close: jest.fn()
};
const mockBrowser = {
newPage: jest.fn().mockResolvedValue(mockPage)
};
searchService.browser = mockBrowser;
const result = await searchService.multiSearch('test query', ['google', 'bing'], 5);
expect(result).toHaveProperty('query', 'test query');
expect(result).toHaveProperty('engines');
expect(result.engines).toContain('google');
expect(result.engines).toContain('bing');
});
});
describe('scrapeWebpage', () => {
it('should scrape webpage successfully', async () => {
const result = await searchService.scrapeWebpage('https://example.com');
expect(result).toHaveProperty('url', 'https://example.com');
expect(result).toHaveProperty('title');
expect(result).toHaveProperty('content');
expect(result).toHaveProperty('links');
});
it('should handle scraping errors', async () => {
// Mock axios to throw an error
const axios = await import('axios');
axios.default.get.mockRejectedValueOnce(new Error('Connection failed'));
await expect(searchService.scrapeWebpage('https://invalid-url.com')).rejects.toThrow('Failed to scrape webpage: Connection failed');
});
});
});