"""Событие партии несёт список участников: по нему клиент решает, чьи витрины протухли.""" from __future__ import annotations from fastapi.testclient import TestClient from tests.conftest import add_group_member, csrf_headers, finish_match, login, start_match def _capture_events(monkeypatch) -> list[tuple[list[int], dict]]: from app.core import events published: list[tuple[list[int], dict]] = [] monkeypatch.setattr( events.hub, "publish", lambda ids, event: published.append((list(ids), event)) ) return published def _match_events(published: list[tuple[list[int], dict]]) -> list[dict]: return [e for _ids, e in published if e.get("type") == "match"] def test_match_event_carries_participants(client: TestClient, engine, monkeypatch): me = login(client, "Хост") exps = [e["id"] for e in client.get("/api/expansions").json()] gid = client.post( "/api/groups", json={"name": "Группа", "expansion_ids": exps}, headers=csrf_headers(client) ).json()["id"] p2 = add_group_member(engine, gid, "Игрок2") # Третий в группе, но НЕ в партии: его история от этой партии не меняется. p3 = add_group_member(engine, gid, "Зритель") fids = [f["id"] for f in client.get(f"/api/groups/{gid}/factions").json()] published = _capture_events(monkeypatch) started = start_match( client, gid, [{"user_id": me["id"], "faction_id": fids[0]}, {"user_id": p2, "faction_id": fids[1]}], ) assert started.status_code == 200, started.text mid = started.json()["id"] ev = _match_events(published)[-1] assert sorted(ev["participant_ids"]) == sorted([me["id"], p2]) assert p3 not in ev["participant_ids"] published.clear() fin = finish_match( client, mid, [{"user_id": me["id"], "place": 1}, {"user_id": p2, "place": 2}] ) assert fin.status_code == 200, fin.text assert sorted(_match_events(published)[-1]["participant_ids"]) == sorted([me["id"], p2]) def test_delete_event_carries_participants(client: TestClient, engine, monkeypatch): """Удаление — главный случай: строки участников уже уничтожены каскадом. Если собирать их после удаления, список всегда окажется пустым, и клиент не обновит историю тем, кто в этой партии играл.""" me = login(client, "Хост") exps = [e["id"] for e in client.get("/api/expansions").json()] gid = client.post( "/api/groups", json={"name": "Группа", "expansion_ids": exps}, headers=csrf_headers(client) ).json()["id"] p2 = add_group_member(engine, gid, "Игрок2") fids = [f["id"] for f in client.get(f"/api/groups/{gid}/factions").json()] mid = start_match( client, gid, [{"user_id": me["id"], "faction_id": fids[0]}, {"user_id": p2, "faction_id": fids[1]}], ).json()["id"] published = _capture_events(monkeypatch) version = client.get(f"/api/matches/{mid}").json()["version"] r = client.delete( f"/api/matches/{mid}", params={"expected_version": version}, headers=csrf_headers(client) ) assert r.status_code == 200, r.text assert sorted(_match_events(published)[-1]["participant_ids"]) == sorted([me["id"], p2])