enabled())->toBeFalse(); Settings::set('ai_enabled', '1'); Settings::set('ai_base_url', 'https://api.groq.test/openai/v1'); Settings::set('ai_model', 'llama-3.3-70b-versatile'); expect(app(AiClient::class)->enabled())->toBeTrue(); }); test('chat returns the assistant message content on success', function () { Settings::set('ai_enabled', '1'); Settings::set('ai_base_url', 'https://api.groq.test/openai/v1'); Settings::set('ai_model', 'llama-3.3-70b-versatile'); Http::fake([ 'api.groq.test/*' => Http::response(['choices' => [['message' => ['content' => 'hello']]]]), ]); expect(app(AiClient::class)->chat([['role' => 'user', 'content' => 'hi']]))->toBe('hello'); }); test('chat returns null on a non-successful response instead of throwing', function () { Settings::set('ai_enabled', '1'); Settings::set('ai_base_url', 'https://api.groq.test/openai/v1'); Settings::set('ai_model', 'llama-3.3-70b-versatile'); Http::fake(['api.groq.test/*' => Http::response(['error' => 'nope'], 500)]); expect(app(AiClient::class)->chat([['role' => 'user', 'content' => 'hi']]))->toBeNull(); }); test('chat sends no Authorization header when no api key is configured (self-hosted Ollama style)', function () { Settings::set('ai_enabled', '1'); Settings::set('ai_base_url', 'http://ollama.test/v1'); Settings::set('ai_model', 'llama3'); Http::fake(['ollama.test/*' => Http::response(['choices' => [['message' => ['content' => 'ok']]]])]); app(AiClient::class)->chat([['role' => 'user', 'content' => 'hi']]); Http::assertSent(fn ($request) => ! $request->hasHeader('Authorization')); }); test('testConnection reports ok on a successful response', function () { Http::fake(['api.groq.test/*' => Http::response(['choices' => [['message' => ['content' => 'pong']]]])]); $ok = app(AiClient::class)->testConnection('https://api.groq.test/openai/v1', 'key', 'llama3', true); expect($ok)->toBe(['ok' => true, 'message' => null]); }); test('testConnection reports the provider error message on failure', function () { Http::fake(['api.groq.test/*' => Http::response(['error' => ['message' => 'bad model']], 400)]); $error = app(AiClient::class)->testConnection('https://api.groq.test/openai/v1', 'key', 'bad-model', true); expect($error['ok'])->toBeFalse(); expect($error['message'])->toBe('bad model'); });