File size: 3,148 Bytes
7e25f7a | 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 | """Unit tests for cores.metadata.forensic — ICC, thumbnail, editing history, etc."""
from __future__ import annotations
import io
import pytest
from PIL import Image
from cores.metadata import (
extract_icc_profile,
extract_thumbnail,
extract_embedded_preview,
extract_editing_history,
analyze_compression,
normalize_timestamp,
extract_lens_info,
camera_fingerprint,
)
class TestICCProfile:
def test_no_icc_returns_none(self, sample_image_bytes):
result = extract_icc_profile(sample_image_bytes)
# Synthetic JPEG likely has no ICC
assert result is None or result.get("present") is False
def test_empty_bytes(self):
assert extract_icc_profile(b"") is None
class TestThumbnail:
def test_no_thumbnail_returns_none(self, sample_image_bytes):
result = extract_thumbnail(sample_image_bytes)
assert result is None or result.get("present") is False
def test_empty_bytes(self):
assert extract_thumbnail(b"") is None
class TestEditingHistory:
def test_empty_exif(self):
assert extract_editing_history({}) == []
def test_extracts_software(self):
exif = {"Software": "Adobe Photoshop"}
history = extract_editing_history(exif)
assert any("Software" in h for h in history)
def test_extracts_artist(self):
exif = {"Artist": "John Doe"}
history = extract_editing_history(exif)
assert any("Artist" in h for h in history)
class TestCompressionAnalysis:
def test_returns_format(self, sample_image_bytes):
result = analyze_compression(sample_image_bytes)
assert result is not None
assert result["format"] == "JPEG"
assert result["size_bytes"] > 0
assert result["compression_ratio"] > 0
def test_empty_bytes(self):
assert analyze_compression(b"") is None
class TestTimestampNormalization:
def test_exif_format(self):
result = normalize_timestamp("2023:01:15 14:30:45")
assert result is not None
assert result["iso"].startswith("2023-01-15T14:30:45")
assert result["timezone"] == "unknown"
def test_iso_format(self):
result = normalize_timestamp("2023-01-15 14:30:45")
assert result is not None
assert result["iso"].startswith("2023-01-15")
def test_empty(self):
assert normalize_timestamp("") is None
def test_invalid(self):
result = normalize_timestamp("not a date")
assert result is not None
assert result["iso"] is None
class TestLensInfo:
def test_extracts_lens_model(self):
exif = {"LensModel": "24-70mm f/2.8"}
assert extract_lens_info(exif) == "24-70mm f/2.8"
def test_empty_exif(self):
assert extract_lens_info({}) is None
class TestCameraFingerprint:
def test_returns_hash(self, sample_image_bytes):
fp = camera_fingerprint(sample_image_bytes, (200, 200))
# Should return a 32-char hash or None
if fp is not None:
assert len(fp) == 32
def test_empty_bytes(self):
assert camera_fingerprint(b"", (200, 200)) is None
|