diff --git a/tests/test_synthesizer.py b/tests/test_synthesizer.py new file mode 100644 index 0000000..022add6 --- /dev/null +++ b/tests/test_synthesizer.py @@ -0,0 +1,80 @@ +import pytest +from unittest.mock import AsyncMock +from axon.models import SearchResult + + +def make_results(n=3): + return [ + SearchResult(title=f"T{i}", url=f"https://ex{i}.com", content=f"Content {i}", score=0.9) + for i in range(n) + ] + + +@pytest.mark.asyncio +async def test_synthesize_answer_returns_string(monkeypatch): + fake_response = { + "choices": [{"message": {"content": "The answer is 42."}}] + } + + class FakeResponse: + def raise_for_status(self): pass + def json(self): return fake_response + + class FakeClient: + async def __aenter__(self): return self + async def __aexit__(self, *_): pass + async def post(self, *args, **kwargs): return FakeResponse() + + monkeypatch.setattr("axon.services.synthesizer.httpx.AsyncClient", FakeClient) + + from axon.services.synthesizer import synthesize_answer + answer = await synthesize_answer("What is the answer?", make_results()) + assert answer == "The answer is 42." + + +@pytest.mark.asyncio +async def test_synthesize_answer_empty_results(): + from axon.services.synthesizer import synthesize_answer + answer = await synthesize_answer("query", []) + assert "No search results" in answer + + +@pytest.mark.asyncio +async def test_generate_sub_queries_parses_lines(monkeypatch): + fake_response = { + "choices": [{"message": {"content": "Query one\nQuery two\nQuery three"}}] + } + + class FakeResponse: + def raise_for_status(self): pass + def json(self): return fake_response + + class FakeClient: + async def __aenter__(self): return self + async def __aexit__(self, *_): pass + async def post(self, *args, **kwargs): return FakeResponse() + + monkeypatch.setattr("axon.services.synthesizer.httpx.AsyncClient", FakeClient) + + from axon.services.synthesizer import generate_sub_queries + queries = await generate_sub_queries("main topic", count=3) + assert len(queries) == 3 + assert queries[0] == "Query one" + + +@pytest.mark.asyncio +async def test_generate_sub_queries_fallback_on_error(monkeypatch): + import httpx + + class FakeClient: + async def __aenter__(self): return self + async def __aexit__(self, *_): pass + async def post(self, *args, **kwargs): + raise httpx.ConnectError("LLM down") + + monkeypatch.setattr("axon.services.synthesizer.httpx.AsyncClient", FakeClient) + + from axon.services.synthesizer import generate_sub_queries + queries = await generate_sub_queries("main topic", count=3) + assert len(queries) == 3 + assert "main topic" in queries[0]