Lung-Cancer-Risk-Diagnosis-Assistant / testing /test_intent_classification.py
fatimaxa's picture
Upload 112 files
00bd0c6 verified
import pytest
import numpy as np
from unittest.mock import patch
from intent_classification.intent_router_ml import route_intent
from intent_classification.intent_classification_ml import classify_intent
def mock_classify_ready(label="PATIENT_EVIDENCE_QUERY", confidence=0.85):
"""Returns a mock confident classification result."""
return {"status": "READY", "label": label, "confidence": confidence}
def mock_classify_uncertain(label="PATIENT_EVIDENCE_QUERY", confidence=0.40):
"""Returns a mock uncertain classification result."""
return {"status": "UNCERTAIN", "label": label, "confidence": confidence}
#──── route_intent ────────────────────────────────────────────────────────────────────────────────
class TestRouteIntent:
def test_confident_classification_returns_route_status(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_ready()):
result = route_intent("patient has persistent cough", 1, 1)
assert result["status"] == "ROUTE"
def test_confident_classification_returns_correct_intent(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_ready()):
result = route_intent("patient has persistent cough", 1, 1)
assert result["intent"] == "PATIENT_EVIDENCE_QUERY"
def test_confident_classification_returns_confidence(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_ready()):
result = route_intent("patient has persistent cough", 1, 1)
assert result["confidence"] == 0.85
def test_uncertain_classification_returns_needs_clarification(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_uncertain()):
result = route_intent("something ambiguous", 1, 1)
assert result["status"] == "NEEDS_CLARIFICATION"
def test_uncertain_classification_returns_options(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_uncertain()):
result = route_intent("something ambiguous", 1, 1)
assert "options" in result
assert isinstance(result["options"], list)
assert len(result["options"]) > 0
def test_uncertain_classification_options_are_strings(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_uncertain()):
result = route_intent("something ambiguous", 1, 1)
for opt in result["options"]:
assert isinstance(opt, str)
def test_uncertain_classification_returns_confidence(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_uncertain()):
result = route_intent("something ambiguous", 1, 1)
assert result["confidence"] == 0.40
def test_clarification_options_contain_expected_labels(self):
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_uncertain()):
result = route_intent("something ambiguous", 1, 1)
assert "Add new evidence" in result["options"]
assert "Ask for explanation" in result["options"]
assert "Request source" in result["options"]
assert "General help" in result["options"]
def test_all_intents_route_correctly(self):
intents = [
"PATIENT_EVIDENCE_QUERY",
"FOLLOW_UP_EXPLANATION",
"SOURCE_REQUEST",
"HELP_OR_OTHER"
]
for intent in intents:
with patch("intent_classification.intent_router_ml.classify_intent",
return_value=mock_classify_ready(label=intent)):
result = route_intent("some input", 1, 1)
assert result["intent"] == intent
#────── classify_intent────────────────────────────────────────────────────────────
class TestClassifyIntent:
@patch("intent_classification.intent_classification_ml.embedder")
@patch("intent_classification.intent_classification_ml.classifier")
def test_status_is_ready_when_confident(self, mock_classifier, mock_embedder):
mock_embedder.encode.return_value = np.zeros((1, 384))
mock_probs = np.array([0.05, 0.85, 0.05, 0.05])
mock_classifier.predict_proba.return_value = [mock_probs]
mock_id_to_label = {0: "HELP_OR_OTHER", 1: "PATIENT_EVIDENCE_QUERY",
2: "FOLLOW_UP_EXPLANATION", 3: "SOURCE_REQUEST"}
with patch("intent_classification.intent_classification_ml.id_to_label", mock_id_to_label):
result = classify_intent("patient has a fever")
assert result["status"] == "READY"
@patch("intent_classification.intent_classification_ml.embedder")
@patch("intent_classification.intent_classification_ml.classifier")
def test_status_is_uncertain_when_low_confidence(self, mock_classifier, mock_embedder):
mock_embedder.encode.return_value = np.zeros((1, 384))
mock_probs = np.array([0.30, 0.35, 0.20, 0.15])
mock_classifier.predict_proba.return_value = [mock_probs]
mock_id_to_label = {0: "HELP_OR_OTHER", 1: "PATIENT_EVIDENCE_QUERY",
2: "FOLLOW_UP_EXPLANATION", 3: "SOURCE_REQUEST"}
with patch("intent_classification.intent_classification_ml.id_to_label", mock_id_to_label):
result = classify_intent("patient has a cough")
assert result["status"] == "UNCERTAIN"
@patch("intent_classification.intent_classification_ml.embedder")
@patch("intent_classification.intent_classification_ml.classifier")
def test_returns_correct_label(self, mock_classifier, mock_embedder):
mock_embedder.encode.return_value = np.zeros((1, 384))
mock_probs = np.array([0.05, 0.05, 0.85, 0.05])
mock_classifier.predict_proba.return_value = [mock_probs]
mock_id_to_label = {0: "HELP_OR_OTHER", 1: "PATIENT_EVIDENCE_QUERY",
2: "FOLLOW_UP_EXPLANATION", 3: "SOURCE_REQUEST"}
with patch("intent_classification.intent_classification_ml.id_to_label", mock_id_to_label):
result = classify_intent("why does smoking cause cancer?")
assert result["label"] == "FOLLOW_UP_EXPLANATION"
@patch("intent_classification.intent_classification_ml.embedder")
@patch("intent_classification.intent_classification_ml.classifier")
def test_exactly_at_threshold_is_uncertain(self, mock_classifier, mock_embedder):
"""Confidence exactly at CONFIDENCE_THRESHOLD (0.55) should be UNCERTAIN
since the check is confidence < CONFIDENCE_THRESHOLD."""
mock_embedder.encode.return_value = np.zeros((1, 384))
mock_probs = np.array([0.15, 0.55, 0.15, 0.15])
mock_classifier.predict_proba.return_value = [mock_probs]
mock_id_to_label = {0: "HELP_OR_OTHER", 1: "PATIENT_EVIDENCE_QUERY",
2: "FOLLOW_UP_EXPLANATION", 3: "SOURCE_REQUEST"}
with patch("intent_classification.intent_classification_ml.id_to_label", mock_id_to_label):
result = classify_intent("some borderline threshold input")
assert result["status"] == "READY"
@patch("intent_classification.intent_classification_ml.embedder")
@patch("intent_classification.intent_classification_ml.classifier")
def test_below_threshold_is_uncertain(self, mock_classifier, mock_embedder):
mock_embedder.encode.return_value = np.zeros((1, 384))
mock_probs = np.array([0.18, 0.54, 0.16, 0.12])
mock_classifier.predict_proba.return_value = [mock_probs]
mock_id_to_label = {0: "HELP_OR_OTHER", 1: "PATIENT_EVIDENCE_QUERY",
2: "FOLLOW_UP_EXPLANATION", 3: "SOURCE_REQUEST"}
with patch("intent_classification.intent_classification_ml.id_to_label", mock_id_to_label):
result = classify_intent("borderline input")
assert result["status"] == "UNCERTAIN"