File size: 4,441 Bytes
2f8ae1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05ffeb4
2f8ae1f
 
05ffeb4
2f8ae1f
 
 
05ffeb4
2f8ae1f
 
 
 
 
 
89f1173
 
2f8ae1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89f1173
2f8ae1f
 
 
89f1173
2f8ae1f
 
05ffeb4
2f8ae1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05ffeb4
2f8ae1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
05ffeb4
89f1173
2f8ae1f
89f1173
2f8ae1f
 
89f1173
2f8ae1f
89f1173
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": "Testosterone Therapy for HSDD Study",
                        "abstractText": "This study examines testosterone therapy for HSDD.",
                        "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("testosterone HSDD therapy", max_results=5)

            assert len(results) == 1
            assert isinstance(results[0], Evidence)
            assert "Testosterone Therapy for HSDD 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 for sexual health query."""
        tool = EuropePMCTool()
        results = await tool.search("testosterone libido therapy", max_results=3)

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