2026-05-23 03:21:55 +02:00
|
|
|
import devplacepy.main as m
|
|
|
|
|
from starlette.testclient import TestClient
|
|
|
|
|
|
|
|
|
|
|
2026-06-06 16:31:42 +02:00
|
|
|
def _patch_limits(monkeypatch, limit, window=60):
|
|
|
|
|
def fake_get_int_setting(key, default):
|
|
|
|
|
return {"rate_limit_per_minute": limit, "rate_limit_window_seconds": window}.get(key, default)
|
|
|
|
|
monkeypatch.setattr(m, "get_int_setting", fake_get_int_setting)
|
2026-05-23 03:21:55 +02:00
|
|
|
m._rate_limit_store.clear()
|
2026-06-06 16:31:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_rate_limit_blocks_excess(monkeypatch):
|
|
|
|
|
_patch_limits(monkeypatch, 3)
|
2026-05-23 03:21:55 +02:00
|
|
|
client = TestClient(m.app)
|
|
|
|
|
codes = [client.post("/", headers={"X-Real-IP": "9.9.9.9"}).status_code for _ in range(6)]
|
|
|
|
|
assert 429 in codes, codes
|
|
|
|
|
assert codes[-1] == 429
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_rate_limit_is_per_ip(monkeypatch):
|
2026-06-06 16:31:42 +02:00
|
|
|
_patch_limits(monkeypatch, 2)
|
2026-05-23 03:21:55 +02:00
|
|
|
client = TestClient(m.app)
|
|
|
|
|
for _ in range(2):
|
|
|
|
|
client.post("/", headers={"X-Real-IP": "1.1.1.1"})
|
|
|
|
|
blocked = client.post("/", headers={"X-Real-IP": "1.1.1.1"}).status_code
|
|
|
|
|
other_ip = client.post("/", headers={"X-Real-IP": "2.2.2.2"}).status_code
|
|
|
|
|
assert blocked == 429
|
|
|
|
|
assert other_ip != 429
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_requests_not_rate_limited(monkeypatch):
|
2026-06-06 16:31:42 +02:00
|
|
|
_patch_limits(monkeypatch, 2)
|
2026-05-23 03:21:55 +02:00
|
|
|
client = TestClient(m.app)
|
|
|
|
|
codes = [client.get("/robots.txt", headers={"X-Real-IP": "3.3.3.3"}).status_code for _ in range(5)]
|
|
|
|
|
assert all(c == 200 for c in codes), codes
|
2026-06-06 16:31:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_rate_limit_reads_configured_setting(monkeypatch):
|
|
|
|
|
_patch_limits(monkeypatch, 1)
|
|
|
|
|
client = TestClient(m.app)
|
|
|
|
|
first = client.post("/", headers={"X-Real-IP": "7.7.7.7"}).status_code
|
|
|
|
|
second = client.post("/", headers={"X-Real-IP": "7.7.7.7"}).status_code
|
|
|
|
|
assert first != 429
|
|
|
|
|
assert second == 429
|