120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
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 |