73 lines
3.4 KiB
Python
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
|