"""限流器测试."""


from src.ai.rate_limiter import RateLimiter, RateLimitResult


class TestRateLimiterDegraded:
    """Redis 不可用时的降级行为（全并行模式）."""

    async def test_no_redis_allows_all(self) -> None:
        """Redis=None 时降级放行."""
        limiter = RateLimiter(redis=None)
        results = await limiter.check(user_id="u-1", ip="1.2.3.4", school_id="s-1")
        assert len(results) == 3
        assert all(r.allowed for r in results)

    async def test_no_redis_no_identifiers(self) -> None:
        """无任何标识符时返回空列表."""
        limiter = RateLimiter(redis=None)
        results = await limiter.check()
        assert results == []

    async def test_no_redis_only_user(self) -> None:
        """仅 user_id."""
        limiter = RateLimiter(redis=None)
        results = await limiter.check(user_id="u-1")
        assert len(results) == 1
        assert results[0].dimension == "user"
        assert results[0].allowed is True
        assert results[0].remaining == 10  # default user_limit

    async def test_no_redis_only_ip(self) -> None:
        """仅 ip."""
        limiter = RateLimiter(redis=None)
        results = await limiter.check(ip="1.2.3.4")
        assert len(results) == 1
        assert results[0].dimension == "ip"
        assert results[0].limit == 30

    async def test_no_redis_only_school(self) -> None:
        """仅 school_id."""
        limiter = RateLimiter(redis=None)
        results = await limiter.check(school_id="s-1")
        assert len(results) == 1
        assert results[0].dimension == "school"
        assert results[0].limit == 100


class TestRateLimitResult:
    """RateLimitResult dataclass 测试."""

    def test_default_values(self) -> None:
        result = RateLimitResult(allowed=True, dimension="user", limit=10, remaining=5)
        assert result.allowed is True
        assert result.remaining == 5

    def test_denied(self) -> None:
        result = RateLimitResult(allowed=False, dimension="ip", limit=30, remaining=0)
        assert result.allowed is False
