58 خطوط
2.0 KiB
PHP
58 خطوط
2.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\AI;
|
|
|
|
use App\Modules\AI\Infrastructure\AiEndpointPolicy;
|
|
use InvalidArgumentException;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class AiEndpointPolicyTest extends TestCase
|
|
{
|
|
public function test_known_local_provider_allows_only_its_loopback_port(): void
|
|
{
|
|
$policy = new AiEndpointPolicy(customProviderHosts: []);
|
|
|
|
$policy->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')],
|
|
);
|
|
}
|
|
}
|