""" Tests for user management module (Admin only) """ import pytest import json from app import db from app.models import User @pytest.fixture def admin_user(app): """Create an admin user""" with app.app_context(): user = User( username='adminuser', email='admin@example.com', role='admin' ) user.set_password('adminpassword123') db.session.add(user) db.session.commit() return { 'id': user.id, 'username': user.username, 'email': user.email, 'role': user.role } @pytest.fixture def admin_token(client, admin_user): """Get admin token for authenticated requests""" response = client.post('/api/auth/login', data=json.dumps({ 'username': 'adminuser', 'password': 'adminpassword123' }), content_type='application/json' ) return json.loads(response.data)['token'] @pytest.fixture def regular_user(app): """Create a regular user""" with app.app_context(): user = User( username='regularuser', email='regular@example.com', role='user' ) user.set_password('regularpassword123') db.session.add(user) db.session.commit() return { 'id': user.id, 'username': user.username, 'email': user.email, 'role': user.role } class TestGetUsers: """Tests for GET /api/users endpoint""" def test_get_users_success(self, client, admin_token, admin_user): """Test admin can get users list""" response = client.get('/api/users', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 200 data = json.loads(response.data) assert 'data' in data assert 'pagination' in data assert len(data['data']) >= 1 def test_get_users_pagination(self, client, admin_token, admin_user): """Test pagination parameters""" response = client.get('/api/users?page=1&page_size=10', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 200 data = json.loads(response.data) assert data['pagination']['page'] == 1 assert data['pagination']['page_size'] == 10 def test_get_users_search(self, client, admin_token, admin_user): """Test search functionality""" response = client.get('/api/users?search=admin', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 200 data = json.loads(response.data) assert len(data['data']) >= 1 assert 'admin' in data['data'][0]['username'].lower() or 'admin' in data['data'][0]['email'].lower() def test_get_users_unauthorized(self, client, regular_user): """Test regular user cannot access users list""" # Login as regular user login_response = client.post('/api/auth/login', data=json.dumps({ 'username': 'regularuser', 'password': 'regularpassword123' }), content_type='application/json' ) token = json.loads(login_response.data)['token'] response = client.get('/api/users', headers={'Authorization': f'Bearer {token}'} ) assert response.status_code == 403 class TestCreateUser: """Tests for POST /api/users/create endpoint""" def test_create_user_success(self, client, admin_token): """Test admin can create a new user""" response = client.post('/api/users/create', data=json.dumps({ 'username': 'newuser', 'password': 'newpassword123', 'email': 'newuser@example.com', 'role': 'user' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 201 data = json.loads(response.data) assert data['username'] == 'newuser' assert data['email'] == 'newuser@example.com' assert data['role'] == 'user' def test_create_user_missing_fields(self, client, admin_token): """Test create user with missing required fields""" response = client.post('/api/users/create', data=json.dumps({ 'username': 'newuser' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 400 data = json.loads(response.data) assert 'error' in data def test_create_user_duplicate_username(self, client, admin_token, admin_user): """Test create user with duplicate username""" response = client.post('/api/users/create', data=json.dumps({ 'username': 'adminuser', 'password': 'password123', 'email': 'another@example.com', 'role': 'user' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 400 data = json.loads(response.data) assert 'error' in data def test_create_user_invalid_role(self, client, admin_token): """Test create user with invalid role""" response = client.post('/api/users/create', data=json.dumps({ 'username': 'newuser', 'password': 'password123', 'email': 'newuser@example.com', 'role': 'invalid_role' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 400 class TestUpdateUser: """Tests for POST /api/users/update endpoint""" def test_update_user_success(self, client, admin_token, regular_user): """Test admin can update a user""" response = client.post('/api/users/update', data=json.dumps({ 'id': regular_user['id'], 'email': 'updated@example.com' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 200 data = json.loads(response.data) assert data['email'] == 'updated@example.com' def test_update_user_not_found(self, client, admin_token): """Test update non-existent user""" response = client.post('/api/users/update', data=json.dumps({ 'id': 99999, 'email': 'updated@example.com' }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 404 def test_update_user_self_deactivation(self, client, admin_token, admin_user): """Test admin cannot deactivate themselves""" response = client.post('/api/users/update', data=json.dumps({ 'id': admin_user['id'], 'is_active': False }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 400 class TestDeleteUser: """Tests for POST /api/users/delete endpoint""" def test_delete_user_success(self, client, admin_token, regular_user): """Test admin can delete a user""" response = client.post('/api/users/delete', data=json.dumps({ 'id': regular_user['id'] }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 200 data = json.loads(response.data) assert 'message' in data def test_delete_user_not_found(self, client, admin_token): """Test delete non-existent user""" response = client.post('/api/users/delete', data=json.dumps({ 'id': 99999 }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 404 def test_delete_user_self_deletion(self, client, admin_token, admin_user): """Test admin cannot delete themselves""" response = client.post('/api/users/delete', data=json.dumps({ 'id': admin_user['id'] }), content_type='application/json', headers={'Authorization': f'Bearer {admin_token}'} ) assert response.status_code == 400