import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { resetConfig } from '../../../src/config.js';
import { resolveSearchBackend, getBootstrapState } from '../../../src/searxng/bootstrap.js';
vi.mock('../../../src/cache/db.js', () => ({
initDatabase: vi.fn(),
closeDatabase: vi.fn(),
}));
vi.mock('../../../src/fetch/browser-pool.js', () => ({
BrowserPool: class {
shutdown = vi.fn().mockResolvedValue(undefined);
acquire = vi.fn();
release = vi.fn();
},
}));
vi.mock('../../../src/fetch/http-client.js', () => ({ httpFetch: vi.fn() }));
vi.mock('../../../src/fetch/router.js', () => ({
SmartRouter: class {
constructor(_h: unknown, _b: unknown) {}
fetch = vi.fn();
getDomainStats = vi.fn();
},
}));
vi.mock('../../../src/searxng/bootstrap.js', () => ({
resolveSearchBackend: vi.fn().mockResolvedValue({ type: 'scraping' }),
getBootstrapState: vi.fn().mockReturnValue(null),
}));
vi.mock('../../../src/searxng/process.js', () => ({
SearxngProcess: vi.fn().mockImplementation(() => ({
start: vi.fn().mockResolvedValue(null),
stop: vi.fn().mockResolvedValue(undefined),
getUrl: vi.fn().mockReturnValue(null),
})),
}));
vi.mock('../../../src/repl/shell.js', () => ({
startShell: vi.fn().mockResolvedValue({ failures: 0 }),
}));
describe('runShell — sidecar gate (D1)', () => {
beforeEach(() => {
resetConfig();
vi.clearAllMocks();
vi.mocked(resolveSearchBackend).mockResolvedValue({ type: 'scraping' });
vi.mocked(getBootstrapState).mockReturnValue(null);
});
afterEach(() => {
delete process.env.WIGOLO_SEARCH;
resetConfig();
});
it('performs ZERO sidecar activity on the default core backend', async () => {
delete process.env.WIGOLO_SEARCH;
resetConfig();
const { runShell } = await import('../../../src/cli/shell.js');
await runShell(['--json']);
expect(resolveSearchBackend).not.toHaveBeenCalled();
});
it('DOES resolve the backend when WIGOLO_SEARCH=searxng and the sidecar is installed (positive control)', async () => {
process.env.WIGOLO_SEARCH = 'searxng';
resetConfig();
vi.mocked(getBootstrapState).mockReturnValue({ status: 'ready', searxngPath: '/tmp/searxng' });
const { runShell } = await import('../../../src/cli/shell.js');
await runShell(['--json']);
expect(resolveSearchBackend).toHaveBeenCalled();
});
});