import asyncio import json import pytest from unittest.mock import patch, MagicMock from utils.cat import fetch_cat class TestFetchCat: """Тесты функции fetch_cat() — получение URL случайного котика.""" @patch("utils.cat._session.get") def test_fetch_cat_success(self, mock_get): """Успешный ответ с URL должен вернуть строку.""" 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 result = asyncio.run(fetch_cat()) assert result == "https://example.com/cat.jpg" @patch("utils.cat._session.get") def test_fetch_cat_empty_array(self, mock_get): """Пустой массив должен вернуть None.""" mock_response = MagicMock() mock_response.json.return_value = [] mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_http_error(self, mock_get): """HTTP-ошибка (raise_for_status) должна вернуть None.""" import requests mock_response = MagicMock() mock_response.raise_for_status.side_effect = requests.HTTPError("404 Not Found") mock_get.return_value = mock_response result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_connection_error(self, mock_get): """ConnectionError должна вернуть None.""" from requests.exceptions import ConnectionError mock_get.side_effect = ConnectionError("No connection") result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_timeout(self, mock_get): """Timeout должна вернуть None.""" from requests.exceptions import Timeout mock_get.side_effect = Timeout("Request timed out") result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_ssl_error(self, mock_get): """SSLError должна вернуть None.""" from requests.exceptions import SSLError mock_get.side_effect = SSLError("SSL handshake failed") result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_json_parse_error(self, mock_get): """Ошибка парсинга JSON должна вернуть None.""" import requests mock_response = MagicMock() mock_response.json.side_effect = requests.JSONDecodeError("Expecting value", "", 0) mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_missing_url_key(self, mock_get): """Отсутствие ключа 'url' в ответе должно вернуть None.""" mock_response = MagicMock() mock_response.json.return_value = [{"error": "no image"}] mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_request_exception(self, mock_get): """Общий RequestException должен вернуть None.""" import requests mock_get.side_effect = requests.RequestException("Generic error") result = asyncio.run(fetch_cat()) assert result is None @patch("utils.cat._session.get") def test_fetch_cat_url_with_special_chars(self, mock_get): """URL со спецсимволами должен вернуться как есть.""" mock_response = MagicMock() mock_response.json.return_value = [{"url": "https://example.com/cat?w=100&h=200"}] mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response result = asyncio.run(fetch_cat()) assert result == "https://example.com/cat?w=100&h=200"