| import sys |
| import unittest |
| from unittest.mock import patch, AsyncMock |
| from pathlib import Path |
|
|
| |
| sys.path.insert(0, str(Path(__file__).parent.resolve())) |
|
|
| from app.services import engine, rag |
|
|
| class TestFuzzyGroundingGates(unittest.IsolatedAsyncioTestCase): |
|
|
| def setUp(self): |
| |
| engine._load_domain_config.cache_clear() |
|
|
| @patch("app.services.rag.retrieve") |
| async def test_synonym_overlap_fever_jvara(self, mock_retrieve): |
| |
| mock_chunk = rag.RetrievedChunk( |
| chunk_id="test_1", |
| content="Jvara is a condition caused by vitiated doshas, affecting the body and mind.", |
| source="Charaka Samhita", |
| chapter="Chapter 1", |
| section="Sutrasthana", |
| relevance_score=0.9 |
| ) |
| mock_retrieve.return_value = [mock_chunk] |
|
|
| |
| with patch("app.services.llm.check_connection", new_callable=AsyncMock) as mock_conn, \ |
| patch("app.services.llm.stream_completion") as mock_stream: |
| mock_conn.return_value = True |
| |
| async def dummy_generator(*args, **kwargs): |
| yield "Test response" |
| mock_stream.return_value = dummy_generator() |
|
|
| is_grounded = None |
| async for event in engine.stream_answer("ayurveda", "Explain how fever manifests.", []): |
| if event.get("type") == "citations": |
| is_grounded = event.get("is_grounded") |
|
|
| self.assertTrue(is_grounded, "English synonym 'fever' failed to match Sanskrit context 'jvara'!") |
|
|
| @patch("app.services.rag.retrieve") |
| async def test_phonetic_overlap_vasti_basti(self, mock_retrieve): |
| |
| mock_chunk = rag.RetrievedChunk( |
| chunk_id="test_2", |
| content="Basti therapy is the chief treatment for Vata disorders.", |
| source="Charaka Samhita", |
| chapter="Chapter 2", |
| section="Sutrasthana", |
| relevance_score=0.9 |
| ) |
| mock_retrieve.return_value = [mock_chunk] |
|
|
| with patch("app.services.llm.check_connection", new_callable=AsyncMock) as mock_conn, \ |
| patch("app.services.llm.stream_completion") as mock_stream: |
| mock_conn.return_value = True |
| |
| async def dummy_generator(*args, **kwargs): |
| yield "Test response" |
| mock_stream.return_value = dummy_generator() |
|
|
| is_grounded = None |
| async for event in engine.stream_answer("ayurveda", "What is the function of vasti?", []): |
| if event.get("type") == "citations": |
| is_grounded = event.get("is_grounded") |
|
|
| self.assertTrue(is_grounded, "Phonetic variation 'vasti' failed to match context 'basti'!") |
|
|
| @patch("app.services.rag.retrieve") |
| async def test_adversarial_rejection_uranium(self, mock_retrieve): |
| |
| mock_chunk = rag.RetrievedChunk( |
| chunk_id="test_3", |
| content="Basti therapy is the chief treatment for Vata disorders.", |
| source="Charaka Samhita", |
| chapter="Chapter 2", |
| section="Sutrasthana", |
| relevance_score=0.9 |
| ) |
| mock_retrieve.return_value = [mock_chunk] |
|
|
| with patch("app.services.llm.check_connection", new_callable=AsyncMock) as mock_conn: |
| mock_conn.return_value = True |
|
|
| is_grounded = None |
| async for event in engine.stream_answer("ayurveda", "Can I treat Vata using uranium?", []): |
| if event.get("type") == "citations": |
| is_grounded = event.get("is_grounded") |
|
|
| self.assertFalse(is_grounded, "Adversarial query containing 'uranium' incorrectly cleared the grounding gate!") |
|
|
| @patch("app.services.rag.retrieve") |
| async def test_phonetic_sammurchana_sammurshana(self, mock_retrieve): |
| |
| mock_chunk = rag.RetrievedChunk( |
| chunk_id="test_4", |
| content="The pathogenesis involves dosha-dushya sammurshana in the srotas.", |
| source="Charaka Samhita", |
| chapter="Chapter 3", |
| section="Sutrasthana", |
| relevance_score=0.9 |
| ) |
| mock_retrieve.return_value = [mock_chunk] |
|
|
| with patch("app.services.llm.check_connection", new_callable=AsyncMock) as mock_conn, \ |
| patch("app.services.llm.stream_completion") as mock_stream: |
| mock_conn.return_value = True |
| |
| async def dummy_generator(*args, **kwargs): |
| yield "Test response" |
| mock_stream.return_value = dummy_generator() |
|
|
| is_grounded = None |
| async for event in engine.stream_answer("ayurveda", "How does Sammurchana occur?", []): |
| if event.get("type") == "citations": |
| is_grounded = event.get("is_grounded") |
|
|
| self.assertTrue(is_grounded, "Sanskrit phonetic variation 'Sammurchana' failed to match context 'sammurshana'!") |
|
|
| if __name__ == "__main__": |
| unittest.main() |
|
|