Files
hockey_new/tests/test_hotfix_mapping_transport.py
2026-09-26 23:18:54 +03:00

73 lines
3.2 KiB
Python

"""Exercise the BUILD113 transport that replaced the failing BUILD97 mocks."""
import asyncio
from datetime import datetime
from hockey_data.agent_bridge import LiveAgent, VmixAgentHub
from hockey_data.models import VmixAssignment, VmixDevice
from tests.support import LocalTestDatabase
def transport(tmp_path, fail_at=None):
db = LocalTestDatabase(tmp_path / "mapping.sqlite")
db.create_all()
with db.session() as s:
device = VmixDevice(device_uuid="GFX-OWNER", device_secret_hash="x", wfl_user_id="owner",
is_active_for_account=True, current_match_external_id="g", current_assignment_key="assignment")
s.add(device)
s.flush()
s.add(VmixAssignment(device_id=device.id, assignment_key="assignment", wfl_user_id="owner",
game_external_id="g", active=True))
class Socket:
def __init__(self):
self.frames = []
async def send_json(self, message):
if fail_at is not None and len(self.frames) == fail_at:
raise ConnectionError("fake disconnected socket")
self.frames.append(message)
own, other = Socket(), Socket()
hub = VmixAgentHub(db)
hub._live["GFX-OWNER"] = LiveAgent(own, datetime.utcnow())
hub._live["GFX-VIEWER"] = LiveAgent(other, datetime.utcnow())
return hub, own, other
def entries(count):
return [{"data_key": str(i), "command": {"Function": "SetText", "Input": f"input-{i // 31}",
"SelectedName": f"Field{i}.Text", "Value": str(i)}} for i in range(count)]
def send(hub, rows):
return asyncio.run(hub._send_mapping_entries_resilient("GFX-OWNER", assignment_id="assignment",
match_id="g", entries=rows, use_batch=True))
def test_372_mapping_fields_are_ordered_and_isolated_without_ack(tmp_path):
hub, own, other = transport(tmp_path)
rows = entries(372)
result = send(hub, rows)
assert result["commands_sent"] == 372 and result["input_groups"] == 12
assert all(item["ok"] for item in result["results"])
assert result["ack_waited"] is False and result["transport"] == "sequential_no_ack"
assert own.frames[0]["type"] == "match.assign"
assert [f["command"] for f in own.frames[1:]] == [r["command"] for r in rows]
assert all(f["type"] == "vmix.command" and f["match_id"] == "g" and f["assignment_id"] == "assignment"
for f in own.frames[1:])
assert len({f["request_id"] for f in own.frames[1:]}) == 372
assert other.frames == []
def test_disconnect_stops_remaining_mapping_and_reports_failure(tmp_path):
hub, own, other = transport(tmp_path, fail_at=4) # assignment plus three commands
result = send(hub, entries(35))
assert result["commands_sent"] == 3
assert [row["ok"] for row in result["results"]] == [True] * 3 + [False] * 32
assert result["retries"] == 0 and len(own.frames) == 4 and other.frames == []
def test_unconfirmed_assignment_does_not_send_mapping(tmp_path):
hub, own, other = transport(tmp_path, fail_at=0)
result = send(hub, entries(8))
assert result["assignment_refreshed"] is False
assert result["commands_sent"] == 0 and not any(row["ok"] for row in result["results"])
assert own.frames == [] and other.frames == []