81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
const proxyFetchMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock('@/lib/server/proxy-fetch', () => ({
|
|
proxyFetch: proxyFetchMock,
|
|
}));
|
|
|
|
import { buildSearxngSearchUrl, searchWithSearxng } from '@/lib/web-search/searxng';
|
|
|
|
describe('buildSearxngSearchUrl', () => {
|
|
it('builds JSON search URLs from instance root or /search base paths', () => {
|
|
expect(buildSearxngSearchUrl('http://192.168.161.100:6060', 'hello')).toBe(
|
|
'http://192.168.161.100:6060/search?q=hello&format=json',
|
|
);
|
|
expect(buildSearxngSearchUrl('http://192.168.161.100:6060/search', 'hello')).toBe(
|
|
'http://192.168.161.100:6060/search?q=hello&format=json',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('searchWithSearxng', () => {
|
|
beforeEach(() => {
|
|
proxyFetchMock.mockReset();
|
|
});
|
|
|
|
it('requires a configured base URL', async () => {
|
|
await expect(searchWithSearxng({ query: 'test' })).rejects.toThrow(
|
|
'SearXNG base URL is not configured',
|
|
);
|
|
});
|
|
|
|
it('calls SearXNG JSON API and maps organic results', async () => {
|
|
proxyFetchMock.mockResolvedValueOnce(
|
|
new Response(
|
|
JSON.stringify({
|
|
query: 'test query',
|
|
results: [
|
|
{
|
|
title: 'First result',
|
|
url: 'https://example.com/a',
|
|
content: 'Snippet A',
|
|
score: 3.1,
|
|
},
|
|
{ title: 'Second result', url: 'https://example.com/b', content: 'Snippet B' },
|
|
],
|
|
}),
|
|
{ status: 200, headers: { 'content-type': 'application/json' } },
|
|
),
|
|
);
|
|
|
|
const result = await searchWithSearxng({
|
|
query: 'test query',
|
|
baseUrl: 'http://192.168.161.100:6060',
|
|
maxResults: 2,
|
|
});
|
|
|
|
const requestedUrl = new URL(proxyFetchMock.mock.calls[0][0] as string);
|
|
expect(requestedUrl.origin).toBe('http://192.168.161.100:6060');
|
|
expect(requestedUrl.pathname).toBe('/search');
|
|
expect(requestedUrl.searchParams.get('q')).toBe('test query');
|
|
expect(requestedUrl.searchParams.get('format')).toBe('json');
|
|
expect(proxyFetchMock.mock.calls[0][1]).toMatchObject({ method: 'GET' });
|
|
expect(result.sources).toEqual([
|
|
{
|
|
title: 'First result',
|
|
url: 'https://example.com/a',
|
|
content: 'Snippet A',
|
|
score: 3.1,
|
|
},
|
|
{
|
|
title: 'Second result',
|
|
url: 'https://example.com/b',
|
|
content: 'Snippet B',
|
|
score: 0.95,
|
|
},
|
|
]);
|
|
expect(result.query).toBe('test query');
|
|
});
|
|
});
|