Update user tests for the removed POST /api/users endpoint
User creation moved to Keycloak-only, so the creation tests now just assert the endpoint returns 405, and the history test seeds its audit entry directly instead of creating a user through the API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,8 @@ from unittest.mock import patch, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from app.audit import AuditLog
|
||||
from app.extensions import db
|
||||
from app.kc_queue_models import KcSyncQueue
|
||||
|
||||
|
||||
@@ -117,115 +119,16 @@ class TestListUsers:
|
||||
|
||||
|
||||
class TestCreateUser:
|
||||
"""POST /api/users -- admin-only user creation."""
|
||||
|
||||
def test_create_user_success(self, admin_client):
|
||||
"""Creates user with valid data."""
|
||||
with _mock_keycloak():
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "New",
|
||||
"last_name": "User",
|
||||
"email": "new@example.com",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
data = resp.get_json()
|
||||
assert data["name"] == "New User"
|
||||
assert data["email"] == "new@example.com"
|
||||
assert data["enabled"] is True
|
||||
|
||||
def test_create_user_with_keycloak_id(self, admin_client):
|
||||
"""Creating with keycloak_id skips Keycloak sync."""
|
||||
with _mock_keycloak() as mock_kc:
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "KC",
|
||||
"last_name": "User",
|
||||
"email": "kc@example.com",
|
||||
"keycloak_id": "existing-kc-id",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
# Should NOT have tried to create in Keycloak since keycloak_id was provided
|
||||
mock_kc.create_user.assert_not_called()
|
||||
|
||||
def test_create_user_missing_name(self, admin_client):
|
||||
"""Missing first_name returns 400."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"email": "no-name@example.com",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert "required" in resp.get_json()["error"].lower()
|
||||
|
||||
def test_create_user_missing_email(self, admin_client):
|
||||
"""Missing email returns 400."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "No Email",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert "required" in resp.get_json()["error"].lower()
|
||||
|
||||
def test_create_user_empty_name(self, admin_client):
|
||||
"""Empty first_name string returns 400."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": " ",
|
||||
"email": "empty@example.com",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_create_user_empty_email(self, admin_client):
|
||||
"""Empty email string returns 400."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "Empty Email",
|
||||
"email": " ",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_create_user_duplicate_email(self, admin_client, make_user):
|
||||
"""Duplicate email returns 400."""
|
||||
make_user(name="Existing", email="dupe@example.com")
|
||||
"""POST /api/users -- removed; users are created in Keycloak only."""
|
||||
|
||||
def test_create_user_not_allowed(self, admin_client):
|
||||
"""User creation via the API returns 405 (users come from Keycloak/OIDC)."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "New",
|
||||
"email": "dupe@example.com",
|
||||
"last_name": "User",
|
||||
"email": "new@example.com",
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert "already exists" in resp.get_json()["error"]
|
||||
|
||||
def test_create_user_nonadmin_forbidden(self, authed_client):
|
||||
"""Non-admin user gets 403."""
|
||||
resp = authed_client.post("/api/users", json={
|
||||
"first_name": "Not",
|
||||
"last_name": "Allowed",
|
||||
"email": "nope@example.com",
|
||||
})
|
||||
assert resp.status_code == 403
|
||||
|
||||
def test_create_user_missing_body(self, admin_client):
|
||||
"""No JSON body returns 400."""
|
||||
resp = admin_client.post("/api/users", content_type="application/json")
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_create_user_enqueues_keycloak_sync(self, admin_client):
|
||||
"""User creation enqueues a KC create_user job (KC writes are async via
|
||||
the sync queue; failures surface in kc_sync_errors, not the response)."""
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "KC",
|
||||
"last_name": "Sync",
|
||||
"email": "kcsync@example.com",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
assert _queue_count("create_user") == 1
|
||||
|
||||
def test_create_user_returns_projects_list(self, admin_client):
|
||||
"""Newly created user response includes empty projects list."""
|
||||
with _mock_keycloak():
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "Fresh",
|
||||
"last_name": "User",
|
||||
"email": "fresh@example.com",
|
||||
})
|
||||
assert resp.status_code == 201
|
||||
data = resp.get_json()
|
||||
assert "projects" in data
|
||||
assert data["projects"] == []
|
||||
assert resp.status_code == 405
|
||||
|
||||
|
||||
# ===================================================================
|
||||
@@ -566,16 +469,19 @@ class TestDeleteUser:
|
||||
class TestUserHistory:
|
||||
"""GET /api/users/<id>/history -- audit log for user."""
|
||||
|
||||
def test_user_history_after_create(self, admin_client):
|
||||
"""History includes the 'created' entry."""
|
||||
with _mock_keycloak():
|
||||
resp = admin_client.post("/api/users", json={
|
||||
"first_name": "Audited",
|
||||
"email": "audited@example.com",
|
||||
})
|
||||
user_id = resp.get_json()["id"]
|
||||
def test_user_history_returns_audit_entries(self, admin_client, make_user, app):
|
||||
"""History returns audit entries recorded for the user."""
|
||||
user = make_user(name="Audited", email="audited@example.com")
|
||||
with app.app_context():
|
||||
db.session.add(AuditLog(
|
||||
entity_type="user",
|
||||
entity_id=user.id,
|
||||
action="created",
|
||||
user="admin",
|
||||
))
|
||||
db.session.commit()
|
||||
|
||||
resp = admin_client.get(f"/api/users/{user_id}/history")
|
||||
resp = admin_client.get(f"/api/users/{user.id}/history")
|
||||
assert resp.status_code == 200
|
||||
entries = resp.get_json()["entries"]
|
||||
actions = [e["action"] for e in entries]
|
||||
|
||||
Reference in New Issue
Block a user