import pytest from aiatlas.connectors.research.arxiv import ArxivConnector, _arxiv_id, _split_names from aiatlas.sdk.facts import Target from tests.conftest import claims_of, extract_from_fixture, fixture_path @pytest.fixture def connector() -> ArxivConnector: return ArxivConnector({"atom_pages": 2}) async def test_discover(connector): targets = await connector.discover(None) # type: ignore[arg-type] assert [t.key for t in targets] == ["atom:0", "atom:1", "rss:cs.LG", "rss:cs.CL", "rss:cs.AI", "rss:cs.CV"] assert "start=200&max_results=200" in targets[1].url and connector.rate_per_min == 4 assert [t.key for t in await ArxivConnector().discover(None)] == ["rss:cs.LG", "rss:cs.CL", "rss:cs.AI", "rss:cs.CV"] # Atom opt-in async def test_atom(connector): target = Target(url="https://export.arxiv.org/api/query?search_query=cat:cs.LG&start=0&max_results=200", doc_type="feed", key="atom:0") facts = await extract_from_fixture(connector, target, fixture_path("arxiv", "atom-page0.xml"), content_type="application/atom+xml") papers = [e for e in facts.entities if e.entity_type == "paper"] assert len(papers) == 200 and papers[0].identifiers == {"arxiv": "2609.11929"} # version suffix stripped c = claims_of(facts, papers[0].name) assert c["primary_category"] == "cs.CV" and c["published_at"] == "2026-09-10T17:59:55+00:00" assert c["pdf_url"] == "https://arxiv.org/pdf/2609.11929" and c["authors"][0] == "Haiwen Diao" and c["abstract"].startswith("We launch SenseNova") assert c["comment"].startswith("Project page") # no name-only researchers any more: the Atom feed carries no author identifier (ORCID), so authors stay a claim on the paper assert not any(e.entity_type == "researcher" for e in facts.entities) and not any(r.predicate == "authored" for r in facts.relations) assert len(c["authors"]) >= 3 assert not any(t.needs_llm for t in facts.targets) and facts.targets == [] async def test_rss(connector): target = Target(url="https://rss.arxiv.org/rss/cs.LG", doc_type="feed", key="rss:cs.LG") facts = await extract_from_fixture(connector, target, fixture_path("arxiv", "rss-cs-lg.xml"), content_type="application/rss+xml") papers = [e for e in facts.entities if e.entity_type == "paper"] assert len(papers) >= 200 and papers[0].identifiers == {"arxiv": "2609.10559"} c = claims_of(facts, papers[0].name) assert c["authors"] == ["Wenzhe Jin", "Haina Tang"] and c["arxiv_announce_type"] == "new" assert c["abstract"].startswith("To address") and "Announce Type" not in c["abstract"] assert c["categories"] == ["cs.LG", "cs.CV"] def test_helpers(): assert _arxiv_id("http://arxiv.org/abs/2609.11929v1") == "2609.11929" assert _arxiv_id("oai:arXiv.org:2609.10559v2") == "2609.10559" assert _split_names("Wenzhe Jin, Haina Tang and Someone Else") == ["Wenzhe Jin", "Haina Tang", "Someone Else"]