Files
Aidem-Media-DLL-Analysis/tests/test_api.py
Patryk Gensch 8386196653 Add FastAPI catalog backend (games/snapshots/diff) + tests
Modular-monolith backend over SQLAlchemy (SQLite by default, Postgres-ready
via DATABASE_URL). The full snapshot.json is stored verbatim; diffing reads it
back through the ams.diff engine, so the DB never mirrors the snapshot schema.

- ams.api.db/models/schemas/service : Game 1-N Snapshot, sha256-deduped upsert
- routes: POST/GET /games, POST/GET /snapshots (import, deduped), GET /diff
          (?old&new[&owner]) running compute_diff on stored snapshots, /health
- ams.api.importer : bulk CLI loader (python -m ams.api.importer --game ...)
- run: uvicorn ams.api.app:create_app --factory

11 tests pass (6 diff + 5 API via TestClient over the golden pair). Smoke-tested
live on uvicorn: import -> /snapshots -> /diff returns the BlooMoo deltas.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 22:27:24 +02:00

71 lines
2.4 KiB
Python

"""API tests against a temp SQLite DB, exercising import -> list -> diff over the golden pair."""
from __future__ import annotations
import json
from pathlib import Path
import pytest
pytest.importorskip("fastapi")
from fastapi.testclient import TestClient # noqa: E402
from ams.api.app import create_app # noqa: E402
SNAP_DIR = Path(__file__).resolve().parents[1] / "snapshots"
PIKLIB = SNAP_DIR / "PIKLIB8.dll.snapshot.json"
BLOOMOO = SNAP_DIR / "bloomoodll.dll.snapshot.json"
pytestmark = pytest.mark.skipif(not PIKLIB.exists(), reason="golden snapshots not present")
@pytest.fixture()
def client(tmp_path) -> TestClient:
app = create_app(database_url="sqlite:///{0}/api.db".format(tmp_path))
return TestClient(app)
def _load(path: Path) -> dict:
with open(path, "r", encoding="utf-8") as fh:
return json.load(fh)
def test_health(client: TestClient):
assert client.get("/health").json()["status"] == "ok"
def test_import_list_and_dedup(client: TestClient):
r = client.post("/snapshots", params={"game": "Reksio i UFO"}, json=_load(PIKLIB))
assert r.status_code == 201
first_id = r.json()["id"]
assert r.json()["engine"] == "Piklib" and r.json()["n_types"] == 40
# re-importing the same binary (same sha256) updates in place, not a duplicate row
r2 = client.post("/snapshots", json=_load(PIKLIB))
assert r2.json()["id"] == first_id
assert len(client.get("/snapshots").json()) == 1
# the game was auto-created and linked
games = client.get("/games").json()
assert [g["name"] for g in games] == ["Reksio i UFO"]
def test_invalid_snapshot_rejected(client: TestClient):
assert client.post("/snapshots", json={"not": "a snapshot"}).status_code == 422
def test_diff_endpoint(client: TestClient):
a = client.post("/snapshots", params={"game": "Reksio i UFO"}, json=_load(PIKLIB)).json()["id"]
b = client.post("/snapshots", params={"game": "Reksio i Kapitan Nemo"}, json=_load(BLOOMOO)).json()["id"]
diff = client.get("/diff", params={"old": a, "new": b}).json()
added = {t["script_name"] for t in diff["types"]["added"]}
assert {"GRBUFFER", "INTERNET"} <= added
animo = client.get("/diff", params={"old": a, "new": b, "owner": "CMC_Animo"}).json()
assert "GETFPS" in {m["name"] for m in animo["methods"]["added"]}
def test_diff_missing_snapshot_404(client: TestClient):
assert client.get("/diff", params={"old": 999, "new": 998}).status_code == 404