"""User CRUD tests — Go/Gin backend (admin only).""" import pytest from httpx import AsyncClient from tests.conftest import auth_header class TestListUsers: async def test_admin_list_users(self, client: AsyncClient, admin_token: str): resp = await client.get("/api/v1/users", headers=auth_header(admin_token)) assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) assert len(data) > 0 assert "id" in data[0] assert "username" in data[0] assert "role" in data[0] async def test_developer_forbidden(self, client: AsyncClient, developer_token: str): resp = await client.get("/api/v1/users", headers=auth_header(developer_token)) assert resp.status_code == 403 async def test_no_auth(self, client: AsyncClient): resp = await client.get("/api/v1/users") assert resp.status_code == 401 class TestCreateUser: async def test_create_user_success(self, client: AsyncClient, admin_token: str): import uuid uname = f"test_{uuid.uuid4().hex[:8]}" resp = await client.post("/api/v1/users", headers=auth_header(admin_token), json={ "username": uname, "password": "test123456", "role": "developer", "display_name": "Test User", }) assert resp.status_code == 201 data = resp.json() assert data["username"] == uname assert data["role"] == "developer" async def test_create_duplicate_username(self, client: AsyncClient, admin_token: str): resp = await client.post("/api/v1/users", headers=auth_header(admin_token), json={ "username": "admin", "password": "test123456", "role": "developer", "display_name": "Duplicate", }) # Should fail with 400 or 409 assert resp.status_code in (400, 409) async def test_developer_cannot_create(self, client: AsyncClient, developer_token: str): resp = await client.post("/api/v1/users", headers=auth_header(developer_token), json={ "username": "nope", "password": "test123456", "role": "developer", }) assert resp.status_code == 403 class TestUpdateUser: async def test_update_display_name(self, client: AsyncClient, admin_token: str): # Get admin user id me = await client.get("/api/v1/auth/me", headers=auth_header(admin_token)) uid = me.json()["id"] resp = await client.put( f"/api/v1/users/{uid}", headers=auth_header(admin_token), json={"display_name": "Updated Name"}, ) assert resp.status_code == 200 class TestDeleteUser: async def test_delete_nonexistent(self, client: AsyncClient, admin_token: str): resp = await client.delete("/api/v1/users/99999", headers=auth_header(admin_token)) # May return 404 or 200 with message assert resp.status_code in (200, 404)