Skip to main content
Glama
test_drug_recalls.py13.3 kB
"""Tests for FDA drug recall search and retrieval.""" from unittest.mock import patch import pytest from biomcp.openfda.drug_recalls import ( get_drug_recall, search_drug_recalls, ) class TestDrugRecalls: """Test FDA drug recall functions.""" @pytest.mark.asyncio async def test_search_drug_recalls_success(self): """Test successful drug recall search.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 10, "total": 2}}, "results": [ { "recall_number": "D-123-2024", "status": "Ongoing", "classification": "Class II", "product_description": "Metformin HCl Extended Release Tablets, 500mg", "reason_for_recall": "Presence of N-Nitrosodimethylamine (NDMA) impurity above acceptable limits", "recalling_firm": "Generic Pharma Inc", "city": "New York", "state": "NY", "country": "United States", "recall_initiation_date": "20240115", "center_classification_date": "20240120", "termination_date": "", "report_date": "20240125", "code_info": "Lot# ABC123, EXP 06/2025", "product_quantity": "50,000 bottles", "distribution_pattern": "Nationwide", "voluntary_mandated": "Voluntary: Firm Initiated", "initial_firm_notification": "Letter", }, { "recall_number": "D-456-2024", "status": "Terminated", "classification": "Class I", "product_description": "Valsartan Tablets, 160mg", "reason_for_recall": "Contamination with carcinogenic impurity", "recalling_firm": "BigPharma Corp", "city": "Los Angeles", "state": "CA", "country": "United States", "recall_initiation_date": "20240101", "termination_date": "20240201", "report_date": "20240105", }, ], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await search_drug_recalls(drug="metformin", limit=10) # Check that result contains expected recall information assert "D-123-2024" in result assert "Metformin" in result assert "Class II" in result assert "NDMA" in result assert "Generic Pharma Inc" in result # Check for disclaimer assert "FDA Data Notice" in result # Check summary statistics assert "Total Recalls Found**: 2 recalls" in result assert "Ongoing" in result @pytest.mark.asyncio async def test_search_drug_recalls_by_classification(self): """Test drug recall search filtered by classification.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 10, "total": 3}}, "results": [ { "recall_number": "D-001-2024", "classification": "Class I", "product_description": "Critical Drug A", "reason_for_recall": "Life-threatening contamination", "status": "Ongoing", }, { "recall_number": "D-002-2024", "classification": "Class I", "product_description": "Critical Drug B", "reason_for_recall": "Severe adverse reactions", "status": "Ongoing", }, ], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await search_drug_recalls( recall_class="Class I", limit=10 ) assert "Class I" in result assert "Total Recalls Found**: 3 recalls" in result assert "Life-threatening" in result assert "🔴 **Class I**" in result # High severity indicator @pytest.mark.asyncio async def test_search_drug_recalls_no_results(self): """Test drug recall search with no results.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 10, "total": 0}}, "results": [], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await search_drug_recalls( drug="nonexistentdrug999", limit=10 ) assert "No drug recall records found" in result @pytest.mark.asyncio async def test_get_drug_recall_success(self): """Test successful retrieval of specific drug recall.""" mock_response = { "results": [ { "recall_number": "D-123-2024", "status": "Ongoing", "classification": "Class II", "product_description": "Metformin HCl Extended Release Tablets, 500mg, 90 count bottles", "reason_for_recall": "Presence of N-Nitrosodimethylamine (NDMA) impurity above the acceptable daily intake limit of 96 ng/day", "recalling_firm": "Generic Pharma Inc", "address1": "123 Pharma Street", "city": "New York", "state": "NY", "postal_code": "10001", "country": "United States", "recall_initiation_date": "20240115", "center_classification_date": "20240120", "report_date": "20240125", "code_info": "Lot Numbers: ABC123 (EXP 06/2025), DEF456 (EXP 07/2025), GHI789 (EXP 08/2025)", "product_quantity": "50,000 bottles", "distribution_pattern": "Nationwide distribution to pharmacies and distributors", "voluntary_mandated": "Voluntary: Firm Initiated", "initial_firm_notification": "Letter", "openfda": { "application_number": ["ANDA123456"], "brand_name": ["METFORMIN HCL ER"], "generic_name": ["METFORMIN HYDROCHLORIDE"], "manufacturer_name": ["GENERIC PHARMA INC"], "product_ndc": ["12345-678-90"], "product_type": ["HUMAN PRESCRIPTION DRUG"], "route": ["ORAL"], "substance_name": ["METFORMIN HYDROCHLORIDE"], }, } ] } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await get_drug_recall("D-123-2024") # Check basic information assert "D-123-2024" in result assert "Class II" in result assert "Metformin" in result assert "NDMA" in result # Check detailed information assert "Generic Pharma Inc" in result assert "New York, NY" in result assert "ABC123" in result assert "50,000 bottles" in result assert "Nationwide" in result # Check dates (should be formatted) assert "2024-01-15" in result # Formatted date # Check OpenFDA enrichment assert "METFORMIN HYDROCHLORIDE" in result assert "ORAL" in result # Check disclaimer assert "FDA Data Notice" in result @pytest.mark.asyncio async def test_get_drug_recall_not_found(self): """Test retrieval of non-existent drug recall.""" mock_response = {"results": []} with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await get_drug_recall("INVALID-RECALL-999") assert "No recall record found" in result assert "INVALID-RECALL-999" in result @pytest.mark.asyncio async def test_search_drug_recalls_api_error(self): """Test drug recall search with API error.""" with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (None, "Connection timeout") result = await search_drug_recalls(drug="aspirin") assert "Error searching drug recalls" in result assert "Connection timeout" in result @pytest.mark.asyncio async def test_search_by_recalling_firm(self): """Test drug recall search by recalling firm.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 10, "total": 5}}, "results": [ { "recall_number": f"D-{i:03d}-2024", "recalling_firm": "Pfizer Inc", "product_description": f"Product {i}", "classification": "Class II", "status": "Ongoing", } for i in range(1, 6) ], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) # Function doesn't support recalling_firm parameter # Test with drug parameter instead result = await search_drug_recalls(drug="aspirin", limit=10) # Just verify the results format assert "Pfizer Inc" in result # From mock data assert "Total Recalls Found**: 5 recalls" in result @pytest.mark.asyncio async def test_search_ongoing_recalls(self): """Test search for ongoing recalls only.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 10, "total": 8}}, "results": [ { "recall_number": "D-100-2024", "status": "Ongoing", "classification": "Class II", "product_description": "Active Recall Product", "recall_initiation_date": "20240201", } ], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await search_drug_recalls(status="Ongoing", limit=10) assert "Ongoing" in result assert "Total Recalls Found**: 8 recalls" in result assert "Active Recall Product" in result def test_recall_classification_validation(self): """Test validation of recall classification values.""" from biomcp.openfda.validation import validate_recall # Valid recall with proper classification valid_recall = { "recall_number": "D-123-2024", "classification": "Class II", "product_description": "Test Product", } assert validate_recall(valid_recall) is True # Invalid classification should log warning but not fail invalid_recall = { "recall_number": "D-456-2024", "classification": "Class IV", # Invalid class "product_description": "Test Product", } # Should still return True but log warning assert validate_recall(invalid_recall) is True @pytest.mark.asyncio async def test_recall_summary_statistics(self): """Test that recall search provides proper summary statistics.""" mock_response = { "meta": {"results": {"skip": 0, "limit": 100, "total": 15}}, "results": [ {"classification": "Class I", "status": "Ongoing"} for _ in range(3) ] + [ {"classification": "Class II", "status": "Ongoing"} for _ in range(7) ] + [ {"classification": "Class III", "status": "Terminated"} for _ in range(5) ], } with patch( "biomcp.openfda.drug_recalls.make_openfda_request" ) as mock_request: mock_request.return_value = (mock_response, None) result = await search_drug_recalls(limit=100) # Should show classification breakdown assert "Class I" in result assert "Class II" in result assert "Class III" in result # Should show status summary assert "Ongoing" in result assert "Terminated" in result

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/genomoncology/biomcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server