import pytest from backend.app.models import ImagePrediction, ImageRecord, TagAllowlist, TagKind from backend.app.services.tag_service import TagService pytestmark = pytest.mark.integration @pytest.mark.asyncio async def test_list_and_patch_and_delete(client, db): tag = await TagService(db).find_or_create("AL", TagKind.character) db.add(TagAllowlist(tag_id=tag.id, min_confidence=0.95)) await db.commit() resp = await client.get("/api/allowlist") assert resp.status_code == 200 assert any(r["tag_id"] == tag.id for r in await resp.get_json()) resp = await client.patch( f"/api/tags/{tag.id}/allowlist", json={"min_confidence": 0.80} ) assert resp.status_code == 204 resp = await client.get(f"/api/tags/{tag.id}/allowlist") assert (await resp.get_json())["min_confidence"] == pytest.approx(0.80) resp = await client.delete(f"/api/tags/{tag.id}/allowlist") assert resp.status_code == 204 resp = await client.get(f"/api/tags/{tag.id}/allowlist") assert resp.status_code == 404 @pytest.mark.asyncio async def test_patch_rejects_out_of_range(client, db): tag = await TagService(db).find_or_create("AL2", TagKind.character) db.add(TagAllowlist(tag_id=tag.id)) await db.commit() resp = await client.patch( f"/api/tags/{tag.id}/allowlist", json={"min_confidence": 1.5} ) assert resp.status_code == 400 @pytest.mark.asyncio async def test_coverage_endpoint(client, db): tag = await TagService(db).find_or_create("Cover", TagKind.general) db.add(TagAllowlist(tag_id=tag.id, min_confidence=0.90)) for i, score in enumerate((0.95, 0.60)): img = ImageRecord( path=f"/images/cov{i}.jpg", sha256=f"cv{i:062d}", size_bytes=1, mime="image/jpeg", width=1, height=1, origin="imported_filesystem", integrity_status="unknown", ) db.add(img) await db.flush() db.add(ImagePrediction( image_record_id=img.id, raw_name="Cover", category="general", score=score, )) await db.commit() # Explicit threshold. resp = await client.get( f"/api/tags/{tag.id}/allowlist/coverage?threshold=0.90" ) assert resp.status_code == 200 assert (await resp.get_json())["count"] == 1 # Lower what-if threshold widens coverage. resp = await client.get( f"/api/tags/{tag.id}/allowlist/coverage?threshold=0.50" ) assert (await resp.get_json())["count"] == 2 # No threshold → uses the stored min_confidence (0.90). resp = await client.get(f"/api/tags/{tag.id}/allowlist/coverage") body = await resp.get_json() assert body["count"] == 1 assert body["threshold"] == pytest.approx(0.90) @pytest.mark.asyncio async def test_coverage_rejects_bad_threshold(client, db): tag = await TagService(db).find_or_create("Cover2", TagKind.general) db.add(TagAllowlist(tag_id=tag.id)) await db.commit() resp = await client.get( f"/api/tags/{tag.id}/allowlist/coverage?threshold=2.0" ) assert resp.status_code == 400