from __future__ import annotations from gcmd_classifier.models import ( ClassificationFinalStatus, ClassificationRecord, ConfidenceMetadata, DeterministicValidationResult, SupportType, ) from gcmd_classifier.pipeline.review import ( REVIEW_RECOMMENDED_WEAK_SUPPORT, flag_review_risk, ) def _record( *, level: str = "Variable_Level_1", support_type: SupportType | None = SupportType.EXPLICIT, confidence_final: float | None = 0.9, final_status: ClassificationFinalStatus = ClassificationFinalStatus.ACCEPTED, ) -> ClassificationRecord: return ClassificationRecord( UUID=f"uuid-{level.lower()}", name=f"Name {level}", level=level, canonical_path=f"ATMOSPHERE > TERM > {level}", path_components=("ATMOSPHERE", "TERM", level), topic="ATMOSPHERE", term="TERM" if level != "Topic" else None, confidence=ConfidenceMetadata(final=confidence_final), classifier_evidence="Evidence.", support_type=support_type, deterministic_validation=DeterministicValidationResult(valid=True), final_status=final_status, ) def _flagged(record: ClassificationRecord) -> ClassificationRecord: return flag_review_risk((record,))[0] def test_inferred_variable_level_2_is_flagged_even_with_high_confidence() -> None: record = _flagged( _record(level="Variable_Level_2", support_type=SupportType.INFERRED, confidence_final=0.95) ) assert record.review_required is True assert record.final_status is ClassificationFinalStatus.ACCEPTED assert record.warnings[-1].code == REVIEW_RECOMMENDED_WEAK_SUPPORT def test_inferred_variable_level_3_is_flagged_even_with_high_confidence() -> None: record = _flagged( _record(level="Variable_Level_3", support_type=SupportType.INFERRED, confidence_final=0.95) ) assert record.review_required is True assert record.warnings[-1].code == REVIEW_RECOMMENDED_WEAK_SUPPORT def test_inferred_low_confidence_is_flagged() -> None: record = _flagged( _record(level="Variable_Level_1", support_type=SupportType.INFERRED, confidence_final=0.74) ) assert record.review_required is True assert record.warnings[-1].code == REVIEW_RECOMMENDED_WEAK_SUPPORT def test_mixed_low_confidence_is_flagged() -> None: record = _flagged(_record(level="Term", support_type=SupportType.MIXED, confidence_final=0.69)) assert record.review_required is True assert record.warnings[-1].code == REVIEW_RECOMMENDED_WEAK_SUPPORT def test_inferred_or_mixed_topic_is_flagged() -> None: inferred = _flagged( _record(level="Topic", support_type=SupportType.INFERRED, confidence_final=0.9) ) mixed = _flagged(_record(level="Topic", support_type=SupportType.MIXED, confidence_final=0.9)) assert inferred.review_required is True assert mixed.review_required is True def test_explicit_or_strong_mixed_classification_is_not_flagged() -> None: explicit = _flagged( _record(level="Variable_Level_3", support_type=SupportType.EXPLICIT, confidence_final=0.1) ) strong_mixed = _flagged( _record(level="Variable_Level_1", support_type=SupportType.MIXED, confidence_final=0.70) ) assert explicit.review_required is False assert explicit.warnings == () assert strong_mixed.review_required is False assert strong_mixed.warnings == () def test_non_accepted_classification_is_not_flagged() -> None: record = _flagged( _record( level="Variable_Level_3", support_type=SupportType.INFERRED, confidence_final=0.1, final_status=ClassificationFinalStatus.REJECTED, ) ) assert record.review_required is False assert record.warnings == () def test_review_warning_appears_in_json_output() -> None: record = _flagged( _record(level="Variable_Level_2", support_type=SupportType.INFERRED, confidence_final=0.95) ) dumped = record.model_dump(mode="json") assert dumped["review_required"] is True assert dumped["final_status"] == "accepted" assert dumped["warnings"][-1]["code"] == REVIEW_RECOMMENDED_WEAK_SUPPORT