Files
ctms/backend/tests/test_protected_admin_api.py
T

108 lines
3.3 KiB
Python

import uuid
import pytest
from fastapi import HTTPException
from app.api.v1 import users as users_api
from app.models.user import User, UserRole, UserStatus
from app.schemas.user import UserRead, UserUpdate
def _make_user(
*,
email: str,
role: UserRole = UserRole.ADMIN,
status: UserStatus = UserStatus.ACTIVE,
) -> User:
return User(
id=uuid.uuid4(),
email=email,
password_hash="hashed",
full_name="User",
department="SYSTEM",
role=role,
status=status,
)
@pytest.mark.asyncio
async def test_delete_user_blocks_protected_admin(monkeypatch):
current_user = _make_user(email="other-admin@huapont.cn")
protected_admin = _make_user(email="admin@huapont.cn")
async def fake_get_by_id(_db, _user_id):
return protected_admin
async def fake_count_active_admins(_db):
return 2
async def fake_user_has_memberships(_db, _user_id):
return False
async def fake_delete_user(_db, _user):
raise AssertionError("protected admin should not be deleted")
monkeypatch.setattr(users_api.user_crud, "get_by_id", fake_get_by_id)
monkeypatch.setattr(users_api.user_crud, "count_active_admins", fake_count_active_admins)
monkeypatch.setattr(users_api.member_crud, "user_has_memberships", fake_user_has_memberships)
monkeypatch.setattr(users_api.user_crud, "delete_user", fake_delete_user)
with pytest.raises(HTTPException) as exc_info:
await users_api.delete_user(protected_admin.id, db=object(), current_user=current_user)
assert exc_info.value.status_code == 400
@pytest.mark.asyncio
async def test_update_user_blocks_protected_admin_email_change(monkeypatch):
protected_admin = _make_user(email="admin@huapont.cn")
async def fake_get_by_id(_db, _user_id):
return protected_admin
async def fake_count_active_admins(_db):
return 2
async def fake_update_user(_db, _user, _payload):
raise AssertionError("protected admin email should not be changed")
monkeypatch.setattr(users_api.user_crud, "get_by_id", fake_get_by_id)
monkeypatch.setattr(users_api.user_crud, "count_active_admins", fake_count_active_admins)
monkeypatch.setattr(users_api.user_crud, "update_user", fake_update_user)
with pytest.raises(HTTPException) as exc_info:
await users_api.update_user(
protected_admin.id,
UserUpdate(email="renamed@huapont.cn"),
db=object(),
current_user=protected_admin,
)
assert exc_info.value.status_code == 400
@pytest.mark.asyncio
async def test_update_user_allows_protected_admin_password_change(monkeypatch):
protected_admin = _make_user(email="admin@huapont.cn")
captured_payload = {}
async def fake_get_by_id(_db, _user_id):
return protected_admin
async def fake_update_user(_db, _user, payload):
captured_payload["password"] = payload.password
return _user
monkeypatch.setattr(users_api.user_crud, "get_by_id", fake_get_by_id)
monkeypatch.setattr(users_api.user_crud, "update_user", fake_update_user)
result = await users_api.update_user(
protected_admin.id,
UserUpdate(password="Password123"),
db=object(),
current_user=protected_admin,
)
assert isinstance(result, UserRead | User)
assert captured_payload["password"] == "Password123"