"""API-level validation tests for user creation (SEC-004, SEC-007). Users are created with a name + email — no password (see password_setup_service for the emailed set-password link flow) and no admin-supplied username (username is auto-derived from email). """ def test_create_user_missing_full_name_rejected(client, admin_user, admin_token): response = client.post( "/api/v1/users", json={ "full_name": "", "email": "new@test.com", "role": "viewer", }, headers={"Authorization": f"Bearer {admin_token}"}, ) assert response.status_code == 422 def test_create_user_invalid_email_rejected(client, admin_user, admin_token): response = client.post( "/api/v1/users", json={ "full_name": "New User", "email": "not-an-email", "role": "viewer", }, headers={"Authorization": f"Bearer {admin_token}"}, ) assert response.status_code == 422 def test_create_user_valid_request_accepted(client, admin_user, admin_token): response = client.post( "/api/v1/users", json={ "full_name": "Valid User", "email": "valid@test.com", "role": "viewer", }, headers={"Authorization": f"Bearer {admin_token}"}, ) assert response.status_code == 201, response.text body = response.json() assert body["full_name"] == "Valid User" assert body["username"] == "valid@test.com" assert body["must_change_password"] is True def test_create_user_with_manager_role_accepted(client, admin_user, admin_token): """Regression: 'manager' is a real, actively-used role (dispute mediation, operator assignment) but was missing from the creation whitelist.""" response = client.post( "/api/v1/users", json={ "full_name": "New Manager", "email": "newmanager@test.com", "role": "manager", }, headers={"Authorization": f"Bearer {admin_token}"}, ) assert response.status_code == 201, response.text assert response.json()["role"] == "manager" def test_create_user_invalid_role_rejected(client, admin_user, admin_token): response = client.post( "/api/v1/users", json={ "full_name": "Bad Role User", "email": "badrole@test.com", "role": "superuser", }, headers={"Authorization": f"Bearer {admin_token}"}, ) assert response.status_code == 400 assert "Invalid role" in response.text def test_create_user_duplicate_email_rejected(client, admin_user, admin_token): payload = { "full_name": "Dup User", "email": "dup@test.com", "role": "viewer", } first = client.post( "/api/v1/users", json=payload, headers={"Authorization": f"Bearer {admin_token}"}, ) assert first.status_code == 201, first.text second = client.post( "/api/v1/users", json=payload, headers={"Authorization": f"Bearer {admin_token}"}, ) assert second.status_code == 409