from __future__ import annotations
import pytest
from pydantic import ValidationError
from inspirehep_mcp.client import SearchResult
from inspirehep_mcp.server import (
AuthorSearchInput,
FulltextSearchInput,
TitleSearchInput,
run_search,
)
class FakeClient:
def __init__(self, records: list[dict[str, object]]) -> None:
self.records = records
self.calls: list[tuple[str, int, str]] = []
async def search_literature(self, *, query: str, limit: int, sort: str) -> SearchResult:
self.calls.append((query, limit, sort))
return SearchResult(records=self.records)
def test_author_search_input_accepts_multiple_authors() -> None:
params = AuthorSearchInput(author=["Witten, Edward", "Maldacena, Juan"])
assert params.author == ["Witten, Edward", "Maldacena, Juan"]
def test_author_search_input_rejects_empty_author_entries() -> None:
with pytest.raises(ValueError):
AuthorSearchInput(author=["Witten, Edward", " "])
def test_title_search_input_accepts_year() -> None:
params = TitleSearchInput(title="axion", year=2020)
assert params.year == 2020
def test_title_search_input_rejects_invalid_year() -> None:
with pytest.raises(ValidationError):
TitleSearchInput(title="axion", year=1800)
def test_fulltext_search_input_accepts_query() -> None:
params = FulltextSearchInput(fulltext="symmetry breaking")
assert params.fulltext == "symmetry breaking"
@pytest.mark.asyncio
async def test_run_search_returns_compact_payload() -> None:
fake = FakeClient(
records=[
{
"title": "Paper",
"authors": ["Alice"],
"abstract": "Short abstract",
"year": 2020,
}
]
)
result = await run_search(
query='author "Alice" and ac 1->10',
limit=5,
sort_by_citation=True,
client=fake,
)
assert result["count"] == 1
assert "sort_by" not in result
assert result["records"][0]["title"] == "Paper"
assert fake.calls == [('author "Alice" and ac 1->10', 5, "mostcited")]
@pytest.mark.asyncio
async def test_run_search_uses_year_sort() -> None:
fake = FakeClient(records=[])
await run_search(query='title "axion"', limit=2, sort_by_citation=False, client=fake)
assert fake.calls == [('title "axion"', 2, "mostrecent")]