assertAllowed('ollama', 'local', 'http://127.0.0.1:11434/v1'); $this->expectException(InvalidArgumentException::class); $policy->assertAllowed('ollama', 'local', 'http://169.254.169.254:11434/v1'); } public function test_custom_online_provider_requires_an_exact_allowlisted_host(): void { $policy = new AiEndpointPolicy(customProviderHosts: ['allowed.example.test']); $policy->assertAllowed('openai_compatible', 'online', 'https://allowed.example.test/v1'); $this->expectException(InvalidArgumentException::class); $policy->assertAllowed('openai_compatible', 'online', 'https://other.example.test/v1'); } public function test_dns_results_fail_closed_if_any_address_is_not_public(): void { $policy = new AiEndpointPolicy( resolver: fn (string $host): array => ['93.184.216.34', '127.0.0.1'], customProviderHosts: ['allowed.example.test'], ); $this->expectException(InvalidArgumentException::class); $policy->requestOptions('openai_compatible', 'online', 'https://allowed.example.test/v1'); } public function test_outbound_requests_pin_dns_and_disable_redirects(): void { $policy = new AiEndpointPolicy( resolver: fn (string $host): array => ['93.184.216.34'], customProviderHosts: ['allowed.example.test'], ); $options = $policy->requestOptions('openai_compatible', 'online', 'https://allowed.example.test/v1'); $this->assertFalse($options['allow_redirects']); $this->assertSame( ['allowed.example.test:443:93.184.216.34'], $options['curl'][constant('CURLOPT_RESOLVE')], ); } }