File size: 2,786 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
"""Provider tests for ImageIntegrityProvider."""

from __future__ import annotations

import cv2
import numpy as np
import pytest

from config.settings import Settings
from pipeline.feature_extraction import PipelineOutput
from providers.forensics.image_integrity import ImageIntegrityProvider


@pytest.fixture
def integrity_provider():
    return ImageIntegrityProvider(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",
    )


class TestImageIntegrityProvider:
    def test_name(self, integrity_provider):
        assert integrity_provider.name == "image_integrity"

    def test_capability(self, integrity_provider):
        from models.providers import ProviderCapability
        assert integrity_provider.capability == ProviderCapability.FORENSICS

    def test_is_available(self, integrity_provider):
        assert integrity_provider.is_available() is True

    def test_execute_returns_integrity_score(self, integrity_provider, pipeline_with_bytes):
        result = integrity_provider.execute(pipeline_with_bytes)
        assert result.success is True
        n = result.normalized
        assert "integrity_score" in n
        assert 0.0 <= n["integrity_score"] <= 1.0
        assert "sha256" in n["details"]
        assert n["details"]["sha256"] is not None  # original_bytes present

    def test_clean_image_has_high_integrity(self, integrity_provider, pipeline_with_bytes):
        result = integrity_provider.execute(pipeline_with_bytes)
        assert result.normalized["integrity_score"] >= 0.8

    def test_sha256_stable(self, integrity_provider, pipeline_with_bytes):
        r1 = integrity_provider.execute(pipeline_with_bytes)
        # Re-execute — should produce the same hash
        r2 = integrity_provider.execute(pipeline_with_bytes)
        assert r1.normalized["details"]["sha256"] == r2.normalized["details"]["sha256"]

    def test_no_original_bytes_handled_gracefully(self, integrity_provider, sample_image_bytes):
        img = cv2.imdecode(np.frombuffer(sample_image_bytes, np.uint8), cv2.IMREAD_COLOR)
        po = PipelineOutput(
            image=img, image_hash="h", width=img.shape[1], height=img.shape[0],
            source="bytes", original_bytes=None, original_format=None,
        )
        result = integrity_provider.execute(po)
        assert result.success is True
        # sha256 should be None when original_bytes is missing
        assert result.normalized["details"]["sha256"] is None