Files
hockey_new/tests/test_build202_goal_hide_config.py

73 lines
3.4 KiB
Python

"""Persist real penalty OUT animation settings through draft and publish APIs."""
from copy import deepcopy
import json
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from ui_builder.manager import DEFAULT_CONFIG, UIBuilderManager
from ui_builder.router import create_ui_builder_router
def config_with_targets(value=None, *, omitted=False):
config = deepcopy(DEFAULT_CONFIG)
config["data_source"] = "hockey"
targets = {}
for side, overlay in (("home", "2"), ("away", "8")):
target = {"id": side, "input": f"Penalty {side}", "selected_name": "Clock.Text",
"overlay": overlay, "scoreboard_delay_seconds": 5}
if not omitted:
target["goal_hide_delay_seconds"] = value
targets[side + "_penalty_targets"] = [target]
config["shortcut_sequences"] = [{"id": "timers", "steps": [
{"id": "native", "type": "hockey_vmix_timers_start", **targets}]}]
return config
def assert_targets(config, expected):
step = config["shortcut_sequences"][0]["steps"][0]
for side, overlay in (("home", "2"), ("away", "8")):
target = step[side + "_penalty_targets"][0]
assert target["goal_hide_delay_seconds"] == expected
assert isinstance(target["goal_hide_delay_seconds"], float)
assert target["input"] == f"Penalty {side}"
assert target["selected_name"] == "Clock.Text"
assert target["overlay"] == overlay
assert target["scoreboard_delay_seconds"] == 5.0
@pytest.mark.parametrize("value,omitted,expected", [
pytest.param(None, True, 1.0, id="old-config-default"),
pytest.param(2.5, False, 2.5, id="custom-animation"),
pytest.param(0, False, 0.0, id="explicit-zero"),
])
def test_goal_hide_delay_save_reload_publish_restart(tmp_path, value, omitted, expected):
draft = UIBuilderManager(tmp_path, filename="draft.json")
published = UIBuilderManager(tmp_path, filename="published.json")
app = FastAPI()
app.include_router(create_ui_builder_router(draft, {}, publish_manager=published))
with TestClient(app) as client:
response = client.post("/api/ui-builder/config", json=config_with_targets(value, omitted=omitted))
assert response.status_code == 200, response.text
assert_targets(response.json()["config"], expected)
assert_targets(client.get("/api/ui-builder/config").json(), expected)
response = client.post("/api/ui-builder/publish")
assert response.status_code == 200, response.text
assert_targets(response.json()["config"], expected)
assert_targets(UIBuilderManager(tmp_path, filename="draft.json").load(), expected)
assert_targets(UIBuilderManager(tmp_path, filename="published.json").load(), expected)
assert_targets(json.loads(published.settings_file.read_text()), expected)
assert draft.load() == published.load()
def test_goal_hide_delay_invalid_defaults_and_bounds_are_finite(tmp_path):
manager = UIBuilderManager(tmp_path)
for value, expected in ((None, 1.0), ("", 1.0), (True, 1.0), (False, 1.0),
("invalid", 1.0), (float("nan"), 1.0), (float("inf"), 1.0),
(float("-inf"), 1.0), (-2, 0.0), (80, 60.0), ("2.55", 2.55)):
assert_targets(manager.save(config_with_targets(value)), expected)
assert_targets(UIBuilderManager(tmp_path).load(), expected)
text = manager.settings_file.read_text()
assert "NaN" not in text and "Infinity" not in text