mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-16 23:50:12 +01:00
document deck summary DFC badges, exporter annotations, and per-face metadata across README/DOCKER/release notes record completion of all MDFC roadmap follow-ups and add the authoring guide for multi-face CSV entries wire in optional DFC_PER_FACE_SNAPSHOT env support, exporter regression tests, and diagnostics updates noted in the changelog
77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Iterator
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from code.web.app import app
|
|
|
|
|
|
@pytest.fixture()
|
|
def client() -> Iterator[TestClient]:
|
|
with TestClient(app) as test_client:
|
|
yield test_client
|
|
|
|
|
|
def test_candidate_list_includes_exclusion_warning(monkeypatch: pytest.MonkeyPatch, client: TestClient) -> None:
|
|
def fake_candidates(_: str, limit: int = 8):
|
|
return [("Sample Front", 10, ["G"])]
|
|
|
|
def fake_lookup(name: str):
|
|
if name == "Sample Front":
|
|
return {
|
|
"primary_face": "Sample Front",
|
|
"eligible_faces": ["Sample Back"],
|
|
"reason": "secondary_face_only",
|
|
}
|
|
return None
|
|
|
|
monkeypatch.setattr("code.web.routes.build.orch.commander_candidates", fake_candidates)
|
|
monkeypatch.setattr("code.web.routes.build.lookup_commander_detail", fake_lookup)
|
|
|
|
response = client.get("/build/new/candidates", params={"commander": "Sample"})
|
|
assert response.status_code == 200
|
|
body = response.text
|
|
assert "Use the back face 'Sample Back' when building" in body
|
|
assert "data-name=\"Sample Back\"" in body
|
|
assert "data-display=\"Sample Front\"" in body
|
|
|
|
|
|
def test_front_face_submit_returns_modal_error(monkeypatch: pytest.MonkeyPatch, client: TestClient) -> None:
|
|
def fake_lookup(name: str):
|
|
if "Budoka" in name:
|
|
return {
|
|
"primary_face": "Budoka Gardener",
|
|
"eligible_faces": ["Dokai, Weaver of Life"],
|
|
"reason": "secondary_face_only",
|
|
}
|
|
return None
|
|
|
|
monkeypatch.setattr("code.web.routes.build.lookup_commander_detail", fake_lookup)
|
|
monkeypatch.setattr("code.web.routes.build.orch.bracket_options", lambda: [{"level": 3, "name": "Upgraded"}])
|
|
monkeypatch.setattr("code.web.routes.build.orch.ideal_labels", lambda: {})
|
|
monkeypatch.setattr("code.web.routes.build.orch.ideal_defaults", lambda: {})
|
|
|
|
def fail_select(name: str): # pragma: no cover - should not trigger
|
|
raise AssertionError(f"commander_select should not be called for {name}")
|
|
|
|
monkeypatch.setattr("code.web.routes.build.orch.commander_select", fail_select)
|
|
|
|
client.get("/build")
|
|
response = client.post(
|
|
"/build/new",
|
|
data={
|
|
"name": "",
|
|
"commander": "Budoka Gardener",
|
|
"bracket": "3",
|
|
"include_cards": "",
|
|
"exclude_cards": "",
|
|
"enforcement_mode": "warn",
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
body = response.text
|
|
assert "can't lead a deck" in body
|
|
assert "Use 'Dokai, Weaver of Life' as the commander instead" in body
|
|
assert "value=\"Dokai, Weaver of Life\"" in body
|