feat: add early Telegram anti-flood guard
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from bot.middlewares.update_antiflood import RateLimitRule, UpdateAntiFloodMiddleware
|
||||
|
||||
|
||||
def _settings(**overrides):
|
||||
base = {
|
||||
"REDIS_URL": None,
|
||||
"REDIS_KEY_PREFIX": "test-shop",
|
||||
"TELEGRAM_ANTIFLOOD_ENABLED": True,
|
||||
"TELEGRAM_ANTIFLOOD_WINDOW_SECONDS": 60,
|
||||
"TELEGRAM_ANTIFLOOD_MAX_UPDATES_PER_WINDOW": 180,
|
||||
}
|
||||
base.update(overrides)
|
||||
return SimpleNamespace(**base)
|
||||
|
||||
|
||||
def _message_update(*, user_id=42, chat_id=42, chat_type="private", text="hello"):
|
||||
return SimpleNamespace(
|
||||
event_type="message",
|
||||
message=SimpleNamespace(
|
||||
from_user=SimpleNamespace(id=user_id),
|
||||
chat=SimpleNamespace(id=chat_id, type=chat_type),
|
||||
text=text,
|
||||
),
|
||||
callback_query=None,
|
||||
inline_query=None,
|
||||
)
|
||||
|
||||
|
||||
class UpdateAntiFloodMiddlewareTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_extreme_update_flood_is_dropped_before_handler(self):
|
||||
middleware = UpdateAntiFloodMiddleware(
|
||||
_settings(),
|
||||
default_rule=RateLimitRule(window_seconds=60, max_events=2),
|
||||
)
|
||||
handler = AsyncMock(return_value="ok")
|
||||
event = _message_update()
|
||||
|
||||
with patch("bot.middlewares.update_antiflood.get_redis", AsyncMock(return_value=None)):
|
||||
self.assertEqual(await middleware(handler, event, {}), "ok")
|
||||
self.assertEqual(await middleware(handler, event, {}), "ok")
|
||||
self.assertIsNone(await middleware(handler, event, {}))
|
||||
|
||||
self.assertEqual(handler.await_count, 2)
|
||||
|
||||
async def test_antiflood_can_be_disabled(self):
|
||||
middleware = UpdateAntiFloodMiddleware(
|
||||
_settings(TELEGRAM_ANTIFLOOD_ENABLED=False),
|
||||
default_rule=RateLimitRule(window_seconds=60, max_events=0),
|
||||
)
|
||||
handler = AsyncMock(return_value="ok")
|
||||
|
||||
with patch("bot.middlewares.update_antiflood.get_redis", AsyncMock(return_value=None)):
|
||||
self.assertEqual(await middleware(handler, _message_update(), {}), "ok")
|
||||
|
||||
handler.assert_awaited_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user