face-intel / tests /providers /test_exif.py
Marwan
Restructure + add reverse face search (PimEyes-style)
f5eeb1c
Raw
History Blame Contribute Delete
2.77 kB
"""Provider tests for EXIFProvider."""
from __future__ import annotations
import cv2
import io
import numpy as np
import pytest
from PIL import Image
from config.settings import Settings
from pipeline.feature_extraction import PipelineOutput
from providers.metadata.exif import EXIFProvider
@pytest.fixture
def exif_provider():
return EXIFProvider(settings=Settings(environment="test", db_path=":memory:"))
@pytest.fixture
def pipeline_with_bytes(sample_image_bytes):
img = cv2.imdecode(np.frombuffer(sample_image_bytes, np.uint8), cv2.IMREAD_COLOR)
return PipelineOutput(
image=img, image_hash="h", width=img.shape[1], height=img.shape[0], source="bytes",
original_bytes=sample_image_bytes, original_format=".jpg",
)
@pytest.fixture
def pipeline_without_bytes(sample_image_bytes):
"""A pipeline output WITHOUT original_bytes — EXIF should gracefully return empty."""
img = cv2.imdecode(np.frombuffer(sample_image_bytes, np.uint8), cv2.IMREAD_COLOR)
return PipelineOutput(
image=img, image_hash="h", width=img.shape[1], height=img.shape[0], source="bytes",
original_bytes=None, original_format=None,
)
class TestEXIFProvider:
def test_name(self, exif_provider):
assert exif_provider.name == "exif"
def test_capability(self, exif_provider):
from models.providers import ProviderCapability
assert exif_provider.capability == ProviderCapability.METADATA
def test_is_available(self, exif_provider):
# Should be available if Pillow is installed (it is, in requirements)
assert exif_provider.is_available() is True
def test_execute_with_bytes(self, exif_provider, pipeline_with_bytes):
result = exif_provider.execute(pipeline_with_bytes)
assert result.success is True
assert "format" in result.normalized
assert "exif" in result.normalized
assert isinstance(result.normalized["exif"], dict)
def test_execute_without_bytes_returns_empty(self, exif_provider, pipeline_without_bytes):
result = exif_provider.execute(pipeline_without_bytes)
assert result.success is True
assert result.normalized["exif"] == {}
def test_synthetic_jpeg_has_no_exif(self, exif_provider, pipeline_with_bytes):
"""A synthetic JPEG (no camera) should have no EXIF tags."""
result = exif_provider.execute(pipeline_with_bytes)
assert len(result.normalized["exif"]) == 0
assert result.normalized["camera_make"] is None
assert result.normalized["capture_time"] is None
def test_format_extracted(self, exif_provider, pipeline_with_bytes):
result = exif_provider.execute(pipeline_with_bytes)
assert result.normalized["format"] == "JPEG"