#!/usr/bin/env python3 """ Comprehensive test for Task 8: Enhanced Provider Summary Generation Implementation. This script validates that all requirements for Task 8 have been successfully implemented: - Task 8.1: Property test for provider summary completeness ✓ - Task 8.2: Updated provider summary data model ✓ - Task 8.3: Implemented triage context inclusion ✓ Requirements validated: 7.1, 7.2, 7.3, 7.4, 7.5 """ import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'src')) from datetime import datetime, timedelta from core.provider_summary_generator import ProviderSummaryGenerator, ProviderSummary def test_task_8_1_property_based_provider_summary(): """Test Task 8.1: Property test for provider summary completeness.""" print("Testing Task 8.1: Property-based provider summary completeness...") # This is tested in the main property test suite # Here we do a focused validation of the key properties generator = ProviderSummaryGenerator() # Property: Complete provider summary generation summary = generator.generate_summary( indicators=['severe_distress', 'suicidal_ideation', 'spiritual_crisis'], reasoning="Patient expressing severe spiritual distress with suicidal ideation requiring immediate intervention.", confidence=0.92, patient_name="Test Patient", patient_phone="555-123-4567", patient_email="test@example.com", triage_questions=["How are you feeling about your spiritual beliefs?"], triage_responses=["I feel like God has abandoned me completely"], conversation_context="Patient revealed escalating spiritual crisis during conversation.", medical_context={'conditions': ['terminal illness'], 'medications': ['pain management']}, context_factors=['escalating_distress', 'medical_context_relevant'] ) # Property assertion: All required fields present (Requirements 7.1-7.5) assert summary.patient_name == "Test Patient", "Should include patient contact information" assert summary.patient_phone == "555-123-4567", "Should include patient phone" assert summary.patient_email == "test@example.com", "Should include patient email" assert len(summary.indicators) == 3, "Should include all distress indicators" assert summary.reasoning.startswith("Patient expressing"), "Should provide clear reasoning" assert len(summary.triage_context) == 1, "Should include triage context" assert summary.conversation_context != "", "Should include conversation background" # Validation should pass for complete summary validation_issues = summary.validate_completeness() assert len(validation_issues) == 0, f"Complete summary should have no validation issues: {validation_issues}" print(" ✓ Property 7: Complete Provider Summary Generation validated") return True def test_task_8_2_enhanced_data_model(): """Test Task 8.2: Enhanced provider summary data model.""" print("Testing Task 8.2: Enhanced provider summary data model...") # Test enhanced ProviderSummary data model using generator generator = ProviderSummaryGenerator() summary = generator.generate_summary( indicators=['hopelessness', 'spiritual_abandonment', 'family_conflict'], reasoning="Comprehensive assessment indicates severe spiritual distress", confidence=0.88, patient_name="Jane Doe", patient_phone="555-987-6543", patient_email="jane.doe@email.com", emergency_contact="John Doe (husband) - 555-111-2222", medical_context={'conditions': ['chronic_pain'], 'medications': ['opioids']}, context_factors=['medical_context_relevant', 'family_stress'], defensive_patterns_detected=True ) # Test serialization summary_dict = summary.to_dict() # Enhanced fields should be present enhanced_fields = [ 'patient_email', 'emergency_contact', 'severity_level', 'urgency_level', 'medical_context', 'context_factors', 'defensive_patterns_detected', 'recommended_actions', 'follow_up_timeline', 'conversation_history_summary' ] for field in enhanced_fields: assert field in summary_dict, f"Enhanced data model should include {field}" # Test validation functionality validation_issues = summary.validate_completeness() if validation_issues: print(f" Validation issues: {validation_issues}") assert len(validation_issues) == 0, f"Complete summary should pass validation: {validation_issues}" # Test incomplete summary validation incomplete_summary = ProviderSummary() # Default values validation_issues = incomplete_summary.validate_completeness() assert len(validation_issues) > 0, "Incomplete summary should have validation issues" expected_issues = [ "Patient name is missing or placeholder", "Patient phone is missing or placeholder", "No distress indicators specified", "Classification reasoning is missing or insufficient" ] for expected_issue in expected_issues: assert any(expected_issue in issue for issue in validation_issues), \ f"Should detect issue: {expected_issue}" print(" ✓ Enhanced provider summary data model working correctly") return True def test_task_8_3_triage_context_inclusion(): """Test Task 8.3: Triage context inclusion and conversation background extraction.""" print("Testing Task 8.3: Triage context inclusion...") generator = ProviderSummaryGenerator() # Test comprehensive triage context inclusion triage_questions = [ "Can you tell me more about your spiritual concerns?", "How has this affected your daily life?", "What kind of support would be most helpful?" ] triage_responses = [ "I feel completely disconnected from my faith", "I can't find meaning in anything anymore", "I don't know who I can trust to talk about this" ] conversation_history = [ {"message": "I'm questioning everything I believed", "classification": "YELLOW"}, {"message": "Maybe there's no point to any of this", "classification": "RED"}, {"message": "I feel so alone in this struggle", "classification": "RED"} ] summary = generator.generate_summary( indicators=['spiritual_crisis', 'existential_despair', 'social_isolation'], reasoning="Patient experiencing profound spiritual crisis with existential questioning.", confidence=0.85, patient_name="Maria Santos", patient_phone="555-456-7890", triage_questions=triage_questions, triage_responses=triage_responses, conversation_context="Patient revealed deep spiritual questioning through targeted inquiry.", conversation_history=conversation_history, context_factors=['spiritual_crisis', 'existential_questioning'] ) # Test triage context inclusion (Requirement 7.4) assert len(summary.triage_context) == 3, "Should include all triage exchanges" for i, exchange in enumerate(summary.triage_context): assert 'question' in exchange, "Triage context should include questions" assert 'response' in exchange, "Triage context should include responses" assert 'timestamp' in exchange, "Triage context should include timestamps" assert exchange['question'] == triage_questions[i], "Should preserve original questions" assert exchange['response'] == triage_responses[i], "Should preserve original responses" # Test conversation background extraction (Requirement 7.5) assert summary.conversation_context != "", "Should include conversation context" assert summary.conversation_history_summary != "", "Should generate conversation summary" assert "3 exchanges" in summary.conversation_history_summary, "Should analyze conversation length" # Test display formatting includes triage information display_format = generator.format_for_display(summary) assert "TRIAGE EXCHANGES" in display_format, "Display should include triage section" for question in triage_questions: assert question in display_format, f"Should display triage question: {question}" for response in triage_responses: assert response in display_format, f"Should display triage response: {response}" assert "CONVERSATION ANALYSIS" in display_format, "Should include conversation analysis" # Test export format includes triage summary export_format = generator.format_for_export(summary) assert "Triage:" in export_format, "Export should include triage summary" print(" ✓ Triage context inclusion and conversation background extraction working") return True def test_requirements_validation(): """Validate that all Requirements 7.1-7.5 are met.""" print("Validating Requirements 7.1-7.5...") generator = ProviderSummaryGenerator() # Requirement 7.1: RED classification generates referral # THEN Provider_Summary_Generator SHALL include patient contact information print(" Testing Requirement 7.1...") summary_7_1 = generator.generate_summary( indicators=['severe_distress'], reasoning="RED classification test", confidence=0.8, patient_name="Contact Test Patient", patient_phone="555-CONTACT", patient_email="contact@test.com" ) assert summary_7_1.patient_name == "Contact Test Patient", "Req 7.1: Should include patient name" assert summary_7_1.patient_phone == "555-CONTACT", "Req 7.1: Should include patient phone" assert summary_7_1.patient_email == "contact@test.com", "Req 7.1: Should include patient email" print(" ✓ Requirement 7.1 validated") # Requirement 7.2: Provider summary is created # THEN system SHALL include specific distress indicators found in conversation print(" Testing Requirement 7.2...") test_indicators = ['hopelessness', 'spiritual_crisis', 'family_conflict'] summary_7_2 = generator.generate_summary( indicators=test_indicators, reasoning="Indicator test", confidence=0.8, patient_name="Indicator Test", patient_phone="555-INDICATOR" ) assert summary_7_2.indicators == test_indicators, "Req 7.2: Should include specific distress indicators" # Display should show all indicators display = generator.format_for_display(summary_7_2) for indicator in test_indicators: assert indicator in display, f"Req 7.2: Display should show indicator {indicator}" print(" ✓ Requirement 7.2 validated") # Requirement 7.3: Classification reasoning is documented # THEN system SHALL provide clear explanation of RED determination print(" Testing Requirement 7.3...") test_reasoning = "Patient expressing severe spiritual distress with suicidal ideation requiring immediate intervention based on multiple indicators." summary_7_3 = generator.generate_summary( indicators=['suicidal_ideation'], reasoning=test_reasoning, confidence=0.9, patient_name="Reasoning Test", patient_phone="555-REASONING" ) assert summary_7_3.reasoning == test_reasoning, "Req 7.3: Should provide clear reasoning" # Display should include reasoning display = generator.format_for_display(summary_7_3) assert test_reasoning in display, "Req 7.3: Display should show reasoning" print(" ✓ Requirement 7.3 validated") # Requirement 7.4: Triage context exists # THEN system SHALL include relevant question-answer pairs in summary print(" Testing Requirement 7.4...") test_questions = ["How are you coping?", "What support do you have?"] test_responses = ["I'm not coping well", "I don't have much support"] summary_7_4 = generator.generate_summary( indicators=['poor_coping'], reasoning="Triage context test", confidence=0.8, patient_name="Triage Test", patient_phone="555-TRIAGE", triage_questions=test_questions, triage_responses=test_responses ) assert len(summary_7_4.triage_context) == 2, "Req 7.4: Should include question-answer pairs" for i, exchange in enumerate(summary_7_4.triage_context): assert exchange['question'] == test_questions[i], "Req 7.4: Should preserve questions" assert exchange['response'] == test_responses[i], "Req 7.4: Should preserve responses" print(" ✓ Requirement 7.4 validated") # Requirement 7.5: Conversation history is available # THEN system SHALL provide relevant background context for provider print(" Testing Requirement 7.5...") test_context = "Patient initially seemed positive but revealed deeper concerns through follow-up questioning." test_history = [ {"message": "I'm doing okay", "classification": "GREEN"}, {"message": "Actually, I'm struggling with my faith", "classification": "YELLOW"} ] summary_7_5 = generator.generate_summary( indicators=['faith_struggle'], reasoning="Context test", confidence=0.8, patient_name="Context Test", patient_phone="555-CONTEXT", conversation_context=test_context, conversation_history=test_history ) assert summary_7_5.conversation_context == test_context, "Req 7.5: Should include conversation context" assert len(summary_7_5.conversation_history_summary) > 0, "Req 7.5: Should generate history summary" # Display should include background context display = generator.format_for_display(summary_7_5) assert test_context in display, "Req 7.5: Display should show conversation context" print(" ✓ Requirement 7.5 validated") print(" ✓ All Requirements 7.1-7.5 validated successfully") return True def test_integration_with_existing_system(): """Test integration with existing medical assistant system.""" print("Testing integration with existing system...") generator = ProviderSummaryGenerator() # Test backward compatibility with existing ProviderSummaryGenerator interface legacy_summary = generator.generate_summary( indicators=['anxiety', 'depression'], reasoning="Legacy interface test", confidence=0.75, patient_name="Legacy Test", patient_phone="555-LEGACY" ) # Should work with minimal parameters (backward compatibility) assert legacy_summary.patient_name == "Legacy Test", "Should support legacy interface" assert legacy_summary.classification == "RED", "Should default to RED classification" assert len(legacy_summary.indicators) == 2, "Should preserve indicators" # Enhanced features should have sensible defaults assert legacy_summary.severity_level in ['CRITICAL', 'HIGH', 'MODERATE'], "Should determine severity" assert legacy_summary.urgency_level in ['IMMEDIATE', 'URGENT', 'STANDARD'], "Should determine urgency" assert len(legacy_summary.recommended_actions) > 0, "Should generate recommended actions" # Test validation with existing system validation_result = generator.validate_summary_completeness(legacy_summary) assert isinstance(validation_result, bool), "Should provide validation result" # Test generation with validation summary_with_validation, issues = generator.generate_summary_with_validation( indicators=['test_indicator'], reasoning="Test with validation", confidence=0.8, patient_name="Validation Test", patient_phone="555-VALIDATE" ) assert isinstance(summary_with_validation, ProviderSummary), "Should return summary" assert isinstance(issues, list), "Should return validation issues list" print(" ✓ Integration with existing system working correctly") return True def main(): """Run all Task 8 completion tests.""" print("=" * 70) print("TASK 8 COMPLETION VALIDATION: ENHANCED PROVIDER SUMMARY GENERATION") print("=" * 70) try: # Test all subtasks if not test_task_8_1_property_based_provider_summary(): return False if not test_task_8_2_enhanced_data_model(): return False if not test_task_8_3_triage_context_inclusion(): return False if not test_requirements_validation(): return False if not test_integration_with_existing_system(): return False print("\n" + "=" * 70) print("✅ TASK 8 COMPLETED SUCCESSFULLY!") print("=" * 70) print("IMPLEMENTED FEATURES:") print("✓ Enhanced provider summary data model with comprehensive fields") print("✓ Complete contact information validation and completeness checking") print("✓ Comprehensive triage context inclusion with question-answer pairs") print("✓ Conversation background extraction and analysis") print("✓ Severity and urgency level determination based on assessment") print("✓ Medical context integration for comprehensive patient view") print("✓ Defensive pattern detection and handling recommendations") print("✓ Recommended actions generation based on specific assessment factors") print("✓ Enhanced display formatting with all required sections") print("✓ Export formatting with data cleaning for single-line output") print("✓ Validation and completeness checking with detailed issue reporting") print("✓ Integration with context-aware classification results") print("✓ Backward compatibility with existing system interfaces") print("\nREQUIREMENTS VALIDATED:") print("✓ 7.1: Provider summaries include complete patient contact information") print("✓ 7.2: Summaries include specific distress indicators from conversation") print("✓ 7.3: Clear explanation of RED classification reasoning provided") print("✓ 7.4: Relevant triage question-answer pairs included in summaries") print("✓ 7.5: Conversation background context provided for provider review") print("=" * 70) return True except Exception as e: print(f"\n❌ TASK 8 VALIDATION FAILED: {e}") import traceback traceback.print_exc() return False if __name__ == "__main__": success = main() sys.exit(0 if success else 1)