DocUA's picture
Fix CSV download button for Hugging Face Spaces - use DownloadButton for direct file download
ab93d81
# conftest.py
"""
Pytest fixtures for Chaplain Feedback tests.
"""
import pytest
from hypothesis import strategies as st
from datetime import datetime
from src.core.chaplain_models import (
DistressIndicator,
FollowUpQuestion,
ClassificationFlowResult,
TaggingRecord,
InteractionStepLog,
INDICATOR_DEFINITIONS,
CLASSIFICATION_SUBCATEGORIES,
QUESTION_ISSUE_TYPES,
REFERRAL_ISSUE_TYPES,
INTERACTION_STEP_TYPES,
)
# =============================================================================
# Hypothesis Strategies for generating test data
# =============================================================================
def valid_id_strategy():
"""Generate valid IDs."""
return st.text(
alphabet="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-",
min_size=1,
max_size=20,
)
def distress_indicator_strategy():
"""Generate random DistressIndicator instances."""
return st.builds(
DistressIndicator,
indicator_text=st.text(min_size=1, max_size=200),
category=st.sampled_from([
"Emotional", "Grief", "Existential", "Expressions",
"Spiritual", "Medical", "Social", "Cultural",
"Engagement", "Guilt", "Anger", "Aging",
"Environment", "Independence"
]),
subcategory=st.text(min_size=1, max_size=100),
severity=st.sampled_from(["red", "yellow"]),
confidence=st.floats(min_value=0.0, max_value=1.0, allow_nan=False),
definition_reference=st.text(max_size=20),
)
def follow_up_question_strategy():
"""Generate random FollowUpQuestion instances."""
return st.builds(
FollowUpQuestion,
question_id=valid_id_strategy(),
question_text=st.text(min_size=1, max_size=500),
purpose=st.text(min_size=1, max_size=200),
)
def classification_flow_result_strategy():
"""Generate random ClassificationFlowResult instances."""
return st.builds(
ClassificationFlowResult,
classification=st.sampled_from(["red", "yellow", "green"]),
confidence=st.floats(min_value=0.0, max_value=1.0, allow_nan=False),
indicators=st.lists(distress_indicator_strategy(), max_size=5),
explanation=st.text(max_size=500),
permission_check_message=st.one_of(st.none(), st.text(max_size=300)),
referral_message=st.one_of(st.none(), st.text(max_size=500)),
consent_status=st.one_of(st.none(), st.sampled_from(["granted", "declined"])),
follow_up_questions=st.lists(follow_up_question_strategy(), max_size=3),
patient_responses=st.lists(st.text(max_size=200), max_size=3),
re_evaluation_result=st.one_of(st.none(), st.sampled_from(["red", "green"])),
)
def tagging_record_strategy():
"""Generate random TaggingRecord instances."""
return st.builds(
TaggingRecord,
record_id=valid_id_strategy(),
message_id=valid_id_strategy(),
is_classification_correct=st.booleans(),
classification_subcategory=st.one_of(
st.none(),
st.sampled_from(CLASSIFICATION_SUBCATEGORIES)
),
correct_classification=st.one_of(
st.none(),
st.sampled_from(["red", "yellow", "green"])
),
question_issues=st.lists(
st.sampled_from(QUESTION_ISSUE_TYPES),
max_size=3,
unique=True
),
question_comments=st.one_of(st.none(), st.text(max_size=200)),
referral_issues=st.lists(
st.sampled_from(REFERRAL_ISSUE_TYPES),
max_size=3,
unique=True
),
referral_comments=st.one_of(st.none(), st.text(max_size=200)),
indicator_issues=st.lists(st.text(min_size=1, max_size=50), max_size=5),
indicator_comments=st.one_of(st.none(), st.text(max_size=200)),
general_notes=st.text(max_size=300),
timestamp=st.just(datetime.now()),
)
def interaction_step_log_strategy():
"""Generate random InteractionStepLog instances (without nested tagging)."""
return st.builds(
InteractionStepLog,
step_id=valid_id_strategy(),
session_id=valid_id_strategy(),
message_id=valid_id_strategy(),
step_type=st.sampled_from(INTERACTION_STEP_TYPES),
input_text=st.text(max_size=500),
model_output=st.text(max_size=500),
approval_status=st.one_of(st.none(), st.sampled_from(["approved", "disapproved"])),
tagging_data=st.none(), # Simplified - no nested tagging for basic tests
timestamp=st.just(datetime.now()),
)
def interaction_step_log_with_tagging_strategy():
"""Generate random InteractionStepLog instances with nested tagging."""
return st.builds(
InteractionStepLog,
step_id=valid_id_strategy(),
session_id=valid_id_strategy(),
message_id=valid_id_strategy(),
step_type=st.sampled_from(INTERACTION_STEP_TYPES),
input_text=st.text(max_size=500),
model_output=st.text(max_size=500),
approval_status=st.one_of(st.none(), st.sampled_from(["approved", "disapproved"])),
tagging_data=st.one_of(st.none(), tagging_record_strategy()),
timestamp=st.just(datetime.now()),
)