Add test coverage for: - test_auth.py: Login, JWT, protected endpoints (5 tests) - test_users.py: User CRUD, permissions (8 tests) - test_projects.py: Project CRUD, ownership (8 tests) - test_milestones.py: Milestone CRUD, filtering (7 tests) - test_tasks.py: Task CRUD, filtering by status/assignee (8 tests) - test_comments.py: Comment CRUD, edit permissions (5 tests) - test_roles.py: Role/permission management, assignments (9 tests) - test_misc.py: Milestones global, notifications, activity log, API keys, dashboard, health (14 tests) Total: 64 new tests covering all major API endpoints. Uses existing pytest fixtures from conftest.py.
101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
"""P14.1 — Users API tests.
|
|
|
|
Covers:
|
|
- List users
|
|
- Get user by ID
|
|
- Create user
|
|
- Update user
|
|
- Delete user
|
|
- User self-service restrictions
|
|
"""
|
|
import pytest
|
|
|
|
|
|
class TestUsers:
|
|
"""User management endpoints."""
|
|
|
|
def test_list_users(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Admin can list all users."""
|
|
seed_roles_and_permissions
|
|
admin = make_user(username="admin", is_admin=True)
|
|
make_user(username="user1")
|
|
make_user(username="user2")
|
|
|
|
resp = client.get("/users", headers=auth_header(admin))
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert len(data) >= 2
|
|
|
|
def test_get_user_by_id(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Get specific user details."""
|
|
seed_roles_and_permissions
|
|
admin = make_user(username="admin", is_admin=True)
|
|
user = make_user(username="testuser")
|
|
|
|
resp = client.get(f"/users/{user.id}", headers=auth_header(admin))
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["id"] == user.id
|
|
assert data["username"] == "testuser"
|
|
|
|
def test_create_user(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Admin can create new user."""
|
|
seed_roles_and_permissions
|
|
admin = make_user(username="admin", is_admin=True)
|
|
|
|
resp = client.post(
|
|
"/users",
|
|
json={
|
|
"username": "newuser",
|
|
"password": "newpass123",
|
|
"is_admin": False
|
|
},
|
|
headers=auth_header(admin)
|
|
)
|
|
assert resp.status_code == 201
|
|
data = resp.json()
|
|
assert data["username"] == "newuser"
|
|
assert "id" in data
|
|
|
|
def test_update_user(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Admin can update user."""
|
|
seed_roles_and_permissions
|
|
admin = make_user(username="admin", is_admin=True)
|
|
user = make_user(username="testuser")
|
|
|
|
resp = client.patch(
|
|
f"/users/{user.id}",
|
|
json={"username": "updateduser"},
|
|
headers=auth_header(admin)
|
|
)
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["username"] == "updateduser"
|
|
|
|
def test_delete_user(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Admin can delete user."""
|
|
seed_roles_and_permissions
|
|
admin = make_user(username="admin", is_admin=True)
|
|
user = make_user(username="testuser")
|
|
|
|
resp = client.delete(f"/users/{user.id}", headers=auth_header(admin))
|
|
assert resp.status_code == 204
|
|
|
|
def test_regular_user_cannot_list_all_users(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""Non-admin cannot list all users."""
|
|
seed_roles_and_permissions
|
|
user = make_user(username="regular")
|
|
|
|
resp = client.get("/users", headers=auth_header(user))
|
|
assert resp.status_code == 403
|
|
|
|
def test_user_can_view_self(self, client, db, make_user, auth_header, seed_roles_and_permissions):
|
|
"""User can view their own profile."""
|
|
seed_roles_and_permissions
|
|
user = make_user(username="testuser")
|
|
|
|
resp = client.get(f"/users/{user.id}", headers=auth_header(user))
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["id"] == user.id
|