diff --git a/.env.example b/.env.example index e4e5646..f0b307e 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,7 @@ DISCORD_TOKEN=your_bot_token_here MORNING_TIME=07:00 MORNING_CHANNEL_ID=channel_id LOG_LEVEL=INFO +CAT_API_KEY=your_cat_api_key_here CAT_API_RATE=1 CAT_API_BURST=3 WEATHER_API_RATE=1 diff --git a/tests/test_fetch_cat.py b/tests/test_fetch_cat.py index 9f31afe..4a5bb79 100644 --- a/tests/test_fetch_cat.py +++ b/tests/test_fetch_cat.py @@ -97,3 +97,28 @@ class TestFetchCat: mock_get.return_value = mock_response result = await fetch_cat() assert result == "https://example.com/cat?w=100&h=200" + + @patch("utils.cat._session.get") + @patch("utils.cat._cat_api_key", "test-api-key-123") + async def test_fetch_cat_sends_api_key_header(self, mock_get) -> None: + """При заданном CAT_API_KEY должен передаваться заголовок x-api-key.""" + mock_response = MagicMock() + mock_response.json.return_value = [{"url": "https://example.com/cat.jpg"}] + mock_response.raise_for_status = MagicMock() + mock_get.return_value = mock_response + await fetch_cat() + # Проверяем, что headers переданы с x-api-key + call_kwargs = mock_get.call_args + assert call_kwargs[1].get("headers") == {"x-api-key": "test-api-key-123"} + + @patch("utils.cat._session.get") + @patch("utils.cat._cat_api_key", None) + async def test_fetch_cat_no_api_key_header(self, mock_get) -> None: + """При отсутствии CAT_API_KEY заголовок x-api-key не передаётся.""" + mock_response = MagicMock() + mock_response.json.return_value = [{"url": "https://example.com/cat.jpg"}] + mock_response.raise_for_status = MagicMock() + mock_get.return_value = mock_response + await fetch_cat() + call_kwargs = mock_get.call_args + assert call_kwargs[1].get("headers") is None diff --git a/utils/cat.py b/utils/cat.py index 8179376..0b4867f 100644 --- a/utils/cat.py +++ b/utils/cat.py @@ -1,5 +1,6 @@ import asyncio import logging +import os import requests @@ -8,6 +9,7 @@ from utils.rate_limiter import cat_limiter logger = logging.getLogger(__name__) CAT_API_URL = "https://api.thecatapi.com/v1/images/search" +_cat_api_key: str | None = os.getenv("CAT_API_KEY") _session = requests.Session() @@ -15,8 +17,13 @@ _session = requests.Session() async def fetch_cat() -> str | None: """Получить URL случайного котика. Вернуть None при ошибке.""" await cat_limiter.acquire() + headers: dict[str, str] | None = None + if _cat_api_key: + headers = {"x-api-key": _cat_api_key} try: - response = await asyncio.to_thread(_session.get, CAT_API_URL, timeout=10) + response = await asyncio.to_thread( + _session.get, CAT_API_URL, timeout=10, headers=headers + ) response.raise_for_status() data = response.json() return data[0]["url"]