Skip to main content
Glama
test_drug_recalls.py•13.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

Latest Blog Posts

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