sentinel / tests /test_conversation.py
jeuko's picture
Sync from GitHub (main)
cc034ee verified
# pylint: disable=missing-docstring
from unittest.mock import MagicMock, patch
from sentinel.conversation import ConversationManager
from sentinel.models import (
ConversationResponse,
InitialAssessment,
)
from sentinel.user_input import (
Anthropometrics,
Demographics,
Lifestyle,
PersonalMedicalHistory,
SmokingHistory,
UserInput,
)
def sample_user() -> UserInput:
return UserInput(
demographics=Demographics(
age_years=30,
sex="male",
anthropometrics=Anthropometrics(height_cm=175, weight_kg=70),
),
lifestyle=Lifestyle(
smoking=SmokingHistory(
status="never",
cigarettes_per_day=0,
years_smoked=0,
),
),
personal_medical_history=PersonalMedicalHistory(
chronic_conditions=[],
previous_cancers=[],
),
family_history=[],
)
@patch("sentinel.llm_service.create_initial_assessment_chain")
@patch("sentinel.llm_service.create_conversational_chain")
def test_conversation_flow(mock_create_conversational_chain, mock_create_initial_chain):
structured = MagicMock()
freeform = MagicMock()
structured.invoke.return_value = {
"overall_summary": "ok",
"llm_risk_interpretations": [],
"dx_recommendations": [],
}
freeform.invoke.return_value = "hi"
mock_create_initial_chain.return_value = structured
mock_create_conversational_chain.return_value = freeform
conv = ConversationManager(structured, freeform)
user = sample_user()
result = conv.initial_assessment(user)
assert isinstance(result, InitialAssessment)
assert result.overall_summary == "ok"
assert result.calculated_risk_scores == {}
# Verify history contains initial assessment message
assert len(conv.history) == 1
assert conv.history[0][0].startswith("Initial assessment for user profile:")
assert conv.history[0][1] == result.model_dump_json()
answer = conv.follow_up("question")
assert isinstance(answer, ConversationResponse)
assert answer.response == "hi"
# Verify follow-up added to history
assert len(conv.history) == 2
assert conv.history[1] == ("question", "hi")