Ревью: закрыть дыры в собственном покрытии
Прогон /code-review по тестам показал, что проверка обхода каталога ачивок ничего не проверяла: httpx нормализует «..» в URL до отправки, запрос уходил на /api/admin/ и до обработчика не доходил — тест был бы зелёным и без защиты. Теперь percent-кодированная форма плюс проверка конверта ошибки, чтобы промах роутинга не выдавал себя за отказ. Добавлено недостающее: передача владения группой (обратная сторона защиты последнего владельца), сдвиг версии партии при загрузке вложения, совпадение кэш-бастера аватара между профилем и лидербордом. Проверка выживания группы после отказа в удалении теперь смотрит на саму группу и её партии, а не только на код ответа. #8 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186Fk74jkkszahEHSjBzTjD
This commit is contained in:
@@ -227,7 +227,9 @@ def test_admin_delete_group_with_matches_is_conflict(client: TestClient, make_ad
|
||||
_admin_login(client, make_admin)
|
||||
r = client.delete(f"/api/admin/groups/{gid}", headers=csrf_headers(client))
|
||||
assert r.status_code == 409, r.text
|
||||
assert client.get("/api/admin/groups").status_code == 200
|
||||
# Важен не только код ответа: группа и её партии должны пережить отказ.
|
||||
assert any(g["id"] == gid for g in client.get("/api/admin/groups").json())
|
||||
assert any(m["group_id"] == gid for m in client.get("/api/admin/matches").json())
|
||||
|
||||
|
||||
def test_last_owner_cannot_demote_self(client: TestClient, engine):
|
||||
@@ -249,3 +251,27 @@ def test_last_owner_cannot_demote_self(client: TestClient, engine):
|
||||
assert r.status_code == 403, r.text
|
||||
members = client.get(f"/api/groups/{gid}/members").json()
|
||||
assert any(m["user_id"] == me["id"] and m["role"] == "owner" for m in members)
|
||||
|
||||
|
||||
def test_ownership_transfer_still_works(client: TestClient, engine):
|
||||
"""Обратная сторона защиты последнего владельца: передать роль по-прежнему можно."""
|
||||
me = login(client, "Owner")
|
||||
gid = client.post(
|
||||
"/api/groups", json={"name": "Группа", "expansion_ids": []}, headers=csrf_headers(client)
|
||||
).json()["id"]
|
||||
p2 = add_group_member(engine, gid, "Игрок2")
|
||||
|
||||
promote = client.patch(
|
||||
f"/api/groups/{gid}/members/{p2}", json={"role": "owner"}, headers=csrf_headers(client)
|
||||
)
|
||||
assert promote.status_code == 200, promote.text
|
||||
|
||||
# Владельцев теперь двое — прежний может сложить полномочия.
|
||||
demote = client.patch(
|
||||
f"/api/groups/{gid}/members/{me['id']}",
|
||||
json={"role": "member"},
|
||||
headers=csrf_headers(client),
|
||||
)
|
||||
assert demote.status_code == 200, demote.text
|
||||
members = client.get(f"/api/groups/{gid}/members").json()
|
||||
assert [m["user_id"] for m in members if m["role"] == "owner"] == [p2]
|
||||
|
||||
Reference in New Issue
Block a user