File size: 2,255 Bytes
bb5ec1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5ccd8c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from pathlib import Path

import pytest
from fastapi.testclient import TestClient

from deepverify.api import app

FIXTURES = Path(__file__).parent / "fixtures"


@pytest.fixture(scope="module")
def client() -> TestClient:
    with TestClient(app) as test_client:
        yield test_client


def _upload(client: TestClient, name: str, content: bytes | None = None):
    payload = content if content is not None else (FIXTURES / name).read_bytes()
    return client.post("/v1/detect", files={"file": (name, payload, "image/png")})


def test_health_reports_model(client: TestClient):
    body = client.get("/health").json()
    assert body["status"] == "ok"
    assert body["model_id"].startswith("yermandy/deepfake-detection")
    assert len(body["weights_sha256"]) == 64


def test_detect_returns_a_score(client: TestClient):
    body = _upload(client, "real.png").json()
    assert 0.0 <= body["fake_probability"] <= 1.0
    assert body["label"] in {"fake", "real"}
    assert body["is_deepfake"] is (body["fake_probability"] >= body["threshold"])


def test_face_free_image_is_rejected_not_scored(client: TestClient):
    response = _upload(client, "no_face.png")
    assert response.status_code == 422
    assert "no face" in response.json()["detail"].lower()


def test_non_image_is_rejected(client: TestClient):
    response = _upload(client, "notes.txt", content=b"this is not an image")
    assert response.status_code == 400


def test_run_prediction_is_the_seam_the_route_uses(client: TestClient, monkeypatch):
    """The Space replaces run_prediction to scope inference to the GPU window.

    If the route ever calls the detector directly again, that override silently
    stops applying and ZeroGPU deployments break outside a GPU context.
    """
    from deepverify import api
    from deepverify.detector import Prediction

    monkeypatch.setattr(
        api,
        "run_prediction",
        lambda image: Prediction(
            fake_probability=0.75,
            real_probability=0.25,
            threshold=0.5,
            face_box=(1, 2, 3, 4),
            face_confidence=0.9,
        ),
    )

    body = _upload(client, "real.png").json()
    assert body["fake_probability"] == 0.75
    assert body["face_box"] == [1, 2, 3, 4]