"""Список игроков группы — только текущий состав (#76). Удалённый из группы игрок пропадает из рейтинга группы, но его партии остаются в истории: они уже повлияли на (общий) рейтинг оставшихся.""" from __future__ import annotations from fastapi.testclient import TestClient from tests.conftest import add_group_member, create_finished_match, csrf_headers, login def _ids(stats: dict) -> dict[str, set[int]]: return { block: {e["user_id"] for e in stats[block]} for block in ("leaderboard", "provisional", "inactive") } def _group(client: TestClient) -> tuple[int, list[int]]: gid = client.post( "/api/groups", json={"name": "Группа", "expansion_ids": []}, headers=csrf_headers(client) ).json()["id"] fids = [f["id"] for f in client.get(f"/api/groups/{gid}/factions").json()] return gid, fids def _remove(client: TestClient, gid: int, uid: int) -> None: r = client.delete(f"/api/groups/{gid}/members/{uid}", headers=csrf_headers(client)) assert r.status_code == 200, r.text def test_removed_member_leaves_group_rating_but_not_overall(client: TestClient, engine): me = login(client, "Хозяин") gid, fids = _group(client) b = add_group_member(engine, gid, "Ушедший") create_finished_match( client, gid, [ {"user_id": me["id"], "faction_id": fids[0], "place": 1}, {"user_id": b, "faction_id": fids[1], "place": 2}, ], ) before = client.get(f"/api/groups/{gid}/stats").json() my_score = next(e["score"] for e in before["provisional"] if e["user_id"] == me["id"]) _remove(client, gid, b) stats = client.get(f"/api/groups/{gid}/stats").json() ids = _ids(stats) assert all(b not in block for block in ids.values()) assert me["id"] in ids["provisional"] # Партия с ушедшим учтена: рейтинг оставшегося не изменился, счётчик партий тоже. assert next(e["score"] for e in stats["provisional"] if e["user_id"] == me["id"]) == my_score assert stats["total_matches"] == 1 board = client.get("/api/stats/leaderboard").json() assert b in {e["user_id"] for e in board["entries"] + board["provisional"]} # Вернули в группу — снова в списке со своей историей. add_group_member(engine, gid, "Ушедший") back = client.get(f"/api/groups/{gid}/stats").json() entry = next(e for e in back["provisional"] if e["user_id"] == b) assert (entry["games"], entry["score"]) == (1, 1468) def test_group_ranks_renumbered_after_removal(client: TestClient, engine): me = login(client, "Первый") gid, fids = _group(client) b = add_group_member(engine, gid, "Второй") c = add_group_member(engine, gid, "Третий") for _ in range(10): create_finished_match( client, gid, [ {"user_id": me["id"], "faction_id": fids[0], "place": 1}, {"user_id": b, "faction_id": fids[1], "place": 2}, {"user_id": c, "faction_id": fids[2], "place": 3}, ], ) assert [e["rank"] for e in client.get(f"/api/groups/{gid}/stats").json()["leaderboard"]] == [1, 2, 3] _remove(client, gid, b) board = client.get(f"/api/groups/{gid}/stats").json()["leaderboard"] assert [(e["user_id"], e["rank"]) for e in board] == [(me["id"], 1), (c, 2)]