Files
opora/backend/tests/test_auth.py
T

109 lines
3.4 KiB
Python

"""Тесты аутентификации."""
from datetime import datetime, timedelta, timezone
from uuid import uuid4
from app.models.enums import MessengerType, RoleCode
from app.models.user import LoginToken, Role, User, UserRole
def _seed_admin(db) -> User:
for code, name in [(RoleCode.ADMIN, "Админ"), (RoleCode.COORDINATOR, "Координатор")]:
if not db.query(Role).filter(Role.code == code).first():
db.add(Role(code=code, name=name))
db.commit()
admin = (
db.query(User)
.filter(User.messenger_type == MessengerType.TELEGRAM, User.messenger_id == "1")
.first()
)
if not admin:
admin = User(messenger_type=MessengerType.TELEGRAM, messenger_id="1", full_name="Админ")
db.add(admin)
db.flush()
role = db.query(Role).filter(Role.code == RoleCode.ADMIN).first()
if not db.query(UserRole).filter(
UserRole.user_id == admin.id, UserRole.role_id == role.id
).first():
db.add(UserRole(user_id=admin.id, role_id=role.id))
db.commit()
return admin
def _make_login_token(db, value: str) -> None:
db.add(
LoginToken(
id=str(uuid4()),
token=value,
expires_at=datetime.now(timezone.utc) + timedelta(minutes=30),
)
)
db.commit()
def test_login_flow(client, db):
_seed_admin(db)
_make_login_token(db, "tok-1")
# вход
r = client.post(
"/api/v1/auth/login",
json={"token": "tok-1", "messenger_type": "telegram", "messenger_id": "1"},
)
assert r.status_code == 200, r.text
data = r.json()
assert data["user"]["roles"][0]["code"] == "admin"
access, refresh = data["access_token"], data["refresh_token"]
# повторное использование ссылки
r2 = client.post(
"/api/v1/auth/login",
json={"token": "tok-1", "messenger_type": "telegram", "messenger_id": "1"},
)
assert r2.status_code == 409
# профиль
r3 = client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {access}"})
assert r3.status_code == 200
# выдача новой ссылки (как админ)
r4 = client.post(
"/api/v1/auth/login-token",
json={"ttl_minutes": 15},
headers={"Authorization": f"Bearer {access}"},
)
assert r4.status_code == 201, r4.text
assert "token=" in r4.json()["url"]
# refresh
r5 = client.post("/api/v1/auth/refresh", json={"refresh_token": refresh})
assert r5.status_code == 200, r5.text
new_access = r5.json()["access_token"]
# logout
r6 = client.post("/api/v1/auth/logout", headers={"Authorization": f"Bearer {new_access}"})
assert r6.status_code == 204
# после logout
r7 = client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {new_access}"})
assert r7.status_code == 401
def test_login_token_requires_role(client, db):
_seed_admin(db)
_make_login_token(db, "tok-2")
r = client.post(
"/api/v1/auth/login",
json={"token": "tok-2", "messenger_type": "telegram", "messenger_id": "999"},
)
assert r.status_code == 200
access = r.json()["access_token"]
# обычный пользователь без роли не может выдавать ссылки
r2 = client.post(
"/api/v1/auth/login-token",
json={"ttl_minutes": 15},
headers={"Authorization": f"Bearer {access}"},
)
assert r2.status_code == 403