from pathlib import Path from fastapi.testclient import TestClient from app.main import app from app.realism_sources import RealismSample from app.style_detectors import StylePrediction, BUCKET_ANIME, BUCKET_PHOTO def test_list_style_detectors_endpoint(): with TestClient(app) as client: resp = client.get("/api/debug/style-detectors") assert resp.status_code == 200, resp.text ids = {d["id"] for d in resp.json()["detectors"]} assert "wd_taxonomy" in ids assert "imgutils_caformer" in ids def test_debug_style_eval_endpoint(monkeypatch, tmp_path: Path): samples = [ RealismSample( sample_id="photo_1", label="photo", bucket="photo", source="wikimedia_commons", file_url="https://example.invalid/p1.jpg", title="Portrait", query="portrait", ), RealismSample( sample_id="anime_1", label="anime", bucket="anime", source="safebooru", file_url="https://example.invalid/a1.jpg", title="1", query="1girl solo", ), RealismSample( sample_id="edge_1", label="edge_realistic", bucket="anime", source="safebooru", file_url="https://example.invalid/e1.jpg", title="2", query="realistic", ), ] monkeypatch.setattr( "app.style_eval.collect_realism_samples", lambda **_k: samples, ) def fake_download(sample): path = tmp_path / f"{sample.sample_id}.jpg" path.write_bytes(b"fake") return path monkeypatch.setattr("app.style_eval.download_realism_sample", fake_download) def fake_build(detector_id, **_k): def predict(path: Path) -> StylePrediction: name = path.stem if name.startswith("photo"): bucket = BUCKET_PHOTO label = "real" scores = {"real": 0.99, "anime": 0.01} else: bucket = BUCKET_ANIME label = "anime" scores = {"real": 0.02, "anime": 0.98} return StylePrediction( detector_id=detector_id, method=f"fake:{detector_id}", label=label, bucket=bucket, confidence=max(scores.values()), scores=scores, detail={}, ) return predict monkeypatch.setattr("app.style_eval.build_detector", fake_build) with TestClient(app) as client: resp = client.post( "/api/debug/style-eval", json={ "count_per_class": 5, "detectors": ["imgutils_mobilenet", "imgutils_caformer"], }, ) assert resp.status_code == 200, resp.text data = resp.json() assert data["best_detector"] in {"imgutils_mobilenet", "imgutils_caformer"} assert len(data["reports"]) == 2 assert data["reports"][0]["count_evaluated"] == 3 assert data["overall_conclusion"]["decision"] in {"GO", "NO_GO"}