"""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