research('sys', 'user'))->toBe('[]'); }); it('шлёт system+user в chat/completions и возвращает content', function () { Config::set('services.aitunnel', [ 'key' => 'test-key', 'base_url' => 'https://api.aitunnel.ru/v1', 'research_model' => 'sonar-reasoning-pro', 'research_timeout_sec' => 120, ]); $http = app(HttpFactory::class); $http->fake([ '*/chat/completions' => $http->response([ 'choices' => [['message' => ['content' => '[{"name":"CarMoney","type":"федеральная"}]']]], ], 200), ]); $r = new AitunnelResearcher($http); $out = $r->research('SYS-PROMPT', 'USER-PROMPT'); expect($out)->toContain('CarMoney'); $http->assertSent(function ($request) { $body = $request->data(); return str_contains($request->url(), '/chat/completions') && $body['model'] === 'sonar-reasoning-pro' && $body['messages'][0]['role'] === 'system' && $body['messages'][0]['content'] === 'SYS-PROMPT' && $body['messages'][1]['role'] === 'user' && $body['messages'][1]['content'] === 'USER-PROMPT'; }); }); it('при ошибке сети возвращает пустой массив', function () { Config::set('services.aitunnel.key', 'test-key'); $http = app(HttpFactory::class); $http->fake(['*/chat/completions' => $http->response('boom', 500)]); $r = new AitunnelResearcher($http); expect($r->research('sys', 'user'))->toBe('[]'); });