File size: 3,904 Bytes
23d337e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Unit tests for confidence/engine.py."""

from __future__ import annotations

from dataclasses import dataclass

from confidence.engine import ConfidenceEngine


@dataclass
class FakeBox:
    detector: str
    confidence: float


@dataclass
class FakeMatch:
    query_face_index: int
    best_match: str
    distance: float
    recognizer: str


@dataclass
class FakeAnalysis:
    provider: str
    quality_score: float


@dataclass
class FakeMetadata:
    provider: str
    format: str


@dataclass
class FakeForensics:
    provider: str
    integrity_score: float


class TestConfidenceEngine:
    def test_score_detection_returns_score_in_range(self):
        engine = ConfidenceEngine()
        box = FakeBox(detector="haar", confidence=0.9)
        score = engine.score_detection(box, {})
        assert 0.0 <= score.overall <= 1.0
        assert "source_reliability" in score.components
        assert "cross_provider_consensus" in score.components
        assert score.method == "weighted_average"
        assert "haar" in score.explanation

    def test_score_detection_higher_confidence_yields_higher_score(self):
        engine = ConfidenceEngine()
        box_low = FakeBox(detector="haar", confidence=0.1)
        box_high = FakeBox(detector="haar", confidence=1.0)
        score_low = engine.score_detection(box_low, {})
        score_high = engine.score_detection(box_high, {})
        assert score_high.overall > score_low.overall

    def test_score_match_returns_score_in_range(self):
        engine = ConfidenceEngine()
        m = FakeMatch(query_face_index=0, best_match="alice", distance=0.3, recognizer="face_recognition")
        score = engine.score_match(m)
        assert 0.0 <= score.overall <= 1.0
        assert "face_recognition" in score.explanation

    def test_score_match_smaller_distance_yields_higher_score(self):
        engine = ConfidenceEngine()
        m_close = FakeMatch(query_face_index=0, best_match="alice", distance=0.1, recognizer="face_recognition")
        m_far = FakeMatch(query_face_index=0, best_match="alice", distance=0.9, recognizer="face_recognition")
        assert engine.score_match(m_close).overall > engine.score_match(m_far).overall

    def test_score_image_analysis(self):
        engine = ConfidenceEngine()
        a = FakeAnalysis(provider="image_quality", quality_score=0.8)
        score = engine.score_image_analysis(a)
        assert 0.0 <= score.overall <= 1.0
        assert "image_quality" in score.explanation

    def test_score_metadata_with_format(self):
        engine = ConfidenceEngine()
        m = FakeMetadata(provider="exif", format="JPEG")
        score = engine.score_metadata(m)
        assert 0.0 <= score.overall <= 1.0
        assert "JPEG" in score.explanation

    def test_score_metadata_without_format(self):
        engine = ConfidenceEngine()
        m = FakeMetadata(provider="exif", format=None)
        score = engine.score_metadata(m)
        # Without format, extraction_conf drops to 0.5 — should be lower than with format
        m_with = FakeMetadata(provider="exif", format="JPEG")
        score_with = engine.score_metadata(m_with)
        assert score.overall < score_with.overall

    def test_score_forensics(self):
        engine = ConfidenceEngine()
        f = FakeForensics(provider="image_integrity", integrity_score=0.9)
        score = engine.score_forensics(f)
        assert 0.0 <= score.overall <= 1.0

    def test_score_overall_with_no_results(self):
        engine = ConfidenceEngine()
        score = engine.score_overall()
        assert score.overall == 0.0
        assert "No results" in score.explanation

    def test_reliability_overrides(self):
        engine = ConfidenceEngine(reliability_overrides={"haar": 1.0})
        assert engine._reliability["haar"] == 1.0
        # Default reliabilities should still be present
        assert "dnn" in engine._reliability