| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- <?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 App\Domain\Reputation\EffectiveStatus;
- use App\Domain\Reputation\EffectiveStatusService;
- use App\Infrastructure\Reputation\CidrEvaluatorFactory;
- use PHPUnit\Framework\TestCase;
- /**
- * Locks the SPEC §5 precedence: allowlist > manual block > scored > clean.
- * Score-vs-policy lands in M07; until then, anything not on a list is
- * `Clean`.
- */
- final class EffectiveStatusServiceTest extends TestCase
- {
- public function testAllowlistWinsOverManualBlock(): void
- {
- $bin = IpAddress::fromString('198.51.100.5')->binary();
- $factory = $this->factoryReturning(new CidrEvaluator(
- manualIpBins: [$bin],
- manualSubnets: [],
- allowlistIpBins: [$bin],
- allowlistSubnets: [],
- ));
- $service = new EffectiveStatusService($factory);
- self::assertSame(
- EffectiveStatus::Allowlisted,
- $service->forIp(IpAddress::fromString('198.51.100.5'))
- );
- }
- public function testManualBlockReturnedWhenNotAllowlisted(): void
- {
- $bin = IpAddress::fromString('203.0.113.42')->binary();
- $factory = $this->factoryReturning(new CidrEvaluator([$bin], [], [], []));
- $service = new EffectiveStatusService($factory);
- self::assertSame(
- EffectiveStatus::ManuallyBlocked,
- $service->forIp(IpAddress::fromString('203.0.113.42'))
- );
- }
- public function testIpInsideAllowlistedSubnetEvenWithSeparateManualBlockIsAllowlisted(): void
- {
- $allow = Cidr::fromString('203.0.113.0/24');
- $factory = $this->factoryReturning(new CidrEvaluator(
- manualIpBins: [IpAddress::fromString('203.0.113.42')->binary()],
- manualSubnets: [],
- allowlistIpBins: [],
- allowlistSubnets: [$allow],
- ));
- $service = new EffectiveStatusService($factory);
- self::assertSame(
- EffectiveStatus::Allowlisted,
- $service->forIp(IpAddress::fromString('203.0.113.42'))
- );
- }
- public function testCleanWhenNothingMatches(): void
- {
- $factory = $this->factoryReturning(new CidrEvaluator([], [], [], []));
- $service = new EffectiveStatusService($factory);
- self::assertSame(
- EffectiveStatus::Clean,
- $service->forIp(IpAddress::fromString('203.0.113.99'))
- );
- }
- private function factoryReturning(CidrEvaluator $evaluator): CidrEvaluatorFactory
- {
- return new class ($evaluator) extends CidrEvaluatorFactory {
- public function __construct(private readonly CidrEvaluator $fixed)
- {
- // Deliberately not calling parent::__construct — this stub
- // never queries the DB.
- }
- public function get(): CidrEvaluator
- {
- return $this->fixed;
- }
- public function invalidate(): void
- {
- // no-op
- }
- };
- }
- }
|