import os
import httpx
import pytest
from conftest import BASE_URL
def _headers():
uid = os.getenv("SYNC_TEST_USER_ID", "")
return {"X-User-ID": uid}
def test_user_admin_list_users():
with httpx.Client(timeout=10.0) as client:
r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
users = r.json()
assert len(users) > 0
# Verify admin is in the list
admin_email = os.getenv("SUPER_ADMINS", "axieyangb@gmail.com").split(',')[0].strip()
assert any(u["email"] == admin_email for u in users)
def test_group_lifecycle():
group_data = {
"name": "Test Admin Group",
"description": "A group for testing admin APIs",
"policy": {"llm": ["gemini"]}
}
with httpx.Client(timeout=10.0) as client:
# 1. Create Group
r = client.post(f"{BASE_URL}/users/admin/groups", json=group_data, headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
json_data = r.json()
assert "id" in json_data
group_id = json_data["id"]
# 2. List Groups
r = client.get(f"{BASE_URL}/users/admin/groups", headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
groups = r.json()
assert any(g["id"] == group_id for g in groups)
# 3. Update Group
update_data = {
"description": "Updated description"
}
r = client.put(f"{BASE_URL}/users/admin/groups/{group_id}", json=update_data, headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
assert r.json()["description"] == "Updated description"
# 4. Delete Group
r = client.delete(f"{BASE_URL}/users/admin/groups/{group_id}", headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
# Verify deleted
r = client.get(f"{BASE_URL}/users/admin/groups", headers=_headers())
groups = r.json()
assert not any(g["id"] == group_id for g in groups)
def test_admin_update_user_group():
with httpx.Client(timeout=10.0) as client:
# 1. List users to get a user ID
r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
assert r.status_code == 200
users = r.json()
assert len(users) > 0
user_id = users[0]["id"] # Use the first user (likely admin)
# 2. Create a test group
group_data = {
"name": "Test Assign Group",
"description": "Testing group assignment",
"policy": {}
}
r = client.post(f"{BASE_URL}/users/admin/groups", json=group_data, headers=_headers())
assert r.status_code == 200
group_id = r.json()["id"]
# 3. Assign user to group
r = client.put(f"{BASE_URL}/users/admin/users/{user_id}/group", json={"group_id": group_id}, headers=_headers())
assert r.status_code == 200, f"Expected 200 OK, got {r.status_code}: {r.text}"
# Verify assignment
r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
users = r.json()
updated_user = next(u for u in users if u["id"] == user_id)
assert updated_user["group_name"] == group_data["name"]
# Cleanup group
client.delete(f"{BASE_URL}/users/admin/groups/{group_id}", headers=_headers())
def test_admin_update_role_last_admin_protection():
with httpx.Client(timeout=10.0) as client:
# Get current admin user
r = client.get(f"{BASE_URL}/users/admin/users", headers=_headers())
assert r.status_code == 200
users = r.json()
# Find the admin user
admin_user = next((u for u in users if u["role"] == "admin"), None)
assert admin_user is not None
# Try to demote this admin to user
r = client.put(f"{BASE_URL}/users/admin/users/{admin_user['id']}/role", json={"role": "user"}, headers=_headers())
# Expect 400 Bad Request due to last admin protection
assert r.status_code == 400, f"Expected 400 Bad Request, got {r.status_code}: {r.text}"
assert "Maybe this is the last admin?" in r.text or "Failed to update role" in r.text