create(); $this->connection($organization->id, '01J00000000000000000000001', enabled: true, default: false, createdAt: '2026-01-01 00:00:00'); $this->connection($organization->id, '01J00000000000000000000002', enabled: true, default: true, createdAt: '2026-01-02 00:00:00'); $provider = app(AiProviderResolver::class)->forOrganization($organization->id); $this->assertSame('connection:01J00000000000000000000002', $provider->id()); } public function test_disabled_deleted_and_cross_tenant_connections_cannot_be_resolved(): void { $first = Organization::factory()->create(); $second = Organization::factory()->create(); $id = '01J00000000000000000000003'; $this->connection($first->id, $id, enabled: false, default: false); $resolver = app(AiProviderResolver::class); foreach ([$first->id, $second->id] as $organizationId) { try { $resolver->byId('connection:'.$id, $organizationId); $this->fail('Unavailable connection must not resolve.'); } catch (RuntimeException) { $this->addToAssertionCount(1); } } DB::table('ai_provider_connections')->where('id', $id)->delete(); $this->expectException(RuntimeException::class); $resolver->byId('connection:'.$id, $first->id); } public function test_failed_external_provider_falls_back_to_the_local_provider_deterministically(): void { $organization = Organization::factory()->create(); $fallback = app(AiProviderResolver::class)->fallbackForOrganization($organization->id, 'connection:failed'); $this->assertNotNull($fallback); $this->assertSame('local-structuring-v1', $fallback->id()); $this->assertNull(app(AiProviderResolver::class)->fallbackForOrganization($organization->id, 'local')); } private function connection(string $organizationId, string $id, bool $enabled, bool $default, string $createdAt = '2026-01-01 00:00:00'): void { DB::table('ai_provider_connections')->insert([ 'id' => $id, 'organization_id' => $organizationId, 'name' => $id, 'provider' => 'ollama', 'mode' => 'local', 'base_url' => 'http://127.0.0.1:11434/v1', 'models' => json_encode(['qwen']), 'default_model' => 'qwen', 'timeout_seconds' => 30, 'enabled' => $enabled, 'is_default' => $default, 'created_at' => $createdAt, 'updated_at' => $createdAt, ]); } }