<?php
use PHPUnit\Framework\TestCase;
use SHServ\Tools\RateLimiter;
class RateLimiterTest extends TestCase {
private ?RateLimiter $limiter = null;
protected function tearDown(): void {
if ($this -> limiter !== null) {
$this -> limiter -> clear();
}
}
public function test_allows_requests_within_limit(): void {
$this -> limiter = new RateLimiter(5, 60);
for ($i = 0; $i < 5; $i++) {
$this -> assertTrue($this -> limiter -> check('ip1'));
}
}
public function test_blocks_excess_requests(): void {
$this -> limiter = new RateLimiter(3, 60);
for ($i = 0; $i < 3; $i++) {
$this -> limiter -> check('ip2');
}
$this -> assertFalse($this -> limiter -> check('ip2'));
}
public function test_resets_after_window(): void {
$this -> limiter = new RateLimiter(2, 1);
$this -> assertTrue($this -> limiter -> check('ip3'));
$this -> assertTrue($this -> limiter -> check('ip3'));
$this -> assertFalse($this -> limiter -> check('ip3'));
sleep(2);
$this -> assertTrue($this -> limiter -> check('ip3'));
}
public function test_different_keys_are_independent(): void {
$this -> limiter = new RateLimiter(1, 60);
$this -> assertTrue($this -> limiter -> check('ip_a'));
$this -> assertTrue($this -> limiter -> check('ip_b'));
}
public function test_file_storage_shared_across_instances(): void {
$tmpFile = sys_get_temp_dir() . '/rl-test-' . uniqid() . '.json';
$limiterA = new RateLimiter(2, 60, $tmpFile);
$limiterB = new RateLimiter(2, 60, $tmpFile);
$this -> assertTrue($limiterA -> check('shared'));
$this -> assertTrue($limiterB -> check('shared'));
$this -> assertFalse($limiterA -> check('shared'));
unlink($tmpFile);
}
}