import pytest import httpx from unittest.mock import AsyncMock, MagicMock, patch from backend.tools.api.http_request_handler import http_request class TestSuccessfulRequest: """ checks successful HTTP request, parameter passing, and response structure. """ @pytest.mark.asyncio async def test_returns_data_key(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({"items": [{"id": "sud_7"}]}) result = await http_request("/sud", {}) assert "data" in result assert result["data"]["items"][0]["id"] == "sud_7" @pytest.mark.asyncio async def test_returns_url_key(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({}) result = await http_request("/sud", {}) assert "url" in result @pytest.mark.asyncio async def test_params_passed_to_get(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({}) await http_request("/sud", {"query": "Bratislava", "size": 10}) args, kwargs = mock_client.get.call_args called_url = args[0] if args else kwargs.get("url", "") assert "query=Bratislava" in called_url assert "size=10" in called_url class TestRemoveKeys: """ verifies the removal of the given keys from the response without errors. """ @pytest.mark.asyncio async def test_key_removed_from_data(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response( {"id": "sud_7", "_internal": "secret"} ) result = await http_request("/sud", {}, remove_keys=["_internal"]) assert "_internal" not in result["data"] assert result["data"]["id"] == "sud_7" @pytest.mark.asyncio async def test_nonexistent_key_does_not_raise(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({"id": "1"}) result = await http_request("/sud", {}, remove_keys=["ghost"]) assert result["data"] == {"id": "1"} class TestCaching: """ Checks the operation of request caching (repeated calls do not duplicate HTTP). """ @pytest.mark.asyncio async def test_same_request_called_once(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({"data": "x"}) await http_request("/sud", {"q": "test"}) await http_request("/sud", {"q": "test"}) assert mock_client.get.call_count == 1 @pytest.mark.asyncio async def test_different_params_not_cached(self, mock_client, make_response) -> None: mock_client.get.return_value = make_response({}) await http_request("/sud", {"q": "Bratislava"}) await http_request("/sud", {"q": "Košice"}) assert mock_client.get.call_count == 2 class TestHTTPErrors: """ Checks for correct HTTP handling and unexpected errors. """ @pytest.mark.asyncio @pytest.mark.parametrize("status", [404, 500, 503]) async def test_http_error_returns_error_dict(self, status, mock_client) -> None: mock_client.get = AsyncMock( side_effect=httpx.HTTPStatusError( f"HTTP {status}", request=MagicMock(), response=MagicMock(status_code=status), ) ) result = await http_request("/sud", {}) assert result["error"] == "http_error" assert "detail" in result @pytest.mark.asyncio async def test_unexpected_error_returns_error_dict(self, mock_client) -> None: mock_client.get = AsyncMock(side_effect=Exception("boom")) result = await http_request("/sud", {}) assert result["error"] == "unexpected_error" assert "detail" in result