import pytest import pytest_asyncio import httpx import respx from api.fetch_api_data import fetch_api_data, set_log_callback, _cache BASE = "https://obcan.justice.sk/pilot/api/ress-isu-service" @pytest.fixture(autouse=True) def clear_cache(): _cache.clear() yield _cache.clear() @pytest.mark.asyncio class TestFetchApiData: @respx.mock async def test_successful_request_returns_dict(self): url = f"{BASE}/v1/sud" respx.get(url).mock(return_value=httpx.Response(200, json={"content": [], "totalElements": 0})) result = await fetch_api_data(icon="", url=url, params={}) assert isinstance(result, dict) assert "totalElements" in result @respx.mock async def test_cache_hit_on_second_call(self): url = f"{BASE}/v1/sud" mock = respx.get(url).mock(return_value=httpx.Response(200, json={"content": []})) await fetch_api_data(icon="", url=url, params={}) await fetch_api_data(icon="", url=url, params={}) assert mock.call_count == 1 @respx.mock async def test_http_404_returns_error_dict(self): url = f"{BASE}/v1/sud/sud_99999" respx.get(url).mock(return_value=httpx.Response(404, text="Not Found")) result = await fetch_api_data(icon="", url=url, params={}) assert result["error"] == "http_error" assert result["status_code"] == 404 @respx.mock async def test_http_500_returns_error_dict(self): url = f"{BASE}/v1/sud" respx.get(url).mock(return_value=httpx.Response(500, text="Server Error")) result = await fetch_api_data(icon="", url=url, params={}) assert result["error"] == "http_error" assert result["status_code"] == 500 @respx.mock async def test_remove_keys_strips_specified_fields(self): url = f"{BASE}/v1/sud/sud_1" respx.get(url).mock(return_value=httpx.Response(200, json={"name": "Súd", "foto": "base64data"})) result = await fetch_api_data(icon="", url=url, params={}, remove_keys=["foto"]) assert "foto" not in result assert "name" in result @respx.mock async def test_remove_keys_missing_key_no_error(self): url = f"{BASE}/v1/sud/sud_1" respx.get(url).mock(return_value=httpx.Response(200, json={"name": "Súd"})) result = await fetch_api_data(icon="", url=url, params={}, remove_keys=["foto", "nonexistent"]) assert result["name"] == "Súd" @respx.mock async def test_log_callback_is_called(self): url = f"{BASE}/v1/sud" respx.get(url).mock(return_value=httpx.Response(200, json={})) log_lines = [] set_log_callback(lambda line: log_lines.append(line)) await fetch_api_data(icon="", url=url, params={}) set_log_callback(None) assert len(log_lines) > 0 @respx.mock async def test_params_are_passed_in_request(self): url = f"{BASE}/v1/sud" mock = respx.get(url).mock(return_value=httpx.Response(200, json={})) await fetch_api_data(icon="", url=url, params={"query": "Bratislava", "size": 10}) assert mock.called sent_params = dict(mock.calls[0].request.url.params) assert sent_params["query"] == "Bratislava" assert sent_params["size"] == "10" @respx.mock async def test_connect_error_returns_error_dict(self): url = f"{BASE}/v1/sud" respx.get(url).mock(side_effect=httpx.ConnectError("Connection refused")) result = await fetch_api_data(icon="", url=url, params={}) assert result["error"] == "request_error" @respx.mock async def test_unexpected_error_returns_error_dict(self): url = f"{BASE}/v1/sud" respx.get(url).mock(side_effect=ValueError("unexpected")) result = await fetch_api_data(icon="", url=url, params={}) assert result["error"] == "unexpected_error"