Skip to content

Commit 332cd3f

Browse files
committed
Added more tests for strategies and rate_limiter
1 parent 3e673f3 commit 332cd3f

File tree

3 files changed

+104
-22
lines changed

3 files changed

+104
-22
lines changed

backend/tests/rate_limiter/test_ip_strategy.py

Lines changed: 0 additions & 21 deletions
This file was deleted.

backend/tests/rate_limiter/test_sliding_window_logic.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
from unittest.mock import AsyncMock
1+
from unittest.mock import AsyncMock, MagicMock, patch
22

33
import pytest
44

5+
from app.core.rate_limiter.rate_limiting_algorithm.registry import get_rate_limiter
56
from app.core.rate_limiter.rate_limiting_algorithm.sliding_window import (
67
SlidingWindowRateLimiter,
78
)
89

10+
@pytest.fixture
11+
def mock_redis_from_url():
12+
with patch("redis.asyncio.from_url") as mocker:
13+
mock_instance = MagicMock()
14+
mocker.return_value = mock_instance
15+
yield mocker
916

1017
@pytest.mark.asyncio
1118
async def test_allow_first_request():
@@ -40,3 +47,50 @@ async def test_fail_open_allows_requests():
4047

4148
assert allowed is True
4249
assert retry_after is None
50+
51+
def test_get_rate_limiter_none_strategy(mock_redis_from_url):
52+
rl = get_rate_limiter(strategy="none", redis_url="redis://localhost:6379/0", fail_open=True)
53+
assert rl is None
54+
55+
56+
def test_get_rate_limiter_empty_strategy(mock_redis_from_url):
57+
rl = get_rate_limiter(strategy="", redis_url="redis://localhost:6379/0", fail_open=True)
58+
assert rl is None
59+
60+
61+
def test_get_rate_limiter_null_strategy(mock_redis_from_url):
62+
rl = get_rate_limiter(strategy="null", redis_url="redis://localhost:6379/0", fail_open=True)
63+
assert rl is None
64+
65+
66+
def test_get_rate_limiter_no_strategy(mock_redis_from_url):
67+
rl = get_rate_limiter(strategy=None, redis_url="redis://localhost:6379/0", fail_open=True)
68+
assert rl is None
69+
70+
71+
def test_get_rate_limiter_no_redis_url(mock_redis_from_url):
72+
rl = get_rate_limiter(strategy="sliding_window", redis_url="", fail_open=True)
73+
assert rl is None
74+
75+
76+
def test_get_rate_limiter_sliding_window(mock_redis_from_url):
77+
rl = get_rate_limiter(strategy="sliding_window", redis_url="redis://x", fail_open=True)
78+
assert isinstance(rl, SlidingWindowRateLimiter)
79+
80+
81+
def test_get_rate_limiter_sliding_window_dash(mock_redis_from_url):
82+
rl = get_rate_limiter(strategy="sliding-window", redis_url="redis://x", fail_open=False)
83+
assert isinstance(rl, SlidingWindowRateLimiter)
84+
assert rl.get_fail_open() is False
85+
86+
87+
def test_get_rate_limiter_fail_open_coercion(mock_redis_from_url):
88+
rl = get_rate_limiter(strategy="sliding_window", redis_url="redis://x", fail_open=None)
89+
assert isinstance(rl, SlidingWindowRateLimiter)
90+
assert rl.get_fail_open() is False # default fallback
91+
92+
93+
def test_rate_limiter_unknown_strategy(mock_redis_from_url):
94+
with pytest.raises(ValueError) as e:
95+
get_rate_limiter(strategy="weird_strategy", redis_url="redis://x", fail_open=True)
96+
assert "Unknown rate limiter strategy" in str(e.value)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
from starlette.requests import Request
3+
4+
from app.core.rate_limiter.key_strategy.header_key_strategy import HeaderKeyStrategy
5+
from app.core.rate_limiter.key_strategy.ip_key_strategy import IPKeyStrategy
6+
from app.core.rate_limiter.key_strategy.key_strategy_enum import KeyStrategyName
7+
from app.core.rate_limiter.key_strategy.key_strategy_registry import get_key_strategy
8+
9+
10+
def test_ip_strategy_build_key():
11+
strat = IPKeyStrategy()
12+
13+
scope = {
14+
"client": ("127.0.0.1", 5050),
15+
"method": "GET",
16+
"path": "/api/test",
17+
"headers": [],
18+
"type": "http"
19+
}
20+
request = Request(scope)
21+
22+
key = strat.get_key(request, scope.get('path'))
23+
24+
assert key.startswith("ip:127.0.0.1")
25+
assert ":/api/test" in key
26+
27+
def test_get_key_strategy_header_default():
28+
"""
29+
Should return HeaderKeyStrategy with default header name
30+
when header_name is not provided.
31+
"""
32+
ks = get_key_strategy(KeyStrategyName.HEADER)
33+
assert isinstance(ks, HeaderKeyStrategy)
34+
assert ks.header_name == "X-Client-ID"
35+
36+
37+
def test_get_key_strategy_header_custom():
38+
"""Should use user-supplied custom header name."""
39+
ks = get_key_strategy(KeyStrategyName.HEADER, header_name="X-Auth-ID")
40+
assert isinstance(ks, HeaderKeyStrategy)
41+
assert ks.header_name == "X-Auth-ID"
42+
43+
44+
def test_get_key_strategy_invalid():
45+
"""Should throw ValueError for unsupported key strategies."""
46+
with pytest.raises(ValueError) as e:
47+
get_key_strategy("UNKNOWN") # type: ignore[arg-type]
48+
49+
assert "Unsupported key strategy" in str(e.value)

0 commit comments

Comments
 (0)