108 lines
3.3 KiB
Python
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"
|