mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-18 00:20:13 +01:00
59 lines
2.6 KiB
Python
59 lines
2.6 KiB
Python
|
|
from typing import Set
|
||
|
|
|
||
|
|
from fastapi.testclient import TestClient
|
||
|
|
|
||
|
|
from code.web.app import app # FastAPI instance
|
||
|
|
from code.web.services.theme_catalog_loader import load_index
|
||
|
|
|
||
|
|
|
||
|
|
def _first_theme_slug() -> str:
|
||
|
|
idx = load_index()
|
||
|
|
# Deterministic ordering for test stability
|
||
|
|
return sorted(idx.slug_to_entry.keys())[0]
|
||
|
|
|
||
|
|
|
||
|
|
def test_preview_export_json_and_csv_curated_only_round_trip():
|
||
|
|
slug = _first_theme_slug()
|
||
|
|
client = TestClient(app)
|
||
|
|
|
||
|
|
# JSON full sample
|
||
|
|
r = client.get(f"/themes/preview/{slug}/export.json", params={"curated_only": 0, "limit": 12})
|
||
|
|
assert r.status_code == 200, r.text
|
||
|
|
data = r.json()
|
||
|
|
assert data["ok"] is True
|
||
|
|
assert data["theme_id"] == slug
|
||
|
|
assert data["count"] == len(data["items"]) <= 12 # noqa: SIM300
|
||
|
|
required_keys_sampled = {"name", "roles", "score", "rarity", "mana_cost", "color_identity_list", "pip_colors"}
|
||
|
|
sampled_role_set = {"payoff", "enabler", "support", "wildcard"}
|
||
|
|
assert data["items"], "expected non-empty preview sample"
|
||
|
|
for item in data["items"]:
|
||
|
|
roles = set(item.get("roles") or [])
|
||
|
|
# Curated examples & synthetic placeholders don't currently carry full card DB fields
|
||
|
|
if roles.intersection(sampled_role_set):
|
||
|
|
assert required_keys_sampled.issubset(item.keys()), f"sampled card missing expected fields: {item}"
|
||
|
|
else:
|
||
|
|
assert {"name", "roles", "score"}.issubset(item.keys())
|
||
|
|
|
||
|
|
# JSON curated_only variant: ensure only curated/synthetic roles remain
|
||
|
|
r2 = client.get(f"/themes/preview/{slug}/export.json", params={"curated_only": 1, "limit": 12})
|
||
|
|
assert r2.status_code == 200, r2.text
|
||
|
|
curated = r2.json()
|
||
|
|
curated_roles_allowed: Set[str] = {"example", "curated_synergy", "synthetic"}
|
||
|
|
for item in curated["items"]:
|
||
|
|
roles = set(item.get("roles") or [])
|
||
|
|
assert roles, "item missing roles"
|
||
|
|
assert roles.issubset(curated_roles_allowed), f"unexpected sampled role present: {roles}"
|
||
|
|
|
||
|
|
# CSV export header stability + curated_only path
|
||
|
|
r3 = client.get(f"/themes/preview/{slug}/export.csv", params={"curated_only": 1, "limit": 12})
|
||
|
|
assert r3.status_code == 200, r3.text
|
||
|
|
text = r3.text.splitlines()
|
||
|
|
assert text, "empty CSV response"
|
||
|
|
header = text[0].strip()
|
||
|
|
assert header == "name,roles,score,rarity,mana_cost,color_identity_list,pip_colors,reasons,tags"
|
||
|
|
# Basic sanity: curated_only CSV should not contain a sampled role token
|
||
|
|
sampled_role_tokens = {"payoff", "enabler", "support", "wildcard"}
|
||
|
|
body = "\n".join(text[1:])
|
||
|
|
for tok in sampled_role_tokens:
|
||
|
|
assert f";{tok}" not in body, f"sampled role {tok} leaked into curated_only CSV"
|