Spaces:
Runtime error
Runtime error
| """Regression tests for CLI/reporting helper utilities.""" | |
| from pathlib import Path | |
| import pytest | |
| import yaml | |
| from sentinel.models import ( | |
| CancerRiskAssessment, | |
| ContributingFactor, | |
| ContributionStrength, | |
| DxRecommendation, | |
| InitialAssessment, | |
| RiskFactor, | |
| RiskFactorCategory, | |
| ) | |
| from sentinel.reporting import generate_excel_report, generate_pdf_report | |
| from sentinel.user_input import ( | |
| AlcoholConsumption, | |
| Anthropometrics, | |
| CancerType, | |
| Demographics, | |
| Ethnicity, | |
| FamilyMemberCancer, | |
| FamilyRelation, | |
| FamilySide, | |
| Lifestyle, | |
| PersonalMedicalHistory, | |
| RelationshipDegree, | |
| Sex, | |
| SmokingHistory, | |
| SmokingStatus, | |
| UserInput, | |
| ) | |
| from sentinel.utils import load_user_file | |
| def test_load_user_file_yaml(tmp_path): | |
| """Ensure YAML user profiles load into a ``UserInput`` instance. | |
| Args: | |
| tmp_path: Pytest-managed temporary directory path. | |
| """ | |
| data = { | |
| "demographics": { | |
| "age_years": 30, | |
| "sex": "male", | |
| "anthropometrics": {"height_cm": 175, "weight_kg": 70}, | |
| }, | |
| "lifestyle": { | |
| "smoking": {"status": "never"}, | |
| "alcohol_consumption": "none", | |
| }, | |
| "personal_medical_history": {}, | |
| "family_history": [], | |
| } | |
| path = tmp_path / "user.yaml" | |
| path.write_text(yaml.dump(data)) | |
| user = load_user_file(str(path)) | |
| assert isinstance(user, UserInput) | |
| assert user.demographics.age_years == 30 | |
| assert user.lifestyle.smoking.status == SmokingStatus.NEVER | |
| assert user.symptoms == [] | |
| def test_generate_reports(tmp_path, save_files): | |
| """Generate PDF and Excel reports and assert the outputs exist. | |
| Args: | |
| tmp_path: Pytest-managed temporary directory path. | |
| save_files: Whether to write outputs to repo path or temporary path. | |
| """ | |
| # 1. Create mock UserInput data with all fields | |
| user = UserInput( | |
| demographics=Demographics( | |
| age_years=45, | |
| sex=Sex.FEMALE, | |
| ethnicity=Ethnicity.WHITE, | |
| anthropometrics=Anthropometrics(height_cm=165, weight_kg=70), | |
| ), | |
| lifestyle=Lifestyle( | |
| smoking=SmokingHistory( | |
| status=SmokingStatus.FORMER, | |
| pack_years=10, | |
| ), | |
| alcohol_consumption=AlcoholConsumption.LIGHT, | |
| ), | |
| personal_medical_history=PersonalMedicalHistory( | |
| previous_cancers=[CancerType.MELANOMA], | |
| ), | |
| family_history=[ | |
| FamilyMemberCancer( | |
| relation=FamilyRelation.MOTHER, | |
| cancer_type=CancerType.BREAST, | |
| age_at_diagnosis=50, | |
| degree=RelationshipDegree.FIRST, | |
| side=FamilySide.MATERNAL, | |
| ) | |
| ], | |
| ) | |
| # 2. Create mock InitialAssessment data | |
| assessment = InitialAssessment( | |
| response="This is a summary response.", | |
| thinking="The user is a 45-year-old female with a BRCA2 mutation...", | |
| reasoning="1. Assessed breast cancer risk as high due to BRCA2...", | |
| overall_summary="This assessment indicates a significant and immediate need...", | |
| overall_risk_score=68, | |
| identified_risk_factors=[ | |
| RiskFactor( | |
| description="Positive for BRCA2 genetic mutation", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| ), | |
| RiskFactor( | |
| description="Personal history of Skin Cancer", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| ), | |
| RiskFactor( | |
| description="First-degree relative (Mother) with Breast Cancer", | |
| category=RiskFactorCategory.FAMILY_HISTORY, | |
| ), | |
| RiskFactor( | |
| description="Age of 45", category=RiskFactorCategory.DEMOGRAPHICS | |
| ), | |
| RiskFactor( | |
| description="Former smoker (10 pack-years)", | |
| category=RiskFactorCategory.LIFESTYLE, | |
| ), | |
| ], | |
| llm_risk_interpretations=[ | |
| CancerRiskAssessment( | |
| cancer_type="Breast Cancer", | |
| risk_level=4, | |
| explanation="Risk is high due to the combination of a known BRCA2 mutation and a first-degree relative with breast cancer.", | |
| recommended_steps=[ | |
| "Annual mammogram", | |
| "Annual breast MRI", | |
| "Consultation with a high-risk breast specialist", | |
| ], | |
| contributing_factors=[ | |
| ContributingFactor( | |
| description="Positive for BRCA2 genetic mutation", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| strength=ContributionStrength.MAJOR, | |
| ), | |
| ContributingFactor( | |
| description="First-degree relative (Mother) with Breast Cancer", | |
| category=RiskFactorCategory.FAMILY_HISTORY, | |
| strength=ContributionStrength.MAJOR, | |
| ), | |
| ContributingFactor( | |
| description="Age of 45", | |
| category=RiskFactorCategory.DEMOGRAPHICS, | |
| strength=ContributionStrength.MINOR, | |
| ), | |
| ], | |
| ), | |
| CancerRiskAssessment( | |
| cancer_type="Ovarian Cancer", | |
| risk_level=4, | |
| explanation="Risk is significantly elevated due to the known BRCA2 mutation.", | |
| recommended_steps=[ | |
| "Consider risk-reducing surgery", | |
| "Transvaginal ultrasound and CA-125 blood test for surveillance", | |
| ], | |
| contributing_factors=[ | |
| ContributingFactor( | |
| description="Positive for BRCA2 genetic mutation", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| strength=ContributionStrength.MAJOR, | |
| ) | |
| ], | |
| ), | |
| CancerRiskAssessment( | |
| cancer_type="Skin Cancer", | |
| risk_level=3, | |
| explanation="Risk is moderate-to-high due to a personal history of skin cancer, which is a strong predictor of future risk.", | |
| recommended_steps=[ | |
| "Annual full-body dermatological examination.", | |
| "Vigilant use of broad-spectrum sunscreen.", | |
| ], | |
| contributing_factors=[ | |
| ContributingFactor( | |
| description="Personal history of Skin Cancer", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| strength=ContributionStrength.MAJOR, | |
| ) | |
| ], | |
| ), | |
| CancerRiskAssessment( | |
| cancer_type="Colorectal Cancer", | |
| risk_level=3, | |
| explanation="Risk is moderate as you have reached the standard screening age. Some studies suggest a minor increased risk with BRCA2 mutations.", | |
| recommended_steps=[ | |
| "Begin regular colonoscopy screenings as per standard guidelines (age 45)." | |
| ], | |
| contributing_factors=[ | |
| ContributingFactor( | |
| description="Age of 45", | |
| category=RiskFactorCategory.DEMOGRAPHICS, | |
| strength=ContributionStrength.MODERATE, | |
| ), | |
| ContributingFactor( | |
| description="Positive for BRCA2 genetic mutation", | |
| category=RiskFactorCategory.PERSONAL_MEDICAL, | |
| strength=ContributionStrength.MINOR, | |
| ), | |
| ], | |
| ), | |
| CancerRiskAssessment( | |
| cancer_type="Lung Cancer", | |
| risk_level=2, | |
| explanation="A history of smoking, even as a former smoker, confers a residual risk for lung cancer, though it is not high enough to warrant screening at this time.", | |
| recommended_steps=["Monitor for symptoms like persistent cough."], | |
| lifestyle_advice="Continue to avoid smoking.", | |
| contributing_factors=[ | |
| ContributingFactor( | |
| description="Former smoker (10 pack-years)", | |
| category=RiskFactorCategory.LIFESTYLE, | |
| strength=ContributionStrength.MODERATE, | |
| ) | |
| ], | |
| ), | |
| ], | |
| dx_recommendations=[ | |
| DxRecommendation( | |
| test_name="Mammogram", | |
| frequency="Annually", | |
| rationale="High risk for breast cancer due to BRCA2 and family history.", | |
| recommendation_level=5, | |
| ), | |
| DxRecommendation( | |
| test_name="MRI", # Breast MRI | |
| frequency="Annually", | |
| rationale="Supplemental screening for high-risk individuals with BRCA mutations.", | |
| recommendation_level=5, | |
| ), | |
| DxRecommendation( | |
| test_name="Colonoscopy", | |
| frequency="Every 5-10 years", | |
| rationale="Standard screening age reached; commence screening.", | |
| recommendation_level=4, | |
| ), | |
| ], | |
| ) | |
| # 3. Define output path | |
| if save_files: | |
| output_path = Path("outputs") | |
| output_path.mkdir(exist_ok=True) | |
| else: | |
| output_path = tmp_path | |
| # 4. Define output filenames | |
| pdf_filename = output_path / "report.pdf" | |
| excel_filename = output_path / "report.xlsx" | |
| # 5. Generate and check PDF report | |
| try: | |
| generate_pdf_report(assessment, user, str(pdf_filename)) | |
| assert pdf_filename.exists() | |
| assert pdf_filename.stat().st_size > 0 # Check file is not empty | |
| except Exception as e: | |
| # The test environment might not have PDF generation dependencies | |
| print(f"PDF generation failed, likely due to missing dependencies: {e}") | |
| pytest.fail(f"PDF generation failed with an unexpected error: {e}") | |
| # 6. Generate and check Excel report | |
| generate_excel_report(assessment, user, str(excel_filename)) | |
| assert excel_filename.exists() | |
| assert excel_filename.stat().st_size > 0 | |