import pytest import httpx import respx from api.fetch_api_data import _cache from api.config import JUSTICE_API_BASE from api.tools import ( court_search, court_id, court_autocomplete, judge_search, judge_id, judge_autocomplete, decision_search, decision_id, decision_autocomplete, contract_search, contract_id, contract_autocomplete, civil_proceedings_search, civil_proceedings_id, civil_proceedings_autocomplete, admin_proceedings_search, admin_proceedings_id, admin_proceedings_autocomplete, ) EMPTY_LIST_RESPONSE = {"content": [], "totalElements": 0, "numberOfElements": 0} @pytest.fixture(autouse=True) def clear_cache(): _cache.clear() yield _cache.clear() def make_response(body: dict = None): return httpx.Response(200, json=body or EMPTY_LIST_RESPONSE) @pytest.mark.asyncio class TestCourtTools: @respx.mock async def test_court_search_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sud").mock(return_value=make_response()) await court_search.on_invoke_tool(None, '{"params": {"query": "Bratislava"}}') assert mock.called @respx.mock async def test_court_id_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sud/sud_175").mock( return_value=httpx.Response(200, json={"id": "sud_175", "foto": "data"}) ) await court_id.on_invoke_tool(None, '{"params": {"id": "175"}}') assert mock.called @respx.mock async def test_court_id_removes_foto_key(self): respx.get(f"{JUSTICE_API_BASE}/v1/sud/sud_1").mock( return_value=httpx.Response(200, json={"name": "Súd", "foto": "base64"}) ) result = await court_id.on_invoke_tool(None, '{"params": {"id": "1"}}') assert "foto" not in str(result) @respx.mock async def test_court_autocomplete_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sud/autocomplete").mock(return_value=make_response()) await court_autocomplete.on_invoke_tool(None, '{"params": {"query": "Kraj"}}') assert mock.called @respx.mock async def test_court_search_empty_params(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sud").mock(return_value=make_response()) await court_search.on_invoke_tool(None, '{"params": {}}') assert mock.called @pytest.mark.asyncio class TestJudgeTools: @respx.mock async def test_judge_search_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sudca").mock(return_value=make_response()) await judge_search.on_invoke_tool(None, '{"params": {"query": "Novák"}}') assert mock.called @respx.mock async def test_judge_id_normalizes_digit_id(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sudca/sudca_1").mock( return_value=httpx.Response(200, json={"id": "sudca_1"}) ) await judge_id.on_invoke_tool(None, '{"params": {"id": "1"}}') assert mock.called @respx.mock async def test_judge_id_with_prefix(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sudca/sudca_42").mock( return_value=httpx.Response(200, json={"id": "sudca_42"}) ) await judge_id.on_invoke_tool(None, '{"params": {"id": "sudca_42"}}') assert mock.called @respx.mock async def test_judge_autocomplete_passes_guid_sud(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sudca/autocomplete").mock(return_value=make_response()) await judge_autocomplete.on_invoke_tool(None, '{"params": {"query": "Novák", "guidSud": "sud_100"}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("guidSud") == "sud_100" @respx.mock async def test_judge_autocomplete_without_guid(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/sudca/autocomplete").mock(return_value=make_response()) await judge_autocomplete.on_invoke_tool(None, '{"params": {"query": "Kováč", "limit": 5}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("query") == "Kováč" @pytest.mark.asyncio class TestDecisionTools: @respx.mock async def test_decision_search_with_date_range(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie").mock(return_value=make_response()) await decision_search.on_invoke_tool( None, '{"params": {"vydaniaOd": "01.01.2024", "vydaniaDo": "31.01.2024"}}' ) assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("vydaniaOd") == "01.01.2024" @respx.mock async def test_decision_search_with_guid_sudca(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie").mock(return_value=make_response()) await decision_search.on_invoke_tool(None, '{"params": {"guidSudca": "sudca_1"}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("guidSudca") == "sudca_1" @respx.mock async def test_decision_id_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/rozhodnutie_99").mock( return_value=httpx.Response(200, json={"id": "rozhodnutie_99"}) ) await decision_id.on_invoke_tool(None, '{"params": {"id": "rozhodnutie_99"}}') assert mock.called @respx.mock async def test_decision_autocomplete_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete").mock( return_value=make_response() ) await decision_autocomplete.on_invoke_tool(None, '{"params": {"query": "Rozsudok", "limit": 5}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("query") == "Rozsudok" @pytest.mark.asyncio class TestContractTools: @respx.mock async def test_contract_search_with_guid_sud(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy").mock(return_value=make_response()) await contract_search.on_invoke_tool(None, '{"params": {"guidSud": "sud_7"}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("guidSud") == "sud_7" @respx.mock async def test_contract_search_typ_dokumentu_filter(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy").mock(return_value=make_response()) await contract_search.on_invoke_tool(None, '{"params": {"typDokumentuFacetFilter": ["ZMLUVA"]}}') assert mock.called @respx.mock async def test_contract_id_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/2156252").mock( return_value=httpx.Response(200, json={"idZmluvy": "2156252"}) ) await contract_id.on_invoke_tool(None, '{"params": {"idZmluvy": "2156252"}}') assert mock.called @respx.mock async def test_contract_autocomplete_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete").mock( return_value=make_response() ) await contract_autocomplete.on_invoke_tool(None, '{"params": {"query": "Slovak Telekom"}}') assert mock.called params = dict(mock.calls[0].request.url.params) assert params.get("query") == "Slovak Telekom" @pytest.mark.asyncio class TestCivilAndAdminTools: @respx.mock async def test_civil_proceedings_search(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania").mock(return_value=make_response()) await civil_proceedings_search.on_invoke_tool(None, '{"params": {"query": "test"}}') assert mock.called @respx.mock async def test_civil_proceedings_id_calls_correct_url(self): uid = "121e4d31-695e-41e1-9191-7c9ad5d8d484" mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{uid}").mock( return_value=httpx.Response(200, json={"id": uid}) ) await civil_proceedings_id.on_invoke_tool(None, f'{{"params": {{"id": "{uid}"}}}}') assert mock.called @respx.mock async def test_civil_proceedings_autocomplete_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete").mock( return_value=make_response() ) await civil_proceedings_autocomplete.on_invoke_tool( None, '{"params": {"query": "test", "limit": 5}}' ) assert mock.called @respx.mock async def test_admin_proceedings_search(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie").mock(return_value=make_response()) await admin_proceedings_search.on_invoke_tool(None, '{"params": {"query": "test"}}') assert mock.called @respx.mock async def test_admin_proceedings_id_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/spravneKonanie_103").mock( return_value=httpx.Response(200, json={"id": "spravneKonanie_103"}) ) await admin_proceedings_id.on_invoke_tool(None, '{"params": {"id": "103"}}') assert mock.called @respx.mock async def test_admin_proceedings_autocomplete_calls_correct_url(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/autocomplete").mock( return_value=make_response() ) await admin_proceedings_autocomplete.on_invoke_tool( None, '{"params": {"query": "konanie", "limit": 10}}' ) assert mock.called @respx.mock async def test_civil_proceedings_date_params(self): mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania").mock(return_value=make_response()) await civil_proceedings_search.on_invoke_tool( None, '{"params": {"pojednavaniaOd": "01.01.2024", "pojednavaniaDo": "31.01.2024"}}' ) assert mock.called