"""Tests for server-directed waits and exponential fallback delays.""" import pytest from mangacollec.retry_policy import RetryPolicy class TestDelayForRetry: """Verify the delay policy independently of HTTP requests.""" @pytest.mark.parametrize("retry_count", [1, 5]) @pytest.mark.parametrize("retry_after, expected", [ ("120", 126.0), ("8", 8.4), ("1", 1.05), ("0", 0.0), (" 120 ", 126.0), ("00120", 126.0), ]) def test_server_delay(self, retry_count: int, retry_after: str, expected: float) -> None: """Use server seconds plus five percent, without the fallback's cap.""" delay = RetryPolicy.delay_for_retry(retry_count, retry_after=retry_after) assert delay == pytest.approx(expected) @pytest.mark.parametrize("retry_after", [ None, "", " ", "-1", "+1", "1.5", "1e2", "invalid", "NaN", "Infinity", "١٢٠", "120, 60", "Fri, 31 Dec 1999 23:59:59 GMT", ]) def test_invalid_header(self, retry_after: str | None) -> None: """Fall back for missing headers and values outside the seconds format.""" assert RetryPolicy.delay_for_retry(1, retry_after=retry_after) == 0.5 assert RetryPolicy.delay_for_retry(5, retry_after=retry_after) == 8.0 @pytest.mark.parametrize("retry_after", [ pytest.param("9" * 400, id="non-finite-seconds"), pytest.param("179" + "0" * 306, id="non-finite-margin"), pytest.param("9" * 5000, id="oversized-number"), ]) def test_non_finite_delay(self, retry_after: str) -> None: """Avoid passing infinite delays to the asynchronous wait.""" assert RetryPolicy.delay_for_retry(1, retry_after=retry_after) == 0.5 @pytest.mark.parametrize("retry_count, expected", [ (1, 0.5), (2, 1.0), (3, 2.0), (4, 4.0), (5, 8.0), (6, 8.0), ]) def test_exponential_fallback(self, retry_count: int, expected: float) -> None: """Keep the existing exponential delays and maximum intact.""" assert RetryPolicy.delay_for_retry(retry_count) == expected @pytest.mark.parametrize("retry_count", [0, -1]) @pytest.mark.parametrize("retry_after", [None, "120"]) def test_invalid_retry_count(self, retry_count: int, retry_after: str | None) -> None: """Validate the retry number even when the server supplies a delay.""" with pytest.raises(ValueError): RetryPolicy.delay_for_retry(retry_count, retry_after=retry_after)