98 lines
3.9 KiB
Python
98 lines
3.9 KiB
Python
"""Приглашения в группу: создание, просмотр, принятие/отклонение, права участника."""
|
|
from __future__ import annotations
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from tests.conftest import add_group_member, csrf_headers, login
|
|
|
|
|
|
def _group(client: TestClient, name: str = "Группа") -> int:
|
|
return client.post(
|
|
"/api/groups", json={"name": name, "expansion_ids": []}, headers=csrf_headers(client)
|
|
).json()["id"]
|
|
|
|
|
|
def _dev_user(client: TestClient, nick: str) -> None:
|
|
client.post("/api/auth/dev/users", json={"nickname": nick}, headers=csrf_headers(client))
|
|
|
|
|
|
def test_invite_accept_flow(client: TestClient):
|
|
login(client, "Овнер")
|
|
gid = _group(client)
|
|
_dev_user(client, "Гость")
|
|
|
|
r = client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "Гость"}, headers=csrf_headers(client)
|
|
)
|
|
assert r.status_code == 200, r.text
|
|
assert r.json()["invited_by_nickname"] == "Овнер"
|
|
# Повторное приглашение → 409.
|
|
dup = client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "Гость"}, headers=csrf_headers(client)
|
|
)
|
|
assert dup.status_code == 409, dup.text
|
|
|
|
# Приглашённый видит приглашение и принимает.
|
|
login(client, "Гость")
|
|
invs = client.get("/api/invitations").json()
|
|
assert len(invs) == 1
|
|
assert invs[0]["group_id"] == gid and invs[0]["group_name"] == "Группа"
|
|
inv_id = invs[0]["id"]
|
|
acc = client.post(f"/api/invitations/{inv_id}/accept", headers=csrf_headers(client))
|
|
assert acc.status_code == 200, acc.text
|
|
# Стал участником; первая группа стала активной; приглашение исчезло.
|
|
me = client.get("/api/users/me").json()
|
|
assert me["active_group_id"] == gid
|
|
assert client.get("/api/invitations").json() == []
|
|
|
|
# Теперь он участник → приглашать его повторно нельзя.
|
|
login(client, "Овнер")
|
|
again = client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "Гость"}, headers=csrf_headers(client)
|
|
)
|
|
assert again.status_code == 409, again.text
|
|
members = client.get(f"/api/groups/{gid}/members").json()
|
|
assert any(m["nickname"] == "Гость" for m in members)
|
|
|
|
|
|
def test_invite_decline(client: TestClient):
|
|
login(client, "Овнер2")
|
|
gid = _group(client)
|
|
_dev_user(client, "Гость2")
|
|
client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "Гость2"}, headers=csrf_headers(client)
|
|
)
|
|
|
|
login(client, "Гость2")
|
|
inv_id = client.get("/api/invitations").json()[0]["id"]
|
|
dec = client.post(f"/api/invitations/{inv_id}/decline", headers=csrf_headers(client))
|
|
assert dec.status_code == 200, dec.text
|
|
assert client.get("/api/invitations").json() == []
|
|
|
|
login(client, "Овнер2")
|
|
members = client.get(f"/api/groups/{gid}/members").json()
|
|
assert all(m["nickname"] != "Гость2" for m in members)
|
|
|
|
|
|
def test_any_member_can_invite(client: TestClient, engine):
|
|
login(client, "Овнер3")
|
|
gid = _group(client)
|
|
add_group_member(engine, gid, "Участник") # обычный member (не владелец)
|
|
_dev_user(client, "Новичок")
|
|
|
|
# Обычный участник входит и приглашает — должно быть можно (assert_member, не owner).
|
|
login(client, "Участник")
|
|
r = client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "Новичок"}, headers=csrf_headers(client)
|
|
)
|
|
assert r.status_code == 200, r.text
|
|
|
|
|
|
def test_invite_unknown_nick_404(client: TestClient):
|
|
login(client, "Овнер4")
|
|
gid = _group(client)
|
|
r = client.post(
|
|
f"/api/groups/{gid}/invitations", json={"nickname": "НетТакого"}, headers=csrf_headers(client)
|
|
)
|
|
assert r.status_code == 404, r.text
|