File size: 4,335 Bytes
016b413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""Unit tests for Europe PMC tool."""

from unittest.mock import AsyncMock, MagicMock, patch

import pytest

from src.tools.europepmc import EuropePMCTool
from src.utils.models import Evidence


@pytest.mark.unit
class TestEuropePMCTool:
    """Tests for EuropePMCTool."""

    @pytest.fixture
    def tool(self) -> EuropePMCTool:
        return EuropePMCTool()

    def test_tool_name(self, tool: EuropePMCTool) -> None:
        assert tool.name == "europepmc"

    @pytest.mark.asyncio
    async def test_search_returns_evidence(self, tool: EuropePMCTool) -> None:
        """Test that search returns Evidence objects."""
        mock_response = {
            "resultList": {
                "result": [
                    {
                        "id": "12345",
                        "title": "Long COVID Treatment Study",
                        "abstractText": "This study examines treatments for Long COVID.",
                        "doi": "10.1234/test",
                        "pubYear": "2024",
                        "source": "MED",
                        "pubTypeList": {"pubType": ["research-article"]},
                    }
                ]
            }
        }

        with patch("httpx.AsyncClient") as mock_client:
            mock_instance = AsyncMock()
            mock_client.return_value.__aenter__.return_value = mock_instance

            # Create response mock
            mock_resp = MagicMock()
            mock_resp.json.return_value = mock_response
            mock_resp.raise_for_status.return_value = None

            mock_instance.get.return_value = mock_resp

            results = await tool.search("long covid treatment", max_results=5)

            assert len(results) == 1
            assert isinstance(results[0], Evidence)
            assert "Long COVID Treatment Study" in results[0].citation.title

    @pytest.mark.asyncio
    async def test_search_marks_preprints(self, tool: EuropePMCTool) -> None:
        """Test that preprints are marked correctly."""
        mock_response = {
            "resultList": {
                "result": [
                    {
                        "id": "PPR12345",
                        "title": "Preprint Study",
                        "abstractText": "Abstract text",
                        "doi": "10.1234/preprint",
                        "pubYear": "2024",
                        "source": "PPR",
                        "pubTypeList": {"pubType": ["Preprint"]},
                    }
                ]
            }
        }

        with patch("httpx.AsyncClient") as mock_client:
            mock_instance = AsyncMock()
            mock_client.return_value.__aenter__.return_value = mock_instance

            mock_resp = MagicMock()
            mock_resp.json.return_value = mock_response
            mock_resp.raise_for_status.return_value = None
            mock_instance.get.return_value = mock_resp

            results = await tool.search("test", max_results=5)

            assert "PREPRINT" in results[0].content
            assert results[0].citation.source == "preprint"

    @pytest.mark.asyncio
    async def test_search_empty_results(self, tool: EuropePMCTool) -> None:
        """Test handling of empty results."""
        mock_response = {"resultList": {"result": []}}

        with patch("httpx.AsyncClient") as mock_client:
            mock_instance = AsyncMock()
            mock_client.return_value.__aenter__.return_value = mock_instance

            mock_resp = MagicMock()
            mock_resp.json.return_value = mock_response
            mock_resp.raise_for_status.return_value = None
            mock_instance.get.return_value = mock_resp

            results = await tool.search("nonexistent query xyz", max_results=5)

            assert results == []


@pytest.mark.integration
class TestEuropePMCIntegration:
    """Integration tests with real API."""

    @pytest.mark.asyncio
    async def test_real_api_call(self) -> None:
        """Test actual API returns relevant results."""
        tool = EuropePMCTool()
        results = await tool.search("long covid treatment", max_results=3)

        assert len(results) > 0
        # At least one result should mention COVID
        titles = " ".join([r.citation.title.lower() for r in results])
        assert "covid" in titles or "sars" in titles