| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- <?php
- declare(strict_types=1);
- namespace App\Tests\Unit\Reputation;
- use App\Domain\Ip\Cidr;
- use App\Domain\Ip\IpAddress;
- use App\Domain\Reputation\CidrEvaluator;
- use PHPUnit\Framework\TestCase;
- /**
- * Unit-level coverage of the in-memory containment math: v4, v6, IPv4
- * mapped into v6, and the empty-evaluator no-op shape.
- */
- final class CidrEvaluatorTest extends TestCase
- {
- public function testEmptyEvaluatorMatchesNothing(): void
- {
- $evaluator = new CidrEvaluator([], [], [], []);
- $ip = IpAddress::fromString('203.0.113.42');
- self::assertFalse($evaluator->isAllowlisted($ip));
- self::assertFalse($evaluator->isManuallyBlocked($ip));
- self::assertSame([], $evaluator->manualBlockedSubnets());
- self::assertSame([], $evaluator->allowlistedSubnets());
- }
- public function testSingleIpManualBlockMatches(): void
- {
- $bin = IpAddress::fromString('203.0.113.42')->binary();
- $evaluator = new CidrEvaluator([$bin], [], [], []);
- self::assertTrue($evaluator->isManuallyBlocked(IpAddress::fromString('203.0.113.42')));
- self::assertFalse($evaluator->isManuallyBlocked(IpAddress::fromString('203.0.113.43')));
- }
- public function testV4SubnetContainsHostV4(): void
- {
- $cidr = Cidr::fromString('203.0.113.0/24');
- $evaluator = new CidrEvaluator([], [$cidr], [], []);
- self::assertTrue($evaluator->isManuallyBlocked(IpAddress::fromString('203.0.113.42')));
- self::assertFalse($evaluator->isManuallyBlocked(IpAddress::fromString('203.0.114.42')));
- }
- public function testV6SubnetContainsV6Host(): void
- {
- $cidr = Cidr::fromString('2001:db8::/32');
- $evaluator = new CidrEvaluator([], [$cidr], [], []);
- self::assertTrue($evaluator->isManuallyBlocked(IpAddress::fromString('2001:db8::1')));
- self::assertTrue($evaluator->isManuallyBlocked(IpAddress::fromString('2001:db8:abcd::42')));
- self::assertFalse($evaluator->isManuallyBlocked(IpAddress::fromString('2001:db9::1')));
- }
- public function testIpv4MappedV6RoundTripsAsV4(): void
- {
- // Per IpAddress: ::ffff:203.0.113.42 normalizes to the v4-mapped binary
- // of 203.0.113.42 — i.e. it should match a v4 /24 manual block.
- $cidr = Cidr::fromString('203.0.113.0/24');
- $evaluator = new CidrEvaluator([], [$cidr], [], []);
- $ip = IpAddress::fromString('::ffff:203.0.113.42');
- self::assertTrue($evaluator->isManuallyBlocked($ip));
- }
- public function testAllowlistAndBlockOverlapAreIndependent(): void
- {
- // Both lists "see" the same IP — the evaluator just reports each
- // independently. SPEC §5 precedence is the responsibility of the
- // caller (EffectiveStatusService).
- $bin = IpAddress::fromString('198.51.100.5')->binary();
- $evaluator = new CidrEvaluator([$bin], [], [$bin], []);
- $ip = IpAddress::fromString('198.51.100.5');
- self::assertTrue($evaluator->isManuallyBlocked($ip));
- self::assertTrue($evaluator->isAllowlisted($ip));
- }
- public function testManualBlockedSubnetsExposesSingleEntryForLargeCidr(): void
- {
- $cidr = Cidr::fromString('10.0.0.0/16');
- $evaluator = new CidrEvaluator([], [$cidr], [], []);
- self::assertCount(1, $evaluator->manualBlockedSubnets());
- self::assertSame('10.0.0.0/16', $evaluator->manualBlockedSubnets()[0]->text());
- }
- public function testAllowlistedSubnetsExposesEntries(): void
- {
- $a = Cidr::fromString('10.0.0.0/8');
- $b = Cidr::fromString('192.168.0.0/16');
- $evaluator = new CidrEvaluator([], [], [], [$a, $b]);
- self::assertCount(2, $evaluator->allowlistedSubnets());
- }
- }
|