Spaces:
Running
Running
| """Tests for the PIIGuard PII protection module.""" | |
| import pytest | |
| from reachy_mini_conversation_app.pii_guard import PIIGuard, DEFAULT_MEDICATION_MAPPINGS | |
| class TestPIIGuard: | |
| """Test PIIGuard redaction and hydration.""" | |
| def test_medication_redaction(self): | |
| """Test that medication names are redacted to symptom categories.""" | |
| guard = PIIGuard() | |
| text = "I took my Topiramate this morning" | |
| redacted, mapping = guard.redact(text) | |
| assert "Topiramate" not in redacted | |
| assert "migraine prevention medication" in redacted | |
| assert mapping["migraine prevention medication"] == "Topiramate" | |
| def test_multiple_medications(self): | |
| """Test redaction of multiple different medications.""" | |
| guard = PIIGuard() | |
| text = "I take Topiramate for migraines and Aspirin for stroke prevention" | |
| redacted, mapping = guard.redact(text) | |
| assert "Topiramate" not in redacted | |
| assert "Aspirin" not in redacted | |
| assert "migraine prevention medication" in redacted | |
| assert "blood thinner medication" in redacted | |
| def test_name_redaction(self): | |
| """Test that patient/caregiver names are redacted to roles.""" | |
| guard = PIIGuard() | |
| guard.set_patient_context( | |
| patient_name="Elena", caregiver_name="Maya", doctor_name="Dr. Patel" | |
| ) | |
| text = "Elena needs her medication. Maya will call Dr. Patel." | |
| redacted, mapping = guard.redact(text) | |
| assert "Elena" not in redacted | |
| assert "Maya" not in redacted | |
| assert "Dr. Patel" not in redacted | |
| assert "the patient" in redacted | |
| assert "the caregiver" in redacted | |
| assert "the neurologist" in redacted | |
| def test_hydration_restores_values(self): | |
| """Test that hydration restores original values.""" | |
| guard = PIIGuard() | |
| guard.set_patient_context(patient_name="Elena", caregiver_name="Maya") | |
| original = "Elena should take her Topiramate at 8am" | |
| redacted, mapping = guard.redact(original) | |
| # Simulate cloud AI response using redacted terms | |
| ai_response = ( | |
| "the patient should take the migraine prevention medication with water" | |
| ) | |
| hydrated = guard.hydrate(ai_response, mapping) | |
| assert "Elena" in hydrated | |
| assert "Topiramate" in hydrated | |
| def test_case_insensitive_redaction(self): | |
| """Test that redaction works regardless of case.""" | |
| guard = PIIGuard() | |
| text = "I took TOPIRAMATE and topiramate" | |
| redacted, mapping = guard.redact(text) | |
| assert "TOPIRAMATE" not in redacted | |
| assert "topiramate" not in redacted | |
| def test_empty_text(self): | |
| """Test handling of empty text.""" | |
| guard = PIIGuard() | |
| redacted, mapping = guard.redact("") | |
| assert redacted == "" | |
| assert mapping == {} | |
| hydrated = guard.hydrate("", {}) | |
| assert hydrated == "" | |
| def test_no_pii_text(self): | |
| """Test text with no PII returns unchanged.""" | |
| guard = PIIGuard() | |
| text = "Today is a beautiful day" | |
| redacted, mapping = guard.redact(text) | |
| assert redacted == text | |
| assert mapping == {} | |
| def test_register_custom_medication(self): | |
| """Test registering custom medication mappings.""" | |
| guard = PIIGuard() | |
| guard.register_medication("Gabapentin", "nerve_pain", "nerve pain medication") | |
| text = "I take Gabapentin daily" | |
| redacted, mapping = guard.redact(text) | |
| assert "Gabapentin" not in redacted | |
| assert "nerve pain medication" in redacted | |
| def test_default_mappings_loaded(self): | |
| """Test that default medication mappings are available.""" | |
| guard = PIIGuard() | |
| # Check some common CADASIL medications | |
| text = "Topiramate, Aspirin, Paracetamol, and Clopidogrel" | |
| redacted, mapping = guard.redact(text) | |
| # Aspirin & Clopidogrel share "blood thinner medication" key, so 3 unique labels | |
| assert len(mapping) >= 3 | |
| class TestPIIGuardWithDatabase: | |
| """Test PIIGuard with database persistence.""" | |
| def test_database_mappings_loaded(self, tmp_path): | |
| """Test that mappings from database are loaded.""" | |
| from reachy_mini_conversation_app.database import MiniMinderDB | |
| db_path = tmp_path / "test.db" | |
| db = MiniMinderDB(db_path) | |
| # Register a custom mapping in the database | |
| db.register_medication_redaction( | |
| "CustomMed", "custom", "custom category medication" | |
| ) | |
| # Create PIIGuard with database | |
| guard = PIIGuard(database=db) | |
| text = "I take CustomMed daily" | |
| redacted, mapping = guard.redact(text) | |
| assert "CustomMed" not in redacted.lower() | |
| assert "custom category medication" in redacted | |
| db.close() | |