File size: 4,210 Bytes
5ab38b4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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