Files
pixel/backend/tests/test_rate_limiter_unit.py
张鹏 f9f4560459 Initial commit: Pixel AI comic/video creation platform
- FastAPI backend with SQLModel, Alembic migrations, AgentScope agents
- Next.js 15 frontend with React 19, Tailwind, Zustand, React Flow
- Multi-provider AI system (DashScope, Kling, MiniMax, Volcengine, OpenAI, etc.)
- All HTTP clients migrated from sync requests to async httpx
- Admin-managed API keys via environment variables
- SSRF vulnerability fixed in ensure_url()
2026-04-29 01:20:12 +08:00

46 lines
1.7 KiB
Python

import pytest
from src.middlewares.rate_limiter import RateLimiter
class TestRateLimiterPathNormalization:
def test_get_rate_limit_matches_versioned_api_prefix(self):
limiter = RateLimiter()
limit, window = limiter.get_rate_limit("/api/v1/generations/image")
assert (limit, window) == (10, 60)
def test_normalize_path_reduces_dynamic_segments(self):
limiter = RateLimiter()
assert limiter._normalize_path("/api/v1/projects/123") == "/projects/{id}"
assert (
limiter._normalize_path("/api/v1/tasks/550e8400-e29b-41d4-a716-446655440000")
== "/tasks/{id}"
)
@pytest.mark.asyncio
class TestRateLimiterLocalFallback:
async def test_local_fallback_limits_critical_endpoint_when_redis_unavailable(self):
limiter = RateLimiter()
limiter._connected = False
limiter.rate_limits["/generations/image"] = (2, 60)
limited_1, _, _, _ = await limiter.is_rate_limited("ip:test", "/api/v1/generations/image")
limited_2, _, _, _ = await limiter.is_rate_limited("ip:test", "/api/v1/generations/image")
limited_3, _, limit, _ = await limiter.is_rate_limited("ip:test", "/api/v1/generations/image")
assert limited_1 is False
assert limited_2 is False
assert limited_3 is True
assert limit == 2
async def test_local_fallback_not_used_for_non_critical_endpoint(self):
limiter = RateLimiter()
limiter._connected = False
limited, count, limit, reset = await limiter.is_rate_limited("ip:test", "/api/v1/health")
assert limited is False
assert count == 0
assert limit == 0
assert reset == 0