Files
lotteryLaravel/tests/Unit/WalletApiRequestGuardTest.php

75 lines
3.1 KiB
PHP

<?php
use Illuminate\Http\Client\PendingRequest;
use App\Support\Integration\WalletApiRequestGuard;
use App\Support\Integration\WalletApiUrlSanitizer;
test('wallet api sanitizer rejects private and reserved literal addresses', function (string $url): void {
expect(WalletApiUrlSanitizer::normalizeAndValidate($url))->toBeNull();
})->with([
'ipv4 loopback' => 'https://127.0.0.1',
'ipv4 shortened notation' => 'https://127.1',
'ipv4 decimal integer notation' => 'https://2130706433',
'ipv4 hexadecimal notation' => 'https://0x7f000001',
'ipv4 octal notation' => 'https://0177.0.0.1',
'ipv4 private' => 'https://10.0.0.1',
'ipv4 link local' => 'https://169.254.169.254',
'ipv4 cgnat' => 'https://100.64.0.1',
'ipv4 documentation' => 'https://192.0.2.1',
'ipv6 loopback' => 'https://[::1]',
'ipv6 unique local' => 'https://[fd00::1]',
'ipv6 link local' => 'https://[fe80::1]',
'ipv6 nat64 private target' => 'https://[64:ff9b::a00:1]',
'ipv6 protocol assignment' => 'https://[2001::1]',
'ipv6 documentation' => 'https://[2001:db8::1]',
]);
test('wallet api guard rejects hostname when any dns answer is non-public', function (): void {
fakeWalletApiDns([
'wallet.example.test' => ['93.184.216.34', '10.0.0.8'],
], []);
expect(app(WalletApiRequestGuard::class)->guard('https://wallet.example.test', 10))
->toBeNull();
});
test('wallet api guard rejects unresolved hostname', function (): void {
fakeWalletApiDns([], []);
expect(app(WalletApiRequestGuard::class)->guard('https://missing.example.test', 10))
->toBeNull();
});
test('wallet api guard accepts public ipv4 and ipv6 dns answers and bounds connect timeout', function (): void {
fakeWalletApiDns([
'wallet.example.test' => ['93.184.216.34', '2606:4700:4700::1111'],
], []);
$endpoint = app(WalletApiRequestGuard::class)->guard('https://wallet.example.test:8443', 120);
expect($endpoint)->not->toBeNull()
->and($endpoint?->baseUrl)->toBe('https://wallet.example.test:8443')
->and($endpoint?->port)->toBe(8443)
->and($endpoint?->pinnedIp)->toBe('93.184.216.34')
->and($endpoint?->totalTimeoutSeconds)->toBe(120)
->and($endpoint?->connectTimeoutSeconds)->toBe(5);
$pending = $endpoint?->request(['Authorization' => 'Bearer secret']);
$optionsProperty = new ReflectionProperty(PendingRequest::class, 'options');
$options = $optionsProperty->getValue($pending);
expect($options['allow_redirects'] ?? null)->toBeFalse()
->and($options['proxy'] ?? null)->toBe('')
->and($options['timeout'] ?? null)->toBe(120)
->and($options['connect_timeout'] ?? null)->toBe(5)
->and($options['curl'][CURLOPT_RESOLVE] ?? null)
->toBe(['wallet.example.test:8443:93.184.216.34']);
});
test('wallet api sanitizer accepts normal public literals', function (): void {
expect(WalletApiUrlSanitizer::normalizeAndValidate('https://93.184.216.34'))
->toBe('https://93.184.216.34')
->and(WalletApiUrlSanitizer::normalizeAndValidate('https://[2606:4700:4700::1111]'))
->toBe('https://[2606:4700:4700::1111]');
});